+ undoably_install_low_level_interrupt_handler(SIG_MEMORY_FAULT,
+ sigsegv_handler);
+
+ /* OAOOM c.f. linux-os.c.
+ * Should we have a reusable function gc_install_interrupt_handlers? */
+#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
+}
+
+char *
+os_get_runtime_executable_path(int external)
+{
+ char path[] = "/proc/self/object/a.out";
+
+ if (external || access(path, R_OK) == -1)
+ return NULL;
+
+ return copied_string(path);
+}
+
+#ifdef LISP_FEATURE_SB_WTIMER
+/*
+ * Waitable timer implementation for the safepoint-based (SIGALRM-free)
+ * timer facility using SunOS completion ports.
+ */
+
+struct os_wtimer {
+ int port;
+ int timer;
+};
+
+struct os_wtimer *
+os_create_wtimer()
+{
+ int port = port_create();
+ if (port == -1) {
+ perror("port_create");
+ lose("os_create_wtimer");
+ }
+
+ port_notify_t pn;
+ pn.portnfy_port = port;
+ pn.portnfy_user = 0;
+
+ struct sigevent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.sigev_notify = SIGEV_PORT;
+ ev.sigev_value.sival_ptr = &pn;
+
+ timer_t timer;
+ if (timer_create(CLOCK_HIGHRES, &ev, &timer) == -1
+ && (errno != EPERM || timer_create(CLOCK_REALTIME, &ev, &timer) == -1))
+ {
+ perror("timer_create");
+ lose("os_create_wtimer");
+ }
+
+ struct os_wtimer *wt = malloc(sizeof(struct os_wtimer));
+ if (!wt)
+ lose("os_create_wtimer: malloc");
+
+ wt->port = port;
+ wt->timer = timer;
+ return wt;
+}
+
+int
+os_wait_for_wtimer(struct os_wtimer *wt)
+{
+ port_event_t pe;
+ if (port_get(wt->port, &pe, 0) == -1) {
+ if (errno == EINTR)
+ return 1;
+ perror("port_get");
+ lose("os_wtimer_listen failed");
+ }
+ return 0;