Hol található a forráskódját timespec_get?

szavazat
0

A C11szabvány a funkciót timespec_get. Ha futok a példa kódot cppreference, vagy a számítógép, működik:

#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);
}

Azonban, ha megnézem a források glibc itt , a kód a következő:

#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)

Ami ... nem működik ...

Ami a kérdést: hol van a forráskód timespec_get, amely valójában hívják?

A kérdést 24/07/2018 01:41
a forrás felhasználó
Más nyelveken...                            


2 válasz

szavazat
1

A timespec_getdefiníció akkor kapcsolódik egy csonk (lásd a stub_warning). A tényleges megvalósítás alatt lesz sysdepsa platform. Például itt van a verzió sysv: https://github.com/lattera/glibc/blob/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/sysdeps/unix/sysv/linux/timespec_get.c

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;
}
Válaszolt 24/07/2018 01:57
a forrás felhasználó

szavazat
3

A timespec_getfunkció végrehajtása függ a rendszer a könyvtár fut, így úgy tűnik, mind a csonk time/timespec_get.c(ha nincs végrehajtás áll), valamint a különböző rendszer-függő megvalósítások máshol.

Láthatjuk a Linux végrehajtását sysdeps/unix/sysv/linux/timespec_get.c,

/* 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;
}

Ez csak egy vékony borítás körül vDSO hívást, és a vDSO része maga a Linux kernel. Ha kíváncsi, keresse meg a meghatározását clock_gettimeis. Ez szokatlan, hogy clock_gettimeez a vDSO, csak egy kis számú rendszerhívások hajtják végre ezen a módon.

Itt látható az x86 végrehajtásának CLOCK_REALTIMEtalált arch/x86/entry/vdso/vclock_gettime.c:

/* 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;
}

Alapvetően van némi memóriát a folyamat, amely frissíti a kernel, és néhány regiszterek a CPU-t, amely nyomon az idő múlása (vagy valami által biztosított hypervisor). A memória az eljárást alkalmazunk lefordítani az értéke ezeknek a CPU regiszterek a fali órát. Meg kell olvasni ezeket a hurok, mert lehet változtatni miközben olvasod őket ... a ciklus logikája érzékeli az esetben, ha kap egy rossz olvasni, és újra próbálkozik.

Válaszolt 24/07/2018 01:57
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more