GNU/Linux >> Znalost Linux >  >> Linux

Existuje nějaký způsob, jak získat 64bitový time_t v 32bitových programech v Linuxu?

Zřejmě ne, to není možné. Pro začátek existuje pouze jeden time() funkce v Linuxu, ne time32() nebo time64() .

Po chvíli hledání vidím, že to není chyba libc, ale viníkem je ve skutečnosti jádro.

Aby knihovna libc mohla načíst aktuální čas, musí pro něj provést systémové volání:

time_t time (t) time_t *t;
{
    // ...
    INTERNAL_SYSCALL_DECL (err);
    time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
    // ...
    return res;
}

Systémové volání je definováno jako:

SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
    time_t i = get_seconds();
    // ...
    return i;
}

Funkce get_seconds() vrátí unsigned long , třeba takto:

unsigned long get_seconds(void)
{
    struct timekeeper *tk = &timekeeper;

    return tk->xtime_sec;
}

A timekeeper.xtime_sec je ve skutečnosti 64bitový:

struct timekeeper {
    // ...
    /* Current CLOCK_REALTIME time in seconds */
    u64                     xtime_sec;
    // ...
}

Nyní, pokud znáte své C, víte, že velikost unsigned long ve skutečnosti závisí na implementaci. Na mém 64bitovém počítači zde je to 64bitové; ale na mém 32bitovém stroji zde je 32bitový. možná může být 64bitový na nějaké 32bitové implementaci, ale neexistuje žádná záruka.

Na druhou stranu u64 je vždy 64bitový, takže v základu jádro sleduje čas v 64bitovém typu. Proč to potom vrátí jako unsigned long , u kterého není zaručeno, že bude 64bitový, jde mimo mě.

Nakonec, i když knihovna libc vynutí time_t udržet 64bitovou hodnotu, nic by to nezměnilo.

Svou aplikaci byste mohli svázat hluboko s jádrem, ale myslím, že to ani nestojí za to.


Mnoho výše uvedených odpovědí říkalo, že to není možné, ale to je zcela nesprávné . Bylo v té době to nebylo možné, ale o opravě se mluvilo už léta. Nakonec byla do jádra Linuxu 5.1 zavedena 64bitová časová podpora na 32bitových platformách s přidáním nového *time64 systémová volání. Podívejte se na tuto tabulku, kde vidíte, že tato systémová volání jsou dostupná pouze na 32bitových platformách. Nyní, pokud píšete kód pro 32bitové systémy, můžete volat clock_gettime64 přímo (z inline sestavy nebo C s syscall() ), abyste získali aktuální čas

Poté jste však zcela sami. Pokud chcete plný uživatelský prostor podporu musíte mít na Linuxu 5.6 nebo vyšším spolu s musl 1.2+ nebo glibc 2.32+. Stačí znovu vytvořit svůj kód a time_t bude 64bitový

  • Veškerý uživatelský prostor musí být zkompilován pomocí 64bitového time_t , který bude podporován v nadcházejících vydáních musl-1.2 a glibc-2.32, spolu s nainstalovanými hlavičkami jádra z linux-5.6 nebo vyšší.

  • Aplikace, které používají rozhraní systémových volání přímo, musí být portovány, aby mohly používat time64 syscalls přidaná v linux-5.1 místo stávajících systémových volání. To má dopad na většinu uživatelů futex() a seccomp() stejně jako programovací jazyky, které mají své vlastní runtime prostředí, které není založeno na libc.

https://lkml.org/lkml/2020/1/29/355?anz=web

Pro více informací

  • Blíží se konec hry jádra roku 2038
  • Zpracování 64bitových časových symbolů v knihovně GNU C
  • Glibc Y2038 Proofness Design
  • Změňte time_t a clock_t na 64 bitů

Linux
  1. Získejte zdrojový kód pro jakýkoli příkaz Linux

  2. Získejte čas na vytváření souborů s Pythonem na linuxu

  3. Existuje způsob, jak zkontrolovat aktuální rpath v Linuxu?

  1. 64bitová konverze časových razítek Unix

  2. Adresový prostor 32bitového procesu v 64bitovém linuxu

  3. Získejte sekundy od epochy v Linuxu

  1. Hledání 32bitových knihoven v 64bitovém Linuxu

  2. Existuje nějaký způsob, jak zablokovat LD_PRELOAD a LD_LIBRARY_PATH na Linuxu?

  3. Operační režim 32bitového, 64bitového CPU v systému Linux