AUTHOR: Joseph Yang (杨红刚) <ganggexiongqi@gmail.com>
CONTENT: trace-clock.c 分析
NOTE: linux-2.6.38.6
LAST MODIFIED:09-06-2011
-----------------------------------------------------------------------------------------------------------
Distributed and Embedded System Lab (分布式嵌入式系统实验室,兰州大学)
===============================================================
/* Generic kernel tracing clock for architectures without TSC.*/
trace-clock.c 分析------------------- 变量和函数列表 ------------------------
- trace-clock.c (/usr/src/linux2.6.38.6-lttng-0.249/kernel/trace)
|- variable
|| trace_clock_refcount
|| trace_clock_timer
|| trace_clock_var
|
|- function
|| trace_clock_update +
|| trace_clock_timer_fct +
|| enable_trace_clock +
|| disable_trace_clock
|| get_trace_clock +
|| put_trace_clock
------------ 外部接口 ----------------
/*
* bits 0..12 : counter, atomically incremented
* bits 13..{32,64} : time counter, incremented each jiffy.
*/
atomic_long_t trace_clock_var;
EXPORT_SYMBOL(trace_clock_var); // time counter 可以从该变量中读出
EXPORT_SYMBOL_GPL(get_trace_clock);
EXPORT_SYMBOL_GPL(put_trace_clock);
------------- 相关数据结构 -----------
static int trace_clock_refcount; // trace clock 的引用计数
static DEFINE_MUTEX(trace_clock_mutex);
static struct timer_list trace_clock_timer; //所有cpu共用
/*
* bits 0..12 : counter, atomically incremented
* bits 13..{32,64} : time counter, incremented each jiffy.
*/
atomic_long_t trace_clock_var;
-------------------------- 具体分析 ------------------
1.
函数:
void get_trace_clock(void)
参数:
功能:trace clock 引用计数增一 ,如果是第一个引用,则使能该trace clock
流程:
空//get_synthetic_tsc
获得trace_clock_mutex锁 // mutex_lock
trace_clock_refcount ++
如果是第一个引用,则初始化trace_clock_timer,并进行设置后,添加到系统中
//enable_trace_clock
释放trace_clock_mutex锁//mutex_unlock
2.
函数:
static void enable_trace_clock(void)
参数:
功能:初始化trace_clock_timer,并进行设置后,添加到系统中
流程:
初始化 trace_clock_timer // init_timer
注册 trace_clock_timer的回调函数为
设置超时值为 jiffies + 1 // 下一个tick 触发
这次调用其实什么都没有做 //trace_clock_update
把trace_clock_timer添加到系统中//add_timer
3.
函数://看都是在那里调用本函数了(bits 0..12 : counter, atomically incremented)?????????
// trace_clock_timer_fct,
static void trace_clock_update(void)
参数:
功能:更新trace_clock_var的值
流程:
ticks = jiffies - trace_clock_timer.expires + 1; // 为什么这么计算 ?????????????
如果 ticks 为0 ,则什么都不做//比如在 enable_trace_clock中调用 本函数时
更新trace_clock_var的13-{32, 64}值// atomic_long_cmpxchg,这是 “CAS 进行同步“
//trace_clock_var的13-{32, 64}值为timer counter, increased each jiffy
4.
函数:
static void trace_clock_timer_fct(unsigned long data)
参数:
功能:更新trace_clock_var的值,并重新设置和添加内核定时器trace_clock_timer
流程:
更新trace_clock_var的值 // trace_clock_update
重新设置 内核定时器的超时值 trace_clock_timer.expires = jiffies + 1
重新添加内核定时器 //add_timer<这里是不是用mod_timer更好些 ???>
5.
函数:
static void disable_trace_clock(void)
参数:
功能:从系统中删除 trace_clock_timer
流程:
从系统中删除 trace_clock_timer//del_timer_sync
6.
函数:
void put_trace_clock(void)
参数:
功能:
流程:
获得锁trace_clock_mutex //mutex_lock
如果是最后一个使用clock的,
则 从系统中删除 trace_clock_timer //disable_trace_clock
trace_clock_refcount--
释放trace_clock_mutex 锁 //mutex_unlock
空//put_synthetic_tsc
----------------------------------trace clock 总结
本文件为那些没有TSC的体系结构提供trace clock
trace_clock_var的 bits 13..{32,64} : time counter, incremented each jiffy.
get_time()
{
return trace_clock_var >>TRACE_CLOCK_SHIFT;
}