X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fdarwin-os.c;h=fbbae266e20a2cd7099e62a21200290741f6a9a7;hb=bb9b382751d808c76592ce2484c33f8447db6568;hp=5e6642fbde9d46d2735dc4dfc86e3aaafc5000f7;hpb=e05f13837227104f8fa3441ff1085982fab20e2c;p=sbcl.git diff --git a/src/runtime/darwin-os.c b/src/runtime/darwin-os.c index 5e6642f..fbbae26 100644 --- a/src/runtime/darwin-os.c +++ b/src/runtime/darwin-os.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -163,6 +164,66 @@ mach_fork() { return pid; } } +#endif +void darwin_init(void) +{ +#ifdef LISP_FEATURE_MACH_EXCEPTION_HANDLER + setup_mach_exception_handling_thread(); #endif +} + + +#ifdef LISP_FEATURE_SB_THREAD + +inline void +os_sem_init(os_sem_t *sem, unsigned int value) +{ + if (KERN_SUCCESS!=semaphore_create(current_mach_task, sem, SYNC_POLICY_FIFO, (int)value)) + lose("os_sem_init(%p): %s", sem, strerror(errno)); +} + +inline void +os_sem_wait(os_sem_t *sem, char *what) +{ + kern_return_t ret; + restart: + FSHOW((stderr, "%s: os_sem_wait(%p)\n", what, sem)); + ret = semaphore_wait(*sem); + FSHOW((stderr, "%s: os_sem_wait(%p) => %s\n", what, sem, + KERN_SUCCESS==ret ? "ok" : strerror(errno))); + 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, "%s: os_sem_wait(%p): %s", what, sem, strerror(errno)); + /* This is analogous to POSIX EINTR. */ + case KERN_ABORTED: + goto restart; + default: + lose("%s: os_sem_wait(%p): %lu, %s", what, sem, ret, strerror(errno)); + } +} + +void +os_sem_post(os_sem_t *sem, char *what) +{ + if (KERN_SUCCESS!=semaphore_signal(*sem)) + lose("%s: os_sem_post(%p): %s", what, sem, strerror(errno)); + FSHOW((stderr, "%s: os_sem_post(%p) ok\n", what, sem)); +} + +void +os_sem_destroy(os_sem_t *sem) +{ + if (-1==semaphore_destroy(current_mach_task, *sem)) + lose("os_sem_destroy(%p): %s", sem, strerror(errno)); +} +#endif