Rupanya, tidak, itu tidak mungkin. Sebagai permulaan, hanya ada satu time()
berfungsi di Linux, tidak ada time32()
atau time64()
.
Setelah mencari beberapa saat, saya dapat melihat bahwa itu bukan kesalahan libc, tetapi pelakunya sebenarnya adalah kernel.
Agar libc dapat mengambil waktu saat ini, libc perlu menjalankan panggilan sistem untuknya:
time_t time (t) time_t *t;
{
// ...
INTERNAL_SYSCALL_DECL (err);
time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
// ...
return res;
}
Panggilan sistem didefinisikan sebagai:
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
time_t i = get_seconds();
// ...
return i;
}
Fungsi get_seconds()
mengembalikan unsigned long
, seperti:
unsigned long get_seconds(void)
{
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
}
Dan timekeeper.xtime_sec
sebenarnya 64-bit:
struct timekeeper {
// ...
/* Current CLOCK_REALTIME time in seconds */
u64 xtime_sec;
// ...
}
Sekarang, jika Anda tahu C Anda, Anda tahu bahwa ukuran unsigned long
sebenarnya tergantung implementasi. Di mesin 64-bit saya di sini, ini 64-bit; tetapi pada mesin 32-bit saya di sini, ini 32-bit. Itu mungkin bisa 64-bit pada implementasi 32-bit, tetapi tidak ada jaminan.
Di sisi lain, u64
selalu 64-bit, jadi pada dasarnya, kernel melacak waktu dalam tipe 64-bit. Mengapa kemudian mengembalikan ini sebagai unsigned long
, yang tidak dijamin panjangnya 64-bit, berada di luar kemampuan saya.
Pada akhirnya, meskipun libc akan memaksa time_t
untuk menyimpan nilai 64-bit, itu tidak akan mengubah apa pun.
Anda dapat mengikat aplikasi Anda secara mendalam ke dalam kernel, tetapi menurut saya itu tidak sepadan.
Banyak jawaban di atas mengatakan bahwa ini tidak mungkin, tetapi itu sepenuhnya salah . Itu adalah tidak mungkin pada saat itu, namun orang-orang telah berbicara tentang memperbaikinya selama bertahun-tahun. Akhirnya dukungan waktu 64-bit pada platform 32-bit diperkenalkan ke kernel Linux 5.1 dengan penambahan *time64
baru syscall. Lihat tabel ini, Anda dapat melihat bahwa syscall tersebut hanya tersedia pada platform 32-bit. Sekarang jika Anda menulis kode untuk sistem 32-bit, Anda dapat memanggil clock_gettime64
langsung (dari perakitan inline atau C dengan syscall()
) untuk mendapatkan waktu saat ini
Namun setelah itu Anda benar-benar sendiri. Jika Anda ingin ruang pengguna penuh dukungan Anda harus menggunakan Linux 5.6 atau lebih tinggi bersama dengan musl 1.2+ atau glibc 2.32+. Bangun kembali kode Anda dan time_t
Anda akan menjadi panjang 64-bit
Semua ruang pengguna harus dikompilasi dengan
time_t
64-bit , yang akan didukung dalam rilis musl-1.2 dan glibc-2.32 yang akan datang, bersama dengan header kernel yang diinstal dari linux-5.6 atau lebih tinggi.Aplikasi yang menggunakan antarmuka system call secara langsung perlu di-porting untuk menggunakan
time64
syscalls ditambahkan di linux-5.1 menggantikan panggilan sistem yang ada. Ini memengaruhi sebagian besar penggunafutex()
danseccomp()
serta bahasa pemrograman yang memiliki lingkungan runtime sendiri yang tidak berbasis libc.https://lkml.org/lkml/2020/1/29/355?anz=web
Untuk informasi lebih lanjut
- Mendekati game akhir tahun-2038 kernel
- Penanganan simbol waktu 64-bit di GNU C Library
- Desain Pembuktian glibc Y2038
- Ubah time_t dan clock_t ke 64 bit