Fix cut-to-width in the presence of bad constants in dead code.
[sbcl.git] / src / runtime / bsd-os.c
index 0d221f5..4c08b97 100644 (file)
@@ -22,6 +22,7 @@
 #include <sys/param.h>
 #include <sys/file.h>
 #include <unistd.h>
+#include <utime.h>
 #include <assert.h>
 #include <errno.h>
 #include "sbcl.h"
 #if defined LISP_FEATURE_GENCGC
 #include "gencgc-internal.h"
 #endif
+
+#if defined(LISP_FEATURE_SB_WTIMER) && !defined(LISP_FEATURE_DARWIN)
+# include <sys/event.h>
+#endif
+
 \f
 os_vm_size_t os_vm_page_size;
 
@@ -70,7 +76,11 @@ static void freebsd_init();
 #include <sys/types.h>
 #include <sys/resource.h>
 #include <sys/stat.h>
+#include <sys/sysctl.h>
 #include <dlfcn.h>
+#ifdef LISP_FEATURE_X86
+#include <machine/cpu.h>
+#endif
 
 static void openbsd_init();
 #endif
@@ -78,7 +88,7 @@ static void openbsd_init();
 void
 os_init(char *argv[], char *envp[])
 {
-    os_vm_page_size = getpagesize();
+    os_vm_page_size = BACKEND_PAGE_BYTES;
 
 #ifdef __NetBSD__
     netbsd_init();
@@ -86,6 +96,8 @@ os_init(char *argv[], char *envp[])
     freebsd_init();
 #elif defined(__OpenBSD__)
     openbsd_init();
+#elif defined(LISP_FEATURE_DARWIN)
+    darwin_init();
 #endif
 }
 
@@ -194,19 +206,9 @@ is_valid_lisp_addr(os_vm_address_t addr)
  */
 
 void
-memory_fault_handler(int signal, siginfo_t *siginfo, os_context_t *context
-#if defined(LISP_FEATURE_FREEBSD) && defined(LISP_FEATURE_X86_64)
-/* FreeBSD/amd64 stores fault address only in undocumented 4th arg. */
-                     ,void *fault_addr
-#endif
-    )
+memory_fault_handler(int signal, siginfo_t *siginfo, os_context_t *context)
 {
-#if defined(LISP_FEATURE_FREEBSD) && defined(LISP_FEATURE_X86_64)
-    /* KLUDGE: Store fault address into si_addr for compatibilities. */
-    siginfo->si_addr = fault_addr;
-#else
     void *fault_addr = arch_get_bad_addr(signal, siginfo, context);
-#endif
 
 #if defined(LISP_FEATURE_RESTORE_TLS_SEGMENT_REGISTER_FROM_CONTEXT)
     FSHOW_SIGNAL((stderr, "/ TLS: restoring fs: %p in memory_fault_handler\n",
@@ -216,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);
@@ -245,8 +251,14 @@ os_install_interrupt_handlers(void)
 #endif
 
 #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()");
 }
@@ -346,6 +358,12 @@ _readdir(DIR *dirp)
     return readdir(dirp);
 }
 
+int
+_utime(const char *file, const struct utimbuf *timep)
+{
+    return utime(file, timep);
+}
+
 /* Used in sb-bsd-sockets. */
 int
 _socket(int domain, int type, int protocol)
@@ -389,7 +407,8 @@ static void freebsd_init()
 #endif /* LISP_FEATURE_X86 */
 }
 
-#if defined(LISP_FEATURE_SB_THREAD) && !defined(LISP_FEATURE_SB_PTHREAD_FUTEX)
+#if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_SB_FUTEX) \
+    && !defined(LISP_FEATURE_SB_PTHREAD_FUTEX)
 int
 futex_wait(int *lock_word, long oldval, long sec, unsigned long usec)
 {
@@ -433,7 +452,7 @@ futex_wake(int *lock_word, int n)
 #endif
 
 char *
-os_get_runtime_executable_path()
+os_get_runtime_executable_path(int external)
 {
     char path[PATH_MAX + 1];
 
@@ -461,35 +480,56 @@ os_get_runtime_executable_path()
 }
 #elif defined(LISP_FEATURE_NETBSD) || defined(LISP_FEATURE_OPENBSD)
 char *
-os_get_runtime_executable_path()
+os_get_runtime_executable_path(int external)
 {
     struct stat sb;
-    char *path = strdup("/proc/curproc/file");
-    if (path && ((stat(path, &sb)) == 0))
-        return path;
-    else {
-        fprintf(stderr, "Couldn't stat /proc/curproc/file; is /proc mounted?\n");
-        return NULL;
-    }
+    if (!external && stat("/proc/curproc/file", &sb) == 0)
+        return copied_string("/proc/curproc/file");
+    return NULL;
 }
 #else /* Not DARWIN or FREEBSD or NETBSD or OPENBSD */
 char *
-os_get_runtime_executable_path()
+os_get_runtime_executable_path(int external)
 {
     return NULL;
 }
 #endif
 
 #ifdef __OpenBSD__
+
+int openbsd_use_fxsave = 0;
+
 void
 openbsd_init()
 {
+#ifdef LISP_FEATURE_X86
+    int mib[2];
+    size_t size;
+#endif
+    /*
+     * Show a warning if it looks like the memory available after
+     * allocating the spaces won't be at least this much.
+     */
+#ifdef LISP_FEATURE_X86_64
+    const int wantfree = 64 * 1024 * 1024;
+#else
+    const int wantfree = 32 * 1024 * 1024;
+#endif
     struct rlimit rl;
 
+#ifdef LISP_FEATURE_X86
+    /* Save the machdep.osfxsr sysctl for use by os_restore_fp_control() */
+    mib[0] = CTL_MACHDEP;
+    mib[1] = CPU_OSFXSR;
+    size = sizeof (openbsd_use_fxsave);
+    sysctl(mib, 2, &openbsd_use_fxsave, &size, NULL, 0);
+#endif
+
     /* OpenBSD, like NetBSD, counts mmap()ed space against the
      * process's data size limit. If the soft limit is lower than the
      * hard limit then try to yank it up, this lets users in the
-     * "staff" login class run sbcl with a default /etc/login.conf
+     * "staff" or "daemon" login classes run sbcl with larger dynamic
+     * space sizes.
      */
     getrlimit (RLIMIT_DATA, &rl);
     if (rl.rlim_cur < rl.rlim_max) {
@@ -503,18 +543,17 @@ The system may fail to start.\n",
         }
     }
 
-    /* Display a (hopefully) helpful warning if it looks like we won't
-     * be able to allocate enough memory. In testing I found that on
-     * my system at least, a minimum of 25M on top of the three space
-     * sizes was needed to start SBCL. Show a warning below 32M so as
-     * to leave a little breathing room.
+    /*
+     * Display a (hopefully) helpful warning if it looks like we won't
+     * be able to allocate enough memory.
      */
     getrlimit (RLIMIT_DATA, &rl);
     if (dynamic_space_size + READ_ONLY_SPACE_SIZE + STATIC_SPACE_SIZE +
-        LINKAGE_TABLE_SPACE_SIZE + (32*1024*1024) > rl.rlim_cur)
+        LINKAGE_TABLE_SPACE_SIZE + wantfree > rl.rlim_cur)
         fprintf (stderr,
                  "RUNTIME WARNING: data size resource limit may be too low,\n"
-                 "  try decreasing the dynamic space size with --dynamic-space-size\n");
+                 "  try decreasing the dynamic space size with --dynamic-space-size\n"
+                 "  or raising the datasize or datasize-max limits in /etc/login.conf\n");
 }
 
 /* OpenBSD's dlsym() relies on the gcc bulitin
@@ -533,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