首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在哪里可以找到timespec_get的源代码?

在哪里可以找到timespec_get的源代码?
EN

Stack Overflow用户
提问于 2018-07-24 02:41:50
回答 2查看 1.8K关注 0票数 2

C11标准提供了timespec_get函数。如果我在cp首选项上或在我的计算机上运行示例代码,它可以工作:

代码语言:javascript
复制
#include <stdio.h>
#include <time.h>

int main(void)
{
    struct timespec ts;
    timespec_get(&ts, TIME_UTC);
    char buff[100];
    strftime(buff, sizeof buff, "%D %T", gmtime(&ts.tv_sec));
    printf("Current time: %s.%09ld UTC\n", buff, ts.tv_nsec);
}

但是,如果我查看glibc 这里的来源,代码如下:

代码语言:javascript
复制
#include <time.h>


/* Set TS to calendar time based in time base BASE.  */
int
timespec_get (struct timespec *ts, int base)
{
  switch (base)
    {
    case TIME_UTC:
      /* Not supported.  */
      return 0;

    default:
      return 0;
    }

  return base;
}
stub_warning (timespec_get)

哪个..。不应该起作用..。

引出了一个问题:,实际上被调用的timespec_get的源代码在哪里?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-24 02:57:40

timespec_get函数的实现取决于库在其上运行的系统,因此它既显示为time/timespec_get.c中的存根(如果没有实现),也显示为其他地方依赖于系统的各种实现。

您可以在sysdeps/unix/sysv/linux/timespec_get.c中看到Linux实现,

代码语言:javascript
复制
/* Set TS to calendar time based in time base BASE.  */
int
timespec_get (struct timespec *ts, int base)
{
  switch (base)
    {
      int res;
      INTERNAL_SYSCALL_DECL (err);
    case TIME_UTC:
      res = INTERNAL_VSYSCALL (clock_gettime, err, 2, CLOCK_REALTIME, ts);
      if (INTERNAL_SYSCALL_ERROR_P (res, err))
        return 0;
      break;

    default:
      return 0;
    }

  return base;
}

这只是一个vDSO调用的薄包装器,vDSO是Linux内核本身的一部分。如果您有兴趣,可以在那里查找clock_gettime的定义。不寻常的是,clock_gettime在vDSO中,只有少数系统是以这种方式实现的。

以下是CLOCK_REALTIMECLOCK_REALTIME实现,见于arch/x86/entry/vdso/vclock_gettime.c

代码语言:javascript
复制
/* Code size doesn't matter (vdso is 4k anyway) and this is faster. */
notrace static int __always_inline do_realtime(struct timespec *ts)
{
        unsigned long seq;
        u64 ns;
        int mode;

        do {
                seq = gtod_read_begin(gtod);
                mode = gtod->vclock_mode;
                ts->tv_sec = gtod->wall_time_sec;
                ns = gtod->wall_time_snsec;
                ns += vgetsns(&mode);
                ns >>= gtod->shift;
        } while (unlikely(gtod_read_retry(gtod, seq)));

        ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
        ts->tv_nsec = ns;

        return mode;
}

基本上,您的进程中有一些内存由内核更新,还有一些寄存器在CPU中跟踪时间的推移(或者由虚拟机管理程序提供的内容)。进程中的内存用于将这些CPU寄存器的值转换为挂钟时间。你必须把它们循环起来,因为它们可以在你读的时候改变.循环逻辑在读取错误时检测情况,然后再试一次。

票数 7
EN

Stack Overflow用户

发布于 2018-07-24 02:57:23

链接到的timespec_get定义是存根(参见stub_warning)。实际的实现将在您的平台的sysdeps下进行。例如,下面是sysvget.c的版本

代码语言:javascript
复制
int timespec_get (ts, base)
    struct timespec *ts;
    int base;
{
    switch (base)
    {
        int res;
        INTERNAL_SYSCALL_DECL (err);
    case TIME_UTC:
        res = INTERNAL_GETTIME (CLOCK_REALTIME, ts);
        if (INTERNAL_SYSCALL_ERROR_P (res, err))
        return 0;
        break;
    default:
        return 0;
    }
    return base;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51489703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档