#i nclude HZ
HZ符号指出每秒钟产生的时钟滴答数。
#i nclude volatile
unsigned long jiffies jiffies变量每个时钟滴答后加1,因此它每秒增加 HZ 次。
#i nclude
rdtsc(low,high); rdtscl(low);
读取时间戳计数器或其低半部分。头文件和宏是 PC 类处理器特有的,其它平台可能需要用汇编语句实现类似功能。
extern struct
timeval xtime; 当前时间,由最近一次定时器滴答计算出。
#i nclude
void do_gettimeofday(struct timeval *tv); void get_fast_time(struct
timeval *tv); 这两个函数返回当前时间。前者具有很高的分辨率,后者更快些,但分辨率较差。
#i nclude
void udelay(unsigned long usecs); void
mdelay(unsigned long msecs);
这两个函数引入整数数目的微秒或毫秒的延迟。前一个应用于不超过1毫秒的延迟;后一个使用时要格外慎重,因为它们使用的都是忙等待循环。
int
in_interrupt(); 如果处理器正在中断模式运行,就返回非0值。
#i nclude
DECLARE_TASK_QUEUE(variablename);
该宏声明一个新的变量并作初始化。
void queue_task(struct tq_struct *task, task_queue
*list); 该函数注册一个稍后执行的任务。
void run_task_queue(task_queue *list);
该函数运行任务队列。
task_queue tq_immediate, tq_timer;
这些预定义的任务队列在内核调度新的进程前(tq_immediate)尽快地,或者在每个时钟滴答后(tq_timer)得到执行。
int
schedule_task(struct tq_struct *task); 调度一个任务在调度器队列运行。
#i nclude
DECLARE_TASKLET(name, function, data)
DECLARE_TASKLET_DISABLED(name, function, data) 声明一个 tasklet
结构,运行时它将调用指定的函数function(并将指定参数unsigned long data传递给函数)。第二种形式把 tasklet
初始化为禁止状态,直到明确地使能后tasklet才能运行。
void tasklet_schedule(struct
tasklet_struct *tasklet); 调度指定的 tasklet 运行。如果该 tasklet 没有被禁止,它将在调用了
tasklet_schedule 的CPU上很快得到执行。
tasklet_enable(struct tasklet_struct
*tasklet); tasklet_disable(struct tasklet_struct *tasklet);
这两个函数分别使能和禁止指定的tasklet。被禁止的 tasklet 可以被调度,但只有使能后才能运行。
void
tasklet_kill(struct tasklet_struct *tasklet);
使一个正“无休止重新调度”的tasklet停止执行。该函数可以阻塞,而且不能在中断期间调用。
#i nclude
void init_timer(struct timer_list * timer);
该函数初始化新分配的定时器。
void add_timer(struct timer_list * timer);
该函数将定时器插入待处理定时器的全局队列。
int mod_timer(struct
timer_list *timer, unsigned long expires); 该函数用于更改一个已调度的定时器结构中的超时时间。
int del_timer(struct timer_list * timer);
del_timer函数将定时器从待处理定时器队列中删除。如果队列中存在该定时器,del_timer返回1,否则返回0。
int
del_timer_sync(struct timer_list *timer); 该函数类似del_timer,但是确保定时器函数当前不在其它 CPU
上运行。
详细请见:
一个小的测试程序:
int main() { char
filepath[]="/home/gmt/huzza/NewStart/pce/halti/p8894_nemesis/huzza.bmp"; unsigned
buf[585728]; unsigned long starttime, endtime; FILE
*fp=0; int result=0; int filesize; struct stat
filestat; rdtscl(starttime); result=stat(filepath,&filestat); if(result<0) printf("get
file stat
error!\n"); filesize=filestat.st_size; fp=fopen(filepath,"rb"); if(fp==NULL) printf("openfile
error!\n"); result=fread(buf,4,filesize/4,fp); fclose(fp); rdtscl(endtime);
printf("time lapse: %li\n", endtime - starttime);
fclose(fp); }
经过测试发现 result=fread(buf,4,filesize/4,fp) ,如果buf为unsigned型,每次都四个字节,和 result=fread(buf,1,filesize/,fp)
buf为char型,每次读一个字节的速度是一样的:)
另外一种,求程序运行时间的方法,精确到usec(微秒) #i nclude #i nclude
#i nclude #i nclude
int main() { char
filepath[]="/home/gmt/huzza/NewStart/pce/halti/p8894_nemesis/huzza.bmp"; unsigned
buf[585728]; struct timeval starttime; struct timeval
endtime; FILE *fp=0; int result=0; int
filesize; struct stat filestat; //rdtscl(starttime);
gettimeofday(&starttime,0);
result=stat(filepath,&filestat); if(result<0) printf("get
file stat
error!\n"); filesize=filestat.st_size; fp=fopen(filepath,"rb"); if(fp==NULL) printf("openfile
error!\n"); result=fread(buf,4,filesize/4,fp); gettimeofday(&endtime,0); printf("time
lapse: %d\n", endtime.tv_sec-starttime.tv_sec); printf("time lapse: %d\n",
endtime.tv_usec-starttime.tv_usec); fclose(fp); }
说明:
时间精度对于测试工作的重要性不言而喻,那么在测试过程中有什么方法可以获得时间数值并尽可能的精确呢?最容易想到的一个方法就是利用系统提供的时间函数。Linux系统中,可用于测试计时的主要有以下几个函数:time、gmtime、gettimeofday、localtime、ftime。
这些函数中,time、gmtime、localtime得到的时间值精确到秒,对于系统级的测试意义不大。ftime可以返回毫秒,gettimeofday可以返回微秒。
【头文件】: #i nclude #i nclude
【函数定义】:int gettimeofday(struct timeval *tv,struct timezone *tz);0 【函数说明】:gettimeofday会把目前时间由tv所指的结构返回,当地时区的信息则放到tz所指的结构中。
timeval的结构定义: struct timeval{ long tv_sec;
/*秒*/ long tv_usec; /*微妙*/ };
timezone的结构定义: struct timezone{ int tz_minuteswest;
/*和Greenwich时间差了多少分钟*/ long tz_dsttime; /*日光节约时间的状态*/E };F
【返回值】:成功返回0,失败返回-1 利用这个函数就可以返回微妙级别的时间。 |