X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Flinux-os.c;h=6724d15719cf71666bcd946e91f7733cc2ee354e;hb=85483d976cc2d779493985f77f39efefb2ea622b;hp=993c51c369e96d0fc0fc6ffea120ba53e3a6df7c;hpb=79cc569a97e444389350ea3f5b1017374fe16bec;p=sbcl.git diff --git a/src/runtime/linux-os.c b/src/runtime/linux-os.c index 993c51c..6724d15 100644 --- a/src/runtime/linux-os.c +++ b/src/runtime/linux-os.c @@ -47,10 +47,20 @@ #include "validate.h" #include "thread.h" +#include "gc.h" +#if defined LISP_FEATURE_GENCGC +#include "gencgc-internal.h" +#endif + +#ifdef LISP_FEATURE_LINUX +#include +#endif + size_t os_vm_page_size; #ifdef LISP_FEATURE_SB_THREAD -#include +#include +#include #include /* values taken from the kernel's linux/futex.h. This header file @@ -61,22 +71,47 @@ size_t os_vm_page_size; #define FUTEX_FD (2) #define FUTEX_REQUEUE (3) -#define __NR_sys_futex __NR_futex +#define sys_futex sbcl_sys_futex +static inline int sys_futex (void *futex, int op, int val, struct timespec *rel) +{ + return syscall (SYS_futex, futex, op, val, rel); +} -_syscall4(int,sys_futex, - int *, futex, - int, op, - int, val, - struct timespec *, rel); +int +futex_wait(int *lock_word, int oldval) +{ + int t= sys_futex(lock_word,FUTEX_WAIT,oldval, 0); + return t; +} + +int +futex_wake(int *lock_word, int n) +{ + return sys_futex(lock_word,FUTEX_WAKE,n,0); +} #endif -#include "gc.h" int linux_sparc_siginfo_bug = 0; int linux_no_threads_p = 0; +#ifdef LISP_FEATURE_SB_THREAD +int isnptl (void) +{ + size_t n = confstr (_CS_GNU_LIBPTHREAD_VERSION, NULL, 0); + if (n > 0) + { + char *buf = alloca (n); + confstr (_CS_GNU_LIBPTHREAD_VERSION, buf, n); + if (strstr (buf, "NPTL")) + return 1; + } + return 0; +} +#endif + void -os_init(void) +os_init(char *argv[], char *envp[]) { /* Conduct various version checks: do we have enough mmap(), is * this a sparc running 2.2, can we do threads? */ @@ -104,11 +139,50 @@ os_init(void) } #ifdef LISP_FEATURE_SB_THREAD futex_wait(futex,-1); - if(errno==ENOSYS) linux_no_threads_p = 1; - if(linux_no_threads_p) - fprintf(stderr,"Linux with NPTL support (e.g. kernel 2.6 or newer) required for \nthread-enabled SBCL. Disabling thread support.\n\n"); + if(errno==ENOSYS) { + lose("This version of sbcl is compiled with threading support, but your kernel is too old to support this.\n\ +Please use a more recent kernel or a version of sbcl without threading support.\n"); + } + if(! isnptl()) { + lose("This version of sbcl only works correctly with the NPTL threading library. Please use a newer glibc, older sbcl or stop using LD_ASSUME_KERNEL"); + } #endif os_vm_page_size = getpagesize(); + + /* KLUDGE: Disable memory randomization on new Linux kernels + * by setting a personality flag and re-executing. (We need + * to re-execute, since the memory maps that can conflict with + * the SBCL spaces have already been done at this point). + */ +#if defined(LISP_FEATURE_X86) + if ((major_version == 2 && minor_version >= 6) + || major_version >= 3) + { + long pers = personality(-1); + /* 0x40000 aka. ADDR_NO_RANDOMIZE */ + if (!(pers & 0x40000)) { + if (personality(pers | 0x40000) != -1) { + /* Use /proc/self/exe instead of trying to figure out the + * executable path from PATH and argv[0], since that's + * unreliable. We follow the symlink instead of executing + * the file directly to avoid top from displaying the + * name of the process as "exe". + */ + char runtime[PATH_MAX+1]; + int i = readlink("/proc/self/exe", runtime, PATH_MAX); + if (i != -1) { + runtime[i] = '\0'; + execve(runtime, argv, envp); + } + } + /* Either changing the personality or execve() failed. Either + * way we might as well continue, and hope that the random + * memory maps are ok this time around. + */ + fprintf(stderr, "WARNING: Couldn't re-execute SBCL with the proper personality flags (maybe /proc isn't mounted?). Trying to continue anyway.\n"); + } + } +#endif } @@ -125,13 +199,10 @@ os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len) { int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; - os_vm_address_t actual ; + os_vm_address_t actual; - if (addr) - flags |= MAP_FIXED; #ifdef LISP_FEATURE_ALPHA - else { - flags |= MAP_FIXED; + if (!addr) { addr=under_2gb_free_pointer; } #endif @@ -275,18 +346,3 @@ os_install_interrupt_handlers(void) sig_stop_for_gc_handler); #endif } - -#ifdef LISP_FEATURE_SB_THREAD -int -futex_wait(int *lock_word, int oldval) -{ - int t= sys_futex(lock_word,FUTEX_WAIT,oldval, 0); - return t; -} - -int -futex_wake(int *lock_word, int n) -{ - return sys_futex(lock_word,FUTEX_WAKE,n,0); -} -#endif