[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#594742: libc6: clock_gettime(CLOCK_MONOTONIC) not monotonic



reassign 594742 linux-2.6
retitle Bug#594742: linux-2.6: clock_gettime not monotonic
thanks

On Sun, Aug 29, 2010 at 12:16:29AM +0200, Manuel Bilderbeek wrote:
> Package: libc6
> Version: 2.11.2-2
> Severity: normal
> 
> This program:
> 
> #include <time.h>
> #include <assert.h>
> #include <stdio.h>
> int main()
> {
> 	struct timespec last_time, current_time;
> 	int r;
> 	clockid_t id;
> 	assert(clock_gettime(CLOCK_MONOTONIC, &last_time) == 0);
> 	r = clock_getcpuclockid(0, &id);
> 	printf("r: %d, id: %d\n", r, id);
> 	while (1) {
> 		assert(clock_gettime(CLOCK_MONOTONIC, &current_time) == 0);
> 		assert(current_time.tv_sec >= last_time.tv_sec);
> 		assert((current_time.tv_sec > last_time.tv_sec) ||
> 				(current_time.tv_nsec >= last_time.tv_nsec));
> 		last_time = current_time;
> 	}
> }
> 
> when run:
> 
> $ gcc -std=gnu99 -lrt monotonic2.c && ./a.out
> r: 0, id: -6
> a.out: monotonic2.c:16: main: Assertion `(current_time.tv_sec > last_time.tv_sec) || (current_time.tv_nsec >= last_time.tv_nsec)' failed.
> 
> Shouldn't trigger an assert... The function guarantees monotonic time
> increments, but apparently that promise is broken here. I am running
> this on an SMP system, but the output of clock_getcpuclockid(0) is not
> ENOENT, so it should really be monotonic...
> 
> The CPU is an Intel Q9450.
> 

The GNU libc simply uses a kernel syscall to get this time. My guess is
that it happens when the thread is moving from one CPU to another, the
RDTSC are jumping are they are not synchronized.

Anyway, as I think it is a kernel bug, I am reassigning it to this
package.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net



Reply to: