Before asking this on the lkml and waisting peoples time I thought I would seek advice here first. I am experimenting with Ingo Molnars rt patch which among other things, includes high res timer support. I'm not having a problems with the timers them selves but am seeing an anomaly with clock_nanosleep. It seems to return early. I have a short sample program that shows the anomaly. Could someone tell me if I am crazy, just plain wrong, or maybe even right? I am running the 2.6.16-rt23 patch and have the userland high-res timers hooks in place. The following program shows early returns on every 2.6.16-rt23 box I have tried it on. I don't want to bother the developers if my program is broken so if anyone can advise I would appreciate it. Thanks and regards Mark To build this: cc hr_nsleep.c -o hr_nsleep -lposix-time #include <stdlib.h> #include <stdint.h> #include <stdio.h> #include <posix_time.h> int64_t get_nsec_64(); #define MAX_FAILURES 50 int main() { int64_t start_nsecs; int64_t elapsed_nsecs; int64_t latency_nsecs; int32_t i, x; int32_t failures = 0; struct timespec tim; int64_t failed_elapsed_nsecs[MAX_FAILURES]; int64_t failed_latency_nsecs[MAX_FAILURES]; struct timespec failed_sleeps[MAX_FAILURES]; struct timespec sleep[16] = { {0, 10 * 1000}, {0, 20 * 1000}, {0, 40 * 1000}, {0, 80 * 1000}, {0, 100 * 1000}, {0, 200 * 1000}, {0, 400 * 1000}, {0, 800 * 1000}, {0, 1000 * 1000}, {0, 2000 * 1000}, {0, 4000 * 1000}, {0, 8000 * 1000}, {0, 10000 * 1000}, {0, 20000 * 1000}, {0, 40000 * 1000}, {0, 80000 * 1000}, }; for (x = 0; x < 10000; x++) { for (i = 0; i < 16; i++) { clock_gettime(CLOCK_MONOTONIC, &tim); tim.tv_sec += sleep[i].tv_sec; tim.tv_nsec += sleep[i].tv_nsec; if (tim.tv_nsec > 1000000000) { tim.tv_sec++; tim.tv_nsec -= 1000000000; } start_nsecs = get_nsec_64(); while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &tim, NULL) && errno == EINTR); elapsed_nsecs = (get_nsec_64() - start_nsecs); latency_nsecs = (elapsed_nsecs - (int64_t)(sleep[i].tv_nsec)); if (latency_nsecs <= 0) { failed_elapsed_nsecs[failures] = elapsed_nsecs; failed_latency_nsecs[failures] = latency_nsecs; failed_sleeps[failures] = sleep[i]; failures++; } if (failures >= MAX_FAILURES) break; } if (failures >= MAX_FAILURES) break; } for (i = 0; i < failures; i++) { printf("\nAttempted sleep of %8d nsecs.\n" \ "Actual sleep %8lld nsecs. BAD %8lld nsecs\n", (int32_t) failed_sleeps[i].tv_nsec, failed_elapsed_nsecs[i], failed_latency_nsecs[i]); } exit(0); } int64_t get_nsec_64() { int64_t ret; struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); ret = (int64_t) (((int64_t) ts.tv_sec * 1000000000) + (int64_t) ts.tv_nsec); return (ret); } -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/