Messages in this thread |  | | Date | Sun, 23 Sep 2007 19:33:48 +0200 | | From | Michael Kerrisk <> | | Subject | Re: RFC: A revised timerfd API |
| |
Hi Davide,
Davide Libenzi wrote: > On Sat, 22 Sep 2007, Michael Kerrisk wrote: > >> So I'm inclined to implement option (b), unless someone has strong >> objections. Davide, could I persuade you to help? > > I guess I better do, otherwise you'll continue to stress me ;)
Thanks -- that was more than I hoped for!
> int timerfd_create(int clockid); > int timerfd_settime(int ufd, int flags, > const struct itimerspec *utmr, > struct itimerspec *otmr); > int timerfd_gettime(int ufd, struct itimerspec *otmr); > > Patch below. Builds, not tested yet (you need to remove the "broken" > status from CONFIG_TIMERFD in case you want to test - and plug the new > syscall to arch/xxx).
I applied this patch against 2.6.27-rc7, and wired up the syscalls as shown in the definitions below. When I ran the the program below, my system immediately froze. Can you try it on your system please.
Cheers,
Michael
/* Link with -lrt */
#define _GNU_SOURCE #include <sys/syscall.h> #include <unistd.h> #include <time.h> #if defined(__i386__) #define __NR_timerfd_create 325 #define __NR_timerfd_settime 326 #define __NR_timerfd_gettime 327 17170:man-pages/man2> cat timerfd3_test.c /* Link with -lrt */
#define _GNU_SOURCE #include <sys/syscall.h> #include <unistd.h> #include <time.h> #if defined(__i386__) #define __NR_timerfd_create 325 #define __NR_timerfd_settime 326 #define __NR_timerfd_gettime 327 #endif
static int timerfd_create(int clockid) { return syscall(__NR_timerfd_create, clockid); }
static int timerfd_settime(int ufd, int flags, struct itimerspec *utmr, struct itimerspec *outmr) { return syscall(__NR_timerfd_settime, ufd, flags, utmr, outmr); }
static int timerfd_gettime(int ufd, struct itimerspec *outmr) { return syscall(__NR_timerfd_gettime, ufd, outmr); }
/* static int timerfd(int ufd, int clockid, int flags, struct itimerspec *utmr, struct itimerspec *outmr) { return syscall(__NR_timerfd, ufd, clockid, flags, utmr, outmr); }
*/
/* int timerfd_settime(int ufd, int flags, > > const struct itimerspec *utmr, > > struct itimerspec *otmr); > > int timerfd_gettime(int ufd, struct itimerspec *otmr) */ #define TFD_TIMER_ABSTIME (1 << 0)
////////////////////////////////////////////////////////////
// #include <sys/timerfd.h> #include <time.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <stdint.h> /* Definition of uint32_t */
#define die(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
static void print_elapsed_time(void) { static struct timespec start; struct timespec curr; static int first_call = 1; int secs, nsecs;
if (first_call) { first_call = 0; if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) die("clock_gettime"); }
if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) die("clock_gettime");
secs = curr.tv_sec - start.tv_sec; nsecs = curr.tv_nsec - start.tv_nsec; if (nsecs < 0) { secs--; nsecs += 1000000000; } printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000); }
int main(int argc, char *argv[]) { struct itimerspec utmr, outmr; int ufd; struct timespec now; int j, s; uint64_t exp; time_t start;
if (argc < 2) { fprintf(stderr, "%s init-secs [interval-secs]\n", argv[0]); exit(EXIT_FAILURE); }
if (clock_gettime(CLOCK_REALTIME, &now) == -1) die("clock_gettime");
/* Create a CLOCK_REALTIME absolute timer with initial expiration and interval as specified in command line */
utmr.it_value.tv_sec = now.tv_sec + atoi(argv[1]); utmr.it_value.tv_nsec = now.tv_nsec; if (argc == 2) { utmr.it_interval.tv_sec = 0; } else { utmr.it_interval.tv_sec = atoi(argv[2]); } utmr.it_interval.tv_nsec = 0;
ufd = timerfd_create(CLOCK_REALTIME); if (ufd == -1) die("timerfd"); s = timerfd_settime(ufd, TFD_TIMER_ABSTIME, &utmr, NULL); if (ufd == -1) die("timerfd");
start = time(NULL); for (j = 0; ; j++) { sleep(1); if (0 && (j % 10) == 0) { printf("Resetting timer\n"); utmr.it_value.tv_sec += 1; utmr.it_interval.tv_sec += 2; s = timerfd_settime(ufd, 0, &utmr, &outmr); if (s == -1) die("timerfd-2");
} s = timerfd_gettime(ufd, &outmr); printf("Retrieval %3d (%3ld) - Got: %ld %ld; %ld %ld\n", j, (long) (time(NULL) - start), (long) outmr.it_value.tv_sec, (long) outmr.it_value.tv_nsec, (long) outmr.it_interval.tv_sec, (long) outmr.it_interval.tv_nsec); if ((j % 30) == 0 && j > 0) { printf("About to read\n"); s = read(ufd, &exp, sizeof(uint64_t)); if (s != sizeof(uint64_t)) die("read"); printf("Read: %lld\n", exp); } }
exit(EXIT_SUCCESS); }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |