From: Waldemar Kozaczuk <[email protected]> Committer: Nadav Har'El <[email protected]> Branch: master
libc: make pthread_getcpuclockid() compatible with glibc When we run tst-pthread-clock.cc on OSv with Linux dynamic linker, it uses the glibc version of pthread_getcpuclockid(). The glibc pthread_getcpuclockid() uses different scheme (same musl) to encode the clockid which is actually compatible with what Linux kernel expects when handling clock_gettime(). In the end, the tst-pthread-clock.cc fails when calling clock_gettime() with clock_id returned earlier by pthread_getcpuclockid(). To make this test work correctly on OSv with Linux dynamic linker, we change the scheme used by pthread_getcpuclockid() and clock_gettime() to follow what glibc and musl do (see https://git.musl-libc.org/cgit/musl/tree/src/thread/pthread_getcpuclockid.c and https://github.com/bminor/glibc/blob/master/sysdeps/unix/sysv/linux/kernel-posix-cpu-timers.h). With this patch one can run more tests on OSv with Linux dynamic linker: scripts/test.py --linux_ld -m modules/tests-with-linux-ld/usr.manifest \ -d tst-kill \ -d tst-sigaction \ -d tst-sigwait \ -d tst-stdio-rofs \ -d tst-wctype Signed-off-by: Waldemar Kozaczuk <[email protected]> Closes #1286 --- diff --git a/libc/pthread.cc b/libc/pthread.cc --- a/libc/pthread.cc +++ b/libc/pthread.cc @@ -325,7 +325,10 @@ int pthread_getcpuclockid(pthread_t thread, clockid_t *clock_id) if (clock_id) { pthread *p = pthread::from_libc(thread); auto id = p->_thread->id(); - *clock_id = id + _OSV_CLOCK_SLOTS; + //Follow the same formula glibc and musl use to create + //a negative clock_id that is then used by Linux kernel when + //handling get_clocktime (see https://git.musl-libc.org/cgit/musl/tree/src/thread/pthread_getcpuclockid.c) + *clock_id = (-id - 1) * 8U + 6; } return 0; } diff --git a/libc/pthread.hh b/libc/pthread.hh --- a/libc/pthread.hh +++ b/libc/pthread.hh @@ -12,12 +12,6 @@ extern "C" { #endif -// Linux's <time.h> defines 9 types of clocks. We reserve space for 16 slots -// and use the clock ids afterwards for per-thread clocks. This is OSv- -// specific, and an application doesn't need to know about it - only -// pthread_getcpuclockid() and clock_gettime() need to know about this. -#define _OSV_CLOCK_SLOTS 16 - #ifdef __cplusplus } diff --git a/libc/time.cc b/libc/time.cc --- a/libc/time.cc +++ b/libc/time.cc @@ -96,11 +96,20 @@ int clock_gettime(clockid_t clk_id, struct timespec* ts) break; default: - if (clk_id < _OSV_CLOCK_SLOTS) { + //At this point we should only let the negative numbers + //which represent clock_id for specific thread + if (clk_id >= 0) { return libc_error(EINVAL); } else { - auto thread = sched::thread::find_by_id(clk_id - _OSV_CLOCK_SLOTS); - fill_ts(thread->thread_clock(), ts); + //Reverse the formula used in pthread_getcpuclockid() + //and calculate thread id given clk_id + pid_t tid = (-clk_id - 2) / 8; + auto thread = sched::thread::find_by_id(tid); + if (thread) { + fill_ts(thread->thread_clock(), ts); + } else { + return libc_error(EINVAL); + } } } @@ -124,7 +133,9 @@ int clock_getres(clockid_t clk_id, struct timespec* ts) case CLOCK_MONOTONIC_RAW: break; default: - if (clk_id < _OSV_CLOCK_SLOTS) { + //At this point we should only let the negative numbers + //which represent clock_id for specific thread + if (clk_id >= 0) { return libc_error(EINVAL); } } -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/000000000000d5ae0d060cc96102%40google.com.
