X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fruntime%2Fdarwin-os.c;h=fbbae266e20a2cd7099e62a21200290741f6a9a7;hb=c58759647c8fc28996c6d519f2a38497c7edb704;hp=f15e11b9287efa4cc1dac8ec7067c1c4d339df8d;hpb=e8c80f67856e7fd94f64574d10b5637fef5af1f6;p=sbcl.git diff --git a/src/runtime/darwin-os.c b/src/runtime/darwin-os.c index f15e11b..fbbae26 100644 --- a/src/runtime/darwin-os.c +++ b/src/runtime/darwin-os.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -36,8 +37,6 @@ os_get_runtime_executable_path(int external) if (_NSGetExecutablePath(path, &size) == -1) return NULL; - else - path[size] = '\0'; return copied_string(path); } @@ -104,10 +103,10 @@ kern_return_t mach_thread_init(mach_port_t thread_exception_port) { kern_return_t ret; - /* allocate a named port for the thread */ + mach_port_t current_mach_thread; + /* allocate a named port for the thread */ FSHOW((stderr, "Allocating mach port %x\n", thread_exception_port)); - ret = mach_port_allocate_name(current_mach_task, MACH_PORT_RIGHT_RECEIVE, thread_exception_port); @@ -124,20 +123,26 @@ mach_thread_init(mach_port_t thread_exception_port) lose("mach_port_insert_right failed with return_code %d\n", ret); } - ret = thread_set_exception_ports(mach_thread_self(), + current_mach_thread = mach_thread_self(); + ret = thread_set_exception_ports(current_mach_thread, EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION, thread_exception_port, EXCEPTION_DEFAULT, THREAD_STATE_NONE); if (ret) { - lose("thread_set_exception_port failed with return_code %d\n", ret); + lose("thread_set_exception_ports failed with return_code %d\n", ret); + } + + ret = mach_port_deallocate (current_mach_task, current_mach_thread); + if (ret) { + lose("mach_port_deallocate failed with return_code %d\n", ret); } ret = mach_port_move_member(current_mach_task, thread_exception_port, mach_exception_handler_port_set); if (ret) { - lose("mach_port_ failed with return_code %d\n", ret); + lose("mach_port_move_member failed with return_code %d\n", ret); } return ret; @@ -159,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