semaphore Linux时间子系统(五) POSIX Clock(5)

电脑杂谈  发布时间:2018-02-14 21:11:13  来源:网络整理

if (!error) {

tp->tv_sec = 0;

tp->tv_nsec = ((NSEC_PER_SEC + HZ - 1) / HZ);

if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {

tp->tv_nsec = 1;

}

}

return error;

}

该函数的执行逻辑分成两个部分,一部分是参数校验,一部分是返回精度。参数校验需要检查的包括:

(a)clock id中的高29个bit包含了pid,获取pid的代码如下:

#define CPUCLOCK_PID(clock) ((pid_t) ~((clock) >> 3))

从代码可知,实际上并不是将pid放到高29个bit,而是将反码保存到了高29个bit。为何保存反码?这样做为了确保clock id是一个负数(MSB是1),还记得clockid_to_kclock的实现吗?要获取该clock id的精度,要确保该pid的task存在

(b)如果该clock id是一个进程相关的(调用clock_getcpuclockid获得),那么这个进程id应该是一个实实在在的进程id。在linux kernel中,pid实际上是线程ID,POSIX标准的进程ID,也就是PID在内核中被成为线程组ID。因此,所谓一个“实实在在的进程id”就是说该线程的id(pid)和tgid一样,该pid标识的线程是线程组leader。当然,就是获取精度而已,实际上要求并不要那么严格,也许该pid标识的线程leader会退出,因此实际上要求该pid标识的task有thread group leader就OK了。(这里有可能理解有误,TODO)

(c)如果该clock id是一个线程相关的(调用pthread_getcpuclockid获得),那么调用者必须和该线程(clock id中指明的那个线程)属于一个进程(线程组)。

返回精度部分的代码逻辑很简单,对于PROF和VIRT类型的CPU-time clock,其精度是tick,对于SCHED类型,精度是1ns。

(2)获取当前时间值

同样的,首先需要从clock id中获取pid的值,然后根据pid的值获取对应的task sturct,如果pid等于0,那么不需要费劲去寻找。得到task struct之后,可以调用posix_cpu_clock_get_task函数获取时间值:

static int posix_cpu_clock_get_task(struct task_struct *tsk, const clockid_t which_clock,

struct timespec *tp)

{

int err = -EINVAL;

unsigned long long rtn;

if (CPUCLOCK_PERTHREAD(which_clock)) {---per 线程的cpu clock

if (same_thread_group(tsk, current))---必须和调用者是同一个线程组,也就是同一个进程

err = cpu_clock_sample(which_clock, tsk, &rtn);

} else {

if (tsk == current || thread_group_leader(tsk))---进程的cpu clock

err = cpu_clock_sample_group(which_clock, tsk, &rtn);


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-77921-5.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...