Current uClibc-ng version incorrectly calculates clockid in pthread_getcpuclockid (at least for modern kernels). The simplest test program
#include <time.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <pthread.h>
int main() { clockid_t clk; struct timespec ts; const int err = pthread_getcpuclockid(pthread_self(), &clk);
if (err != 0) { errno = err; perror("pthread_getcpuclockid"); return EXIT_FAILURE; }
if (clock_gettime(clk, &ts) == -1) { perror("clock_gettime"); return EXIT_FAILURE; }
printf("Thread time is %lu.%06lu.\n", ts.tv_sec, ts.tv_nsec / 1000);
return EXIT_SUCCESS; }
fails with
clock_gettime: Invalid argument
Tested on Linux 3.4 / MIPS built with GCC 5.4.0.
Other implementations, for example musl, use a simple calculation https://git.musl-libc.org/cgit/musl/tree/src/thread/pthread_getcpuclockid.c
Looks strange, but the official glibc repository https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=nptl/pthread_getcpucl... has the same implementation as in uClibc-ng.
This fork https://github.com/lattera/glibc/blob/master/nptl/sysdeps/unix/sysv/linux/pt... use more accurate approach relying on __NR_clock_getres (defined in the kernel since 2.6.24) with MAKE_THREAD_CPUCLOCK macro copied from the kernel ( http://lxr.free-electrons.com/source/include/linux/posix-timers.h?v=2.6.24#L..., Linux 4.10 has the same one).
I propose an intermediate solution: use MAKE_THREAD_CPUCLOCK like computation of clockid when __NR_clock_getres defined and do a fallback to an older implementation when not.
Sorry,
Latests official glibc in system dependent implementation for Linux simply use MAKE_THREAD_CPUCLOCK https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/pth...
On Wed, Apr 26, 2017 at 2:22 AM, Sergey Korolev s.korolev@ndmsystems.com wrote:
Current uClibc-ng version incorrectly calculates clockid in pthread_getcpuclockid (at least for modern kernels). The simplest test program
#include <time.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <pthread.h>
int main() { clockid_t clk; struct timespec ts; const int err = pthread_getcpuclockid(pthread_self(), &clk);
if (err != 0) { errno = err; perror("pthread_getcpuclockid"); return EXIT_FAILURE; } if (clock_gettime(clk, &ts) == -1) { perror("clock_gettime"); return EXIT_FAILURE; } printf("Thread time is %lu.%06lu.\n", ts.tv_sec, ts.tv_nsec / 1000); return EXIT_SUCCESS;
}
fails with
clock_gettime: Invalid argument
Tested on Linux 3.4 / MIPS built with GCC 5.4.0.
Other implementations, for example musl, use a simple calculation https://git.musl-libc.org/cgit/musl/tree/src/thread/ pthread_getcpuclockid.c
Looks strange, but the official glibc repository https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=nptl/ pthread_getcpuclockid.c;hb=HEAD has the same implementation as in uClibc-ng.
This fork https://github.com/lattera/glibc/blob/master/ nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c use more accurate approach relying on __NR_clock_getres (defined in the kernel since 2.6.24) with MAKE_THREAD_CPUCLOCK macro copied from the kernel (http://lxr.free-electrons.com/source/include/linux/ posix-timers.h?v=2.6.24#L34, Linux 4.10 has the same one).
I propose an intermediate solution: use MAKE_THREAD_CPUCLOCK like computation of clockid when __NR_clock_getres defined and do a fallback to an older implementation when not.
Hi Sergey, Sergey Korolev wrote,
Current uClibc-ng version incorrectly calculates clockid in pthread_getcpuclockid (at least for modern kernels). The simplest test program
fails with
clock_gettime: Invalid argument
Tested on Linux 3.4 / MIPS built with GCC 5.4.0.
Thanks for the test case.
Other implementations, for example musl, use a simple calculation https://git.musl-libc.org/cgit/musl/tree/src/thread/pthread_getcpuclockid.c
Looks strange, but the official glibc repository https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=nptl/ pthread_getcpuclockid.c;hb=HEAD has the same implementation as in uClibc-ng.
uClibc imported NPTL from GNU libc in 2005. There are still many similaraties.
Will you propose a new patch? ( I have read your second mail)
best regards Waldemar
Hi, Waldemar.
Should uClibc-ng support Linux kernels before 2.6.24?
On Thu, Apr 27, 2017 at 8:33 AM, Waldemar Brodkorb wbx@uclibc-ng.org wrote:
Hi Sergey, Sergey Korolev wrote,
Current uClibc-ng version incorrectly calculates clockid in pthread_getcpuclockid (at least for modern kernels). The simplest test program
fails with
clock_gettime: Invalid argument
Tested on Linux 3.4 / MIPS built with GCC 5.4.0.
Thanks for the test case.
Other implementations, for example musl, use a simple calculation https://git.musl-libc.org/cgit/musl/tree/src/thread/
pthread_getcpuclockid.c
Looks strange, but the official glibc repository https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=nptl/ pthread_getcpuclockid.c;hb=HEAD has the same implementation as in uClibc-ng.
uClibc imported NPTL from GNU libc in 2005. There are still many similaraties.
Will you propose a new patch? ( I have read your second mail)
best regards Waldemar
Hi,
I found that MAKE_THREAD_CPUCLOCK really introduced in Linux 2.6.12 with POSIX timers implementation. So it is safe to change clockid computation for all kernels (that support POSIX timers).
On Thu, Apr 27, 2017 at 9:23 AM, Waldemar Brodkorb wbx@uclibc-ng.org wrote:
Hi, Sergey Korolev wrote,
Hi, Waldemar.
Should uClibc-ng support Linux kernels before 2.6.24?
That would be good, some users still use something like 2.6.18 IIRC.
best regards Waldemar
Hi, Sergey Korolev wrote,
Hi,
I found that MAKE_THREAD_CPUCLOCK really introduced in Linux 2.6.12 with POSIX timers implementation. So it is safe to change clockid computation for all kernels (that support POSIX timers).
Will you sent a new patch?
thanks Waldemar
Hi, Waldemar.
No, I suppose my lastest patch is sufficient to fix a bug for all kernels
= 2.6.12.
Regards, Sergey.
On Sun, Apr 30, 2017 at 11:38 AM, Waldemar Brodkorb wbx@uclibc-ng.org wrote:
Hi, Sergey Korolev wrote,
Hi,
I found that MAKE_THREAD_CPUCLOCK really introduced in Linux 2.6.12 with POSIX timers implementation. So it is safe to change clockid computation for all kernels (that support POSIX timers).
Will you sent a new patch?
thanks Waldemar
Hi Sergey, Sergey Korolev wrote,
Hi, Waldemar.
No, I suppose my lastest patch is sufficient to fix a bug for all kernels >= 2.6.12.
Thanks, I added your test-case to uclibc-ng-test and your patch to master uclibc-ng.
best regards Waldemar