【1】应用层
gettimeofday函数
头文件:
#include <sys/time.h>
int gettimeofday(struct timeval*tv, struct timezone *tz);
其参数tv是保存获取时间结果的结构体,参数tz用于保存时区结果:
struct timezone{
int tz_minuteswest;/格林威治时间往西方的时差/
int tz_dsttime;/DST 时间的修正方式/
}
timezone 参数若不使用则传入NULL即可。
结构体定义:
而结构体timeval的定义为:
struct timeval{
long int tv_sec; // 秒数
long int tv_usec; // 微秒数
}
它获得的时间精确到微秒(1e-6 s)量级。在一段代码前后分别使用gettimeofday可以计算代码执行时间:
NAME
gettimeofday, settimeofday - get / set time
SYNOPSIS
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
int settimeofday(const struct timeval *tv, const struct timezone *tz);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
settimeofday(): _BSD_SOURCE
DESCRIPTION
The functions gettimeofday() and settimeofday() can get and set the
time as well as a timezone. The tv argument is a struct timeval (as
specified in <sys/time.h>):
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
and gives the number of seconds and microseconds since the Epoch (see
time(2)). The tz argument is a struct timezone:
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
};
代码实例:
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#define N 10
/*制作计时器*/
void mdelay(int ms_count)
{
struct timeval tpStart, tpEnd;
float timeUse;
gettimeofday(&tpStart, NULL);
do {
gettimeofday(&tpEnd, NULL);
timeUse = 1000 * (tpEnd.tv_sec - tpStart.tv_sec) + 0.001 * (tpEnd.tv_usec - tpStart.tv_usec);
} while(timeUse < ms_count);
}
int main(int argc,char * argv[]){
struct timeval t_start,t_end;
long cost_time = 0;
int i,time=N*10000;
//get start time
gettimeofday(&t_start, NULL);
long start = ((long)t_start.tv_sec)*1000+(long)t_start.tv_usec/1000;
printf("Start time: %ld ms\n", start);//将时间转化为毫秒
/*延时10s*/
for(i=0;i<10000;i++)
{
mdelay(1);
}
//get end time
gettimeofday(&t_end, NULL);
long end = ((long)t_end.tv_sec)*1000+(long)t_end.tv_usec/1000;
printf("End time: %ld ms\n", end);
//calculate time slot
cost_time = end - start;
printf("Cost time: %ld ms\n", cost_time);
return 0;
}
实验结果:
存在一定误差!
【2】内核层
do_gettimeofday()函数
do_gettimeofday(struct timeval tv)
struct timeval {
__kernel_time_t tv_sec; / seconds /
__kernel_suseconds_t tv_usec; / microseconds */
};
#include <linux/init.h> /* printk() */
#include <linux/module.h> /* __init __exit */
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/timex.h>
#include <linux/rtc.h>
static int __init hello_init(void) /*模块加载函数,通过insmod命令加载模块时,被自动执行*/
{
printk("hello world!\n");
int i;
struct timeval start,end;
long cost_time = 0;
do_gettimeofday(&start);//获取开始时间
long start_time = ((long)start.tv_sec)*1000+(long)start.tv_usec/1000;
printk("Start time: %ld ms\n", start_time);//打印开始时间
/*延时10s*/
for(i=0;i<10;i++)
{
udelay(1000000);
}
do_gettimeofday(&end);//获取结束时间
long end_time = ((long)end.tv_sec)*1000+(long)end.tv_usec/1000;
printk("End time: %ld ms\n", end_time);
//printk("%ld\n",end.tv_usec);
cost_time = end_time - start_time;//差值
printk("Cost time: %ld ms\n", cost_time);
return 0;
}
static void __exit hello_exit(void) /*模块卸载函数,当通过rmmod命令卸载时,会被自动执行*/
{
printk(KERN_INFO " Hello World exit\n ");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("shawn.wang"); /*模块作者,可选*/
MODULE_LICENSE("Dual BSD/GPL"); /*模块许可证明,描述内核模块的许可权限,必须*/
MODULE_DESCRIPTION("A simple Hello World Module"); /*模块说明,可选*/