uint32 runtime·mach_semcreate(void) { union { Tmach_semcreateMsg tx; Rmach_semcreateMsg rx; uint8 pad[MinMachMsg]; } m; int32 r; m.tx.h.msgh_bits = 0; m.tx.h.msgh_size = sizeof(m.tx); m.tx.h.msgh_remote_port = runtime·mach_task_self(); m.tx.h.msgh_id = Tmach_semcreate; m.tx.ndr = zerondr; m.tx.policy = 0; // 0 = SYNC_POLICY_FIFO m.tx.value = 0; while((r = machcall(&m.tx.h, sizeof m, sizeof(m.rx))) != 0){ if(r == KERN_ABORTED) // interrupted continue; macherror(r, "semaphore_create"); } if(m.rx.body.msgh_descriptor_count != 1) unimplemented("mach_semcreate desc count"); return m.rx.semaphore.name; }
void runtime·mach_semrelease(uint32 sem) { int32 r; while((r = runtime·mach_semaphore_signal(sem)) != 0) { if(r == KERN_ABORTED) // interrupted continue; macherror(r, "semaphore_signal"); } }
int32 runtime·mach_semacquire(uint32 sem, int64 ns) { int32 r; if(ns >= 0) { r = runtime·mach_semaphore_timedwait(sem, ns/1000000000LL, ns%1000000000LL); if(r == KERN_ABORTED || r == KERN_OPERATION_TIMED_OUT) return -1; if(r != 0) macherror(r, "semaphore_wait"); return 0; } while((r = runtime·mach_semaphore_wait(sem)) != 0) { if(r == KERN_ABORTED) // interrupted continue; macherror(r, "semaphore_wait"); } return 0; }
void mach_semacquire(uint32 sem) { int32 r; while((r = mach_semaphore_wait(sem)) != 0) { if(r == KERN_ABORTED) // interrupted continue; macherror(r, "semaphore_wait"); } }
void runtime·mach_semdestroy(uint32 sem) { union { Tmach_semdestroyMsg tx; uint8 pad[MinMachMsg]; } m; int32 r; m.tx.h.msgh_bits = MACH_MSGH_BITS_COMPLEX; m.tx.h.msgh_size = sizeof(m.tx); m.tx.h.msgh_remote_port = runtime·mach_task_self(); m.tx.h.msgh_id = Tmach_semdestroy; m.tx.body.msgh_descriptor_count = 1; m.tx.semaphore.name = sem; m.tx.semaphore.disposition = MACH_MSG_TYPE_MOVE_SEND; m.tx.semaphore.type = 0; while((r = machcall(&m.tx.h, sizeof m, 0)) != 0){ if(r == KERN_ABORTED) // interrupted continue; macherror(r, "semaphore_destroy"); } }