X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Flinux-os.c;h=b7ceca179cc24294f9b926ff72e9f791500a4e41;hb=bf40ae88bc289fd765a33861cc4bc0853ed483ba;hp=bc87f2a22142f9d27f8f719c3bc1ef54d42da0c4;hpb=dd54f9e004a0a83d1328e94648f48dcc27e0be5b;p=sbcl.git diff --git a/src/runtime/linux-os.c b/src/runtime/linux-os.c index bc87f2a..b7ceca1 100644 --- a/src/runtime/linux-os.c +++ b/src/runtime/linux-os.c @@ -55,6 +55,10 @@ #else #include "cheneygc-internal.h" #endif +#include +#ifdef LISP_FEATURE_SB_WTIMER +# include +#endif #ifdef LISP_FEATURE_X86 /* Prototype for personality(2). Done inline here since the header file @@ -482,3 +486,61 @@ os_get_runtime_executable_path(int external) return copied_string(path); } + +#ifdef LISP_FEATURE_SB_WTIMER +/* + * Waitable timer implementation for the safepoint-based (SIGALRM-free) + * timer facility using timerfd_create(). + */ +int +os_create_wtimer() +{ + int fd = timerfd_create(CLOCK_MONOTONIC, 0); + if (fd == -1) + lose("os_create_wtimer: timerfd_create"); + + /* Cannot count on TFD_CLOEXEC availability, so do it manually: */ + if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + lose("os_create_wtimer: fcntl"); + + return fd; +} + +int +os_wait_for_wtimer(int fd) +{ + unsigned char buf[8]; + int n = read(fd, buf, sizeof(buf)); + if (n == -1) { + if (errno == EINTR) + return -1; + lose("os_wtimer_listen failed"); + } + if (n != sizeof(buf)) + lose("os_wtimer_listen read too little"); + return 0; +} + +void +os_close_wtimer(int fd) +{ + if (close(fd) == -1) + lose("os_close_wtimer failed"); +} + +void +os_set_wtimer(int fd, int sec, int nsec) +{ + struct itimerspec spec = { {0,0}, {0,0} }; + spec.it_value.tv_sec = sec; + spec.it_value.tv_nsec = nsec; + if (timerfd_settime(fd, 0, &spec, 0) == -1) + lose("timerfd_settime"); +} + +void +os_cancel_wtimer(int fd) +{ + os_set_wtimer(fd, 0, 0); +} +#endif