2.3 系统调用

timekeeper提供一系列的系统调用,使得用户空间可以获取想要的时间。下面简单的介绍一下clock_gettime系统调用

SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,

struct timespec __user *,tp)

{

struct k_clock *kc = clockid_to_kclock(which_clock);

struct timespec kernel_tp;

int error;

if (!kc)

return -EINVAL;

error = kc->clock_get(which_clock, &kernel_tp);

if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp)))

error = -EFAULT;

return error;

}

static __init int init_posix_timers(void)

{

struct k_clock clock_realtime = {

.clock_getres   = hrtimer_get_res,

.clock_get      = posix_clock_realtime_get,

.clock_set      = posix_clock_realtime_set,

.clock_adj      = posix_clock_realtime_adj,

.nsleep         = common_nsleep,

.nsleep_restart = hrtimer_nanosleep_restart,

.timer_create   = common_timer_create,

.timer_set      = common_timer_set,

.timer_get      = common_timer_get,

.timer_del      = common_timer_del,

};

struct k_clock clock_monotonic = {

.clock_getres   = hrtimer_get_res,

.clock_get      = posix_ktime_get_ts,

.nsleep         = common_nsleep,

.nsleep_restart = hrtimer_nanosleep_restart,

.timer_create   = common_timer_create,

.timer_set      = common_timer_set,

.timer_get      = common_timer_get,

.timer_del      = common_timer_del,

};

struct k_clock clock_monotonic_raw = {

.clock_getres   = hrtimer_get_res,

.clock_get      = posix_get_monotonic_raw,

};

struct k_clock clock_realtime_coarse = {

.clock_getres   = posix_get_coarse_res,

.clock_get      = posix_get_realtime_coarse,

};

struct k_clock clock_monotonic_coarse = {

.clock_getres   = posix_get_coarse_res,

.clock_get      = posix_get_monotonic_coarse,

};

struct k_clock clock_boottime = {

.clock_getres   = hrtimer_get_res,

.clock_get      = posix_get_boottime,

.nsleep         = common_nsleep,

.nsleep_restart = hrtimer_nanosleep_restart,

.timer_create   = common_timer_create,

.timer_set      = common_timer_set,

.timer_get      = common_timer_get,

.timer_del      = common_timer_del,

};

posix_timers_register_clock(CLOCK_REALTIME, &clock_realtime);

posix_timers_register_clock(CLOCK_MONOTONIC, &clock_monotonic);

posix_timers_register_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);

posix_timers_register_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse);

posix_timers_register_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse);

posix_timers_register_clock(CLOCK_BOOTTIME, &clock_boottime);

posix_timers_cache = kmem_cache_create("posix_timers_cache",

sizeof (struct k_itimer), 0, SLAB_PANIC, NULL);

idr_init(&posix_timers_id);

return 0;

}

#define CLOCK_REALTIME                  0

#define CLOCK_MONOTONIC                 1

#define CLOCK_PROCESS_CPUTIME_ID        2

#define CLOCK_THREAD_CPUTIME_ID         3

#define CLOCK_MONOTONIC_RAW             4

#define CLOCK_REALTIME_COARSE           5

#define CLOCK_MONOTONIC_COARSE          6

#define CLOCK_BOOTTIME                  7

#define CLOCK_REALTIME_ALARM            8

#define CLOCK_BOOTTIME_ALARM            9

系统在初始化是会调用init_posix_timers等函数来初始化clock_gettime系统调用所需要的相关数据结构。这里,调用clock_gettime获取时间时,需要的是k_clock结构中的clock_get回调函数。对于clock_gettime的which_clock参数,系统支持获取包括xtime,boot time,monotonic time,raw monotonic time以及进程或者线程运行时间等共十种方式。对于获取xtime和monotonic time,which_clock有两种设置,分别是带_COARSE和不带两种方式。

2.3.1 _COARSE作用

static int posix_clock_realtime_get(clockid_t which_clock, struct timespec *tp)

{

ktime_get_real_ts(tp);

return 0;

}

#define ktime_get_real_ts(ts)   getnstimeofday(ts)

void getnstimeofday(struct timespec *ts)

{

unsigned long seq;

s64 nsecs;

WARN_ON(timekeeping_suspended);

do {

seq = read_seqcount_begin(&xtime_seq);

*ts = xtime;

nsecs = timekeeping_get_ns();

/* If arch requires, add in gettimeoffset() */

nsecs += arch_gettimeoffset();

} while (read_seqcount_retry(&xtime_seq, seq));

timespec_add_ns(ts, nsecs);

}

static inline s64 timekeeping_get_ns(void)

{

cycle_t cycle_now, cycle_delta;

struct clocksource *clock;

/* read clocksource: */

clock = timekeeper.clock;

cycle_now = clock->read(clock);

/* calculate the delta since the last update_wall_time: */

cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;

/* return delta convert to nanoseconds using ntp adjusted mult. */

return clocksource_cyc2ns(cycle_delta, timekeeper.mult,

timekeeper.shift);

}

static int posix_get_realtime_coarse(clockid_t which_clock, struct timespec *tp)

{

*tp = current_kernel_time();

return 0;

}

struct timespec current_kernel_time(void)

{

struct timespec now;

unsigned long seq;

do {

seq = read_seqcount_begin(&xtime_seq);

now = xtime;

} while (read_seqcount_retry(&xtime_seq, seq));

return now;

}

从函数实现可以看到,当带_COARSE后缀时,函数直接返回xtime。而不带_COARSE后缀时,函数得首先统计当期时刻和上次更新xtime时的时间差,将时间差与xtime之和返回。从这点看,带后缀的比不带后缀的效率要高。当需要的时间不需要太精确时,可以使用带_COARSE后缀的参数来获取时间,这样可以略微提升应用的运行速度。当获取时间的操作很频繁时,作用尤其明显。

linux时间子系统之,linux时间子系统(四)相关推荐

  1. Linux时间子系统之三:时间的维护者:timekeeper

    专题文档汇总目录 Notes: 原文地址:Linux时间子系统之三:时间的维护者:timekeeper 本系列文章的前两节讨论了用于计时的时钟源:clocksource,以及内核内部时间的一些表示方法 ...

  2. Linux内核网络数据包发送(四)——Linux netdevice 子系统

    Linux内核网络数据包发送(四)--Linux netdevice 子系统 1. 前言 2. `dev_queue_xmit` and `__dev_queue_xmit` 2.1 `netdev_ ...

  3. Linux内核进阶----整体框架及子系统概览

    目录 1.概述 2.核心抽象及设计选型 2.1. 对进程和内核的抽象 2.2. 对进程地址空间的抽象 2.3. 支持可重入可抢占的内核 2.4. 放松管控与努力回收 2.5. 单块结构内核+动态加载模 ...

  4. Linux查询系统运行的时间

    方法一: # who -b //系统最后一次开机的时间 方法二: # who -r //查看当前系统运行时间 方法三: # last reboot //可以看到Linux系统历史启动的时间. 方法四: ...

  5. Linux基础(9)--延时与时间

    延时与时间 1. 延时 1.1 基本知识 2. 时间 2.1 基本概念 2.2 时间调用 2.3 时间转换 2.4 处理器性能测试 1. 延时 1.1 基本知识 linux中延时函数很简单,却经常用到 ...

  6. linux新建脚本文件,linux shell脚本编程2—修改文件时间和创建新文件即touch命令的使用...

     在使用ls命令时,每个文件在Linux下面都会记录3个主要的修改时间: modification time(mtime,修改时间):当该文件的"内容数据"更改时,就会更新这个时 ...

  7. Linux获取纳秒级时间,WINDOW和LINXU下获取纳秒级时间精度

    WINDOWS下的实现 这一篇介绍Windows SDk中提供的时间函数.两种时间系统之间没有本质区别(事实上CRT时间是用Windows时间实现的,当然这是说的VC实现),同样提供本地时间和UTC时 ...

  8. linux编写多时区时间显示程序,Linux系统时区时间修改

    我们知道,计算机系统有两个时钟,一个是硬件时钟,一个是系统时钟,硬件时钟的工作原理就是电脑在开机运行的时候会给主板上的纽扣电池充电,关机后这块电池还为存放系统参数的CMOS.RAM供电,以保存其中的系 ...

  9. platform框架--Linux MISC杂项框架--Linux INPUT子系统框架--串行集成电路总线I2C设备驱动框架--串行外设接口SPI 设备驱动框架---通用异步收发器UART驱动框架

    platform框架 input. pinctrl. gpio 子系统都是 Linux 内核针对某一类设备而创建的框架, input子系统是管理输入的子系统 pinctrl 子系统重点是设置 PIN( ...

  10. Linux设备上时间不准确?使用chrony服务配置时间服务器实现Linux时间同步以及实现主从设备时间同步

    本文基于Linux上CentOS 7版本配合chrony(需要使用yum自行下载)进行演示 一.计算机设备上的两种时间 1.硬件时间 2.系统时间 二.配置同步时间服务器 1.安装服务 2.配置服务 ...

最新文章

  1. 简说JAVA8引入函数式的问题
  2. seaborn 画堆叠柱状图_Seaborn-基于matplotlib的更强力制图库
  3. boot spring test 文档_Spring、Spring Boot 和 TestNG 测试指南 ( 3 )
  4. mysql bench如何下载_MySQLWorkbench下载与使用教程详解
  5. pdfjs viewer 开发小结
  6. owncloud mysql版本_Linux Deploy Owncloud php7.0+apache2+mysql5.7+owncloud9.1
  7. java ftp 上传文件 无效_java实现FTP文件上传出现的问题
  8. JS,Jquery获取select,dropdownlist,checkbox 下拉列表框的值
  9. java迭代器怎么用_Java中迭代器的使用
  10. Qi v1.2.4 -- WPC官方文档资源下载
  11. 汉诺塔C语言递归实现详解
  12. font-style字体设置
  13. 教你认识正斜杠(/)与反斜杠(\)
  14. 带你Dart带你Diao之类(二)
  15. 如何使用动态域名,并且自己来定时更新
  16. App Inventor探索
  17. 进入旅游营销时代,携程有什么“大招”?
  18. 常用正则表达式(英文单词、数字、中文 、URL 、电话、身份证、输入内容必须以逗号隔开等)
  19. 亲身经历体会乐歌和爱格升显示器支架,到底谁更胜一筹?
  20. 服务器2003蓝屏A5修复,重装XP系统时蓝屏代码0X000000A5如何修复?

热门文章

  1. 操作系统中的文件系统和访问方法
  2. 给定数字的b+树创建_在C ++中找到给定数字中的两个的下一个和上一个幂
  3. 河南招教考试计算机专业知识,河南教师招聘考试《计算机网络技术基础》知识点归纳七...
  4. 面试官:HashSet是如何保证元素不重复的?
  5. 最常见的10种Java异常问题!
  6. MySQL中你必须知道的10件事,1.5万字!
  7. 如何设计不宕机的 Redis 高可用服务?
  8. 阿里《Java开发手册》最新嵩山版发布!
  9. c#字符相似度对比通用类
  10. C#下2\10\16进制互转代码总汇