#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
利用这个函数就可以返回微妙级别的时间。