diff --git a/make-config.sh b/make-config.sh index 3820b73c0..40fff6c79 100755 --- a/make-config.sh +++ b/make-config.sh @@ -629,10 +629,12 @@ case "$sbcl_os" in ;; darwin) printf ' :unix :bsd :darwin :mach-o' >> $ltf + darwin_version=`uname -r` + darwin_version_major=${DARWIN_VERSION_MAJOR:-${darwin_version%%.*}} + if (( 10 > $darwin_version_major )) || [ $sbcl_arch = "ppc" ]; then + printf ' :use-darwin-posix-semaphores' >> $ltf + fi if [ $sbcl_arch = "x86-64" ]; then - darwin_version=`uname -r` - darwin_version_major=${DARWIN_VERSION_MAJOR:-${darwin_version%%.*}} - if (( 8 < $darwin_version_major )); then printf ' :inode64' >> $ltf fi diff --git a/make-target-2-load.lisp b/make-target-2-load.lisp index 0a10c6f67..be188f5e3 100644 --- a/make-target-2-load.lisp +++ b/make-target-2-load.lisp @@ -55,6 +55,8 @@ ;; The final batch of symbols is strictly for C. The LISP_FEATURE_ ;; prefix on the corresponding #define is unfortunate. :GCC-TLS :USE-SYS-MMAP + ;;; Enforce using of posix semaphores on Darwin instead of dispatch. + :USE-DARWIN-POSIX-SEMAPHORES ;; only for 'src/runtime/wrap.h' :OS-PROVIDES-BLKSIZE-T ;; only for src/runtime/run-program.c diff --git a/src/runtime/darwin-os.c b/src/runtime/darwin-os.c index f417c8dd7..804dd9b9f 100644 --- a/src/runtime/darwin-os.c +++ b/src/runtime/darwin-os.c @@ -55,7 +55,7 @@ void darwin_init(void) } -#ifdef LISP_FEATURE_SB_THREAD +#if defined LISP_FEATURE_SB_THREAD && defined USE_DARWIN_GCD_SEMAPHORES inline void os_sem_init(os_sem_t *sem, unsigned int value) @@ -141,4 +141,53 @@ futex_wake(int *lock_word, int n) return 0; } #endif + +#elif defined LISP_FEATURE_SB_THREAD && defined CANNOT_USE_POSIX_SEM_T + +inline void +os_sem_init(os_sem_t *sem, unsigned int value) +{ + if (KERN_SUCCESS!=semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, (int)value)) + lose("os_sem_init(%p): %s", sem, strerror(errno)); +} + +inline void +os_sem_wait(os_sem_t *sem) +{ + kern_return_t ret; + restart: + ret = semaphore_wait(*sem); + switch (ret) { + case KERN_SUCCESS: + return; + /* It is unclear just when we can get this, but a sufficiently + * long wait seems to do that, at least sometimes. + * + * However, a wait that long is definitely abnormal for the + * GC, so we complain before retrying. + */ + case KERN_OPERATION_TIMED_OUT: + fprintf(stderr, "os_sem_wait(%p): %s", sem, strerror(errno)); + /* This is analogous to POSIX EINTR. */ + case KERN_ABORTED: + goto restart; + default: + lose("os_sem_wait(%p): %lu, %s", sem, (long unsigned)ret, strerror(errno)); + } +} + +void +os_sem_post(os_sem_t *sem) +{ + if (KERN_SUCCESS!=semaphore_signal(*sem)) + lose("os_sem_post(%p): %s", sem, strerror(errno)); +} + +void +os_sem_destroy(os_sem_t *sem) +{ + if (-1==semaphore_destroy(mach_task_self(), *sem)) + lose("os_sem_destroy(%p): %s", sem, strerror(errno)); +} + #endif diff --git a/src/runtime/darwin-os.h b/src/runtime/darwin-os.h index f13669fb0..dfcc9e8ea 100644 --- a/src/runtime/darwin-os.h +++ b/src/runtime/darwin-os.h @@ -36,10 +36,14 @@ typedef ucontext_t os_context_t; void darwin_init(void); -#ifdef LISP_FEATURE_SB_THREAD +#if defined(LISP_FEATURE_SB_THREAD) && !defined(LISP_FEATURE_USE_DARWIN_POSIX_SEMAPHORES) #define USE_DARWIN_GCD_SEMAPHORES #include typedef dispatch_semaphore_t os_sem_t; +#elif defined LISP_FEATURE_SB_THREAD +#define CANNOT_USE_POSIX_SEM_T +#include +typedef semaphore_t os_sem_t; #endif #endif /* _DARWIN_OS_H */ diff --git a/src/runtime/os-common.c b/src/runtime/os-common.c index 8de5e89aa..b08f1ccc1 100644 --- a/src/runtime/os-common.c +++ b/src/runtime/os-common.c @@ -120,7 +120,7 @@ os_get_errno(void) return errno; } -#if defined LISP_FEATURE_SB_THREAD && defined LISP_FEATURE_UNIX && !defined USE_DARWIN_GCD_SEMAPHORES +#if defined LISP_FEATURE_SB_THREAD && defined LISP_FEATURE_UNIX && !defined USE_DARWIN_GCD_SEMAPHORES && !defined CANNOT_USE_POSIX_SEM_T void os_sem_init(os_sem_t *sem, unsigned int value) { diff --git a/src/runtime/os.h b/src/runtime/os.h index 262896562..55c5296ca 100644 --- a/src/runtime/os.h +++ b/src/runtime/os.h @@ -237,7 +237,7 @@ extern char *os_get_runtime_executable_path(); #define OS_VM_SIZE_FMTX PRIxPTR #if defined LISP_FEATURE_SB_THREAD && defined LISP_FEATURE_UNIX -# ifndef USE_DARWIN_GCD_SEMAPHORES +# if !defined USE_DARWIN_GCD_SEMAPHORES && !defined CANNOT_USE_POSIX_SEM_T # include typedef sem_t os_sem_t; # endif