X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fbsd-os.c;h=4c08b9798a733632d92c32b3eb35abc4c8d247e0;hb=eac461c1f1ca91cfe282c779291d582ed6b336cb;hp=eeaf7550714341d9e680a34efac3d888e87ec11e;hpb=e6f4c7523aa628ece995ee01879d3fb90eed6d9f;p=sbcl.git diff --git a/src/runtime/bsd-os.c b/src/runtime/bsd-os.c index eeaf755..4c08b97 100644 --- a/src/runtime/bsd-os.c +++ b/src/runtime/bsd-os.c @@ -45,6 +45,11 @@ #if defined LISP_FEATURE_GENCGC #include "gencgc-internal.h" #endif + +#if defined(LISP_FEATURE_SB_WTIMER) && !defined(LISP_FEATURE_DARWIN) +# include +#endif + os_vm_size_t os_vm_page_size; @@ -213,6 +218,10 @@ memory_fault_handler(int signal, siginfo_t *siginfo, os_context_t *context) FSHOW((stderr, "Memory fault at: %p, PC: %p\n", fault_addr, *os_context_pc_addr(context))); +#ifdef LISP_FEATURE_SB_SAFEPOINT + if (!handle_safepoint_violation(context, fault_addr)) +#endif + if (!gencgc_handle_wp_violation(fault_addr)) if(!handle_guard_page_triggered(context,fault_addr)) lisp_memory_fault_error(context, fault_addr); @@ -241,9 +250,15 @@ os_install_interrupt_handlers(void) memory_fault_handler); #endif -#ifdef THREADS_USING_GCSIGNAL +#ifdef LISP_FEATURE_SB_THREAD +# ifdef LISP_FEATURE_SB_SAFEPOINT +# ifdef LISP_FEATURE_SB_THRUPTION + undoably_install_low_level_interrupt_handler(SIGPIPE, thruption_handler); +# endif +# else undoably_install_low_level_interrupt_handler(SIG_STOP_FOR_GC, sig_stop_for_gc_handler); +# endif #endif SHOW("leaving os_install_interrupt_handlers()"); } @@ -557,3 +572,60 @@ os_dlsym(void *handle, const char *symbol) } #endif + +#if defined(LISP_FEATURE_SB_WTIMER) && !defined(LISP_FEATURE_DARWIN) +/* + * Waitable timer implementation for the safepoint-based (SIGALRM-free) + * timer facility using kqueue. + */ +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 kevent ev; + int n; + if ( (n = kevent(kq, 0, 0, &ev, 1, 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) +{ + long long msec + = ((long long) sec) * 1000 + (long long) (nsec+999999) / 1000000; + if (msec > INT_MAX) msec = INT_MAX; + + struct kevent ev; + EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE|EV_ONESHOT, 0, (int)msec, 0); + if (kevent(kq, &ev, 1, 0, 0, 0) == -1) + perror("os_set_wtimer: kevent"); +} + +void +os_cancel_wtimer(int kq) +{ + struct kevent ev; + EV_SET(&ev, 1, EVFILT_TIMER, EV_DISABLE, 0, 0, 0); + if (kevent(kq, &ev, 1, 0, 0, 0) == -1 && errno != ENOENT) + perror("os_cancel_wtimer: kevent"); +} +#endif