X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fdarwin-os.c;h=415745ef0b5c9a93eb8692da82f4500a2c337e48;hb=2f9585060d5fe2c525955d80f34123761ded80fe;hp=1103d8f40f11f6a1dd1c2bb6302fd26a45e9e990;hpb=578362575fc2112b828597cc1025e3ead43d43ba;p=sbcl.git diff --git a/src/runtime/darwin-os.c b/src/runtime/darwin-os.c index 1103d8f..415745e 100644 --- a/src/runtime/darwin-os.c +++ b/src/runtime/darwin-os.c @@ -31,6 +31,12 @@ #include #endif +#if defined(LISP_FEATURE_SB_WTIMER) +# include +# include +# include +#endif + char * os_get_runtime_executable_path(int external) { @@ -301,3 +307,71 @@ os_sem_destroy(os_sem_t *sem) } #endif + +#if defined(LISP_FEATURE_SB_WTIMER) + +# error Completely untested. Go ahead! Remove this line, try your luck! + +/* + * Waitable timer implementation for the safepoint-based (SIGALRM-free) + * timer facility using kqueue. + * + * Unlike FreeBSD with its ms (!) timer resolution, Darwin supports ns + * timer resolution -- or at least it pretends to do so on the API + * level (?). To use it, we need the *64 versions of the functions and + * structures. + * + * Unfortunately, I don't run Darwin, and can't test this code, so it's + * just a hopeful translation from FreeBSD. + */ + +int +os_create_wtimer() +{ + int kq = kqueue(); + if (kq == -1) + lose("os_create_wtimer: kqueue"); + return kq; +} + +int +os_wait_for_wtimer(int kq) +{ + struct kevent64_s ev; + int n; + if ( (n = kevent64(kq, 0, 0, &ev, 1, 0, 0)) == -1) { + if (errno != EINTR) + lose("os_wtimer_listen failed"); + n = 0; + } + return n != 1; +} + +void +os_close_wtimer(int kq) +{ + if (close(kq) == -1) + lose("os_close_wtimer failed"); +} + +void +os_set_wtimer(int kq, int sec, int nsec) +{ + int64_t nsec = ((int64_t) sec) * 1000000000 + (int64_t) nsec; + + struct kevent64_s ev; + EV_SET64(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE|EV_ONESHOT, NOTE_NSECONDS, + nsec, 0, 0, 0); + if (kevent64(kq, &ev, 1, 0, 0, 0, 0) == -1) + perror("os_set_wtimer: kevent"); +} + +void +os_cancel_wtimer(int kq) +{ + struct kevent64_s ev; + EV_SET64(&ev, 1, EVFILT_TIMER, EV_DISABLE, 0, 0, 0, 0, 0); + if (kevent64(kq, &ev, 1, 0, 0, 0, 0) == -1 && errno != ENOENT) + perror("os_cancel_wtimer: kevent"); +} +#endif