#include "gencgc-internal.h"
#endif
+#ifdef LISP_FEATURE_SB_WTIMER
+# include <port.h>
+# include <time.h>
+# include <errno.h>
+#endif
+
os_vm_size_t os_vm_page_size=0;
void
if (addr == MAP_FAILED) {
perror("mmap");
- lose ("Error in mmap(..)\n");
+ /* While it is generally hard to recover from out-of-memory
+ * situations, we require callers to decide on the right course
+ * of action here. Consider thread creation: Failure to mmap
+ * here is common if users have started too many threads, and
+ * often we can recover from that and treat it as an ordinary
+ * error. */
+ return 0;
}
return addr;
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;
+}
+
+void
+os_close_wtimer(struct os_wtimer *wt)
+{
+ if (close(wt->port) == -1) {
+ perror("close");
+ lose("os_close_wtimer");
+ }
+ if (timer_delete(wt->timer) == -1) {
+ perror("timer_delete");
+ lose("os_close_wtimer");
+ }
+ free(wt);
+}
+
+void
+os_set_wtimer(struct os_wtimer *wt, int sec, int nsec)
+{
+ struct itimerspec spec;
+ spec.it_value.tv_sec = sec;
+ spec.it_value.tv_nsec = nsec;
+ spec.it_interval.tv_sec = 0;
+ spec.it_interval.tv_nsec = 0;
+ if (timer_settime(wt->timer, 0, &spec, 0) == -1) {
+ int x = errno;
+ perror("timer_settime");
+ if (x != EINVAL)
+ lose("os_set_wtimer");
+ }
+}
+
+void
+os_cancel_wtimer(struct os_wtimer *wt)
+{
+ os_set_wtimer(wt, 0, 0);
+}
+#endif