15142c2acSIngo Weinhold /* 25142c2acSIngo Weinhold * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. 35142c2acSIngo Weinhold * Distributed under the terms of the MIT License. 45142c2acSIngo Weinhold */ 55142c2acSIngo Weinhold 65142c2acSIngo Weinhold #include <semaphore.h> 75142c2acSIngo Weinhold 85142c2acSIngo Weinhold #include <errno.h> 95142c2acSIngo Weinhold #include <fcntl.h> 105142c2acSIngo Weinhold #include <stdarg.h> 115142c2acSIngo Weinhold #include <stdlib.h> 125142c2acSIngo Weinhold 135142c2acSIngo Weinhold #include <OS.h> 145142c2acSIngo Weinhold 155142c2acSIngo Weinhold #include <AutoDeleter.h> 16*6b202f4eSIngo Weinhold #include <posix/realtime_sem_defs.h> 175142c2acSIngo Weinhold #include <syscall_utils.h> 185142c2acSIngo Weinhold #include <syscalls.h> 195142c2acSIngo Weinhold 205142c2acSIngo Weinhold 215142c2acSIngo Weinhold sem_t* 225142c2acSIngo Weinhold sem_open(const char* name, int openFlags,...) 235142c2acSIngo Weinhold { 245142c2acSIngo Weinhold if (name == NULL) { 255142c2acSIngo Weinhold errno = B_BAD_VALUE; 265142c2acSIngo Weinhold return SEM_FAILED; 275142c2acSIngo Weinhold } 285142c2acSIngo Weinhold 295142c2acSIngo Weinhold // get the mode and semaphore count parameters, if O_CREAT is specified 305142c2acSIngo Weinhold mode_t mode = 0; 315142c2acSIngo Weinhold unsigned semCount = 0; 325142c2acSIngo Weinhold 335142c2acSIngo Weinhold if ((openFlags & O_CREAT) != 0) { 345142c2acSIngo Weinhold va_list args; 355142c2acSIngo Weinhold va_start(args, openFlags); 365142c2acSIngo Weinhold mode = va_arg(args, mode_t); 375142c2acSIngo Weinhold semCount = va_arg(args, unsigned); 385142c2acSIngo Weinhold va_end(args); 39e8f1b18eSIngo Weinhold } else { 40e8f1b18eSIngo Weinhold // clear O_EXCL, if O_CREAT is not given 41e8f1b18eSIngo Weinhold openFlags &= ~O_EXCL; 425142c2acSIngo Weinhold } 435142c2acSIngo Weinhold 445142c2acSIngo Weinhold // Allocate a sem_t structure -- we don't know, whether this is the first 455142c2acSIngo Weinhold // call of this process to open the semaphore. If it is, we will keep the 465142c2acSIngo Weinhold // structure, otherwise we will delete it later. 475142c2acSIngo Weinhold sem_t* sem = (sem_t*)malloc(sizeof(sem_t)); 485142c2acSIngo Weinhold if (sem == NULL) { 495142c2acSIngo Weinhold errno = B_NO_MEMORY; 505142c2acSIngo Weinhold return SEM_FAILED; 515142c2acSIngo Weinhold } 525142c2acSIngo Weinhold MemoryDeleter semDeleter(sem); 535142c2acSIngo Weinhold 545142c2acSIngo Weinhold // ask the kernel to open the semaphore 555142c2acSIngo Weinhold sem_t* usedSem; 565142c2acSIngo Weinhold status_t error = _kern_realtime_sem_open(name, openFlags, mode, semCount, 575142c2acSIngo Weinhold sem, &usedSem); 585142c2acSIngo Weinhold if (error != B_OK) { 595142c2acSIngo Weinhold errno = error; 605142c2acSIngo Weinhold return SEM_FAILED; 615142c2acSIngo Weinhold } 625142c2acSIngo Weinhold 635142c2acSIngo Weinhold if (usedSem == sem) 645142c2acSIngo Weinhold semDeleter.Detach(); 655142c2acSIngo Weinhold 665142c2acSIngo Weinhold return usedSem; 675142c2acSIngo Weinhold } 685142c2acSIngo Weinhold 695142c2acSIngo Weinhold 705142c2acSIngo Weinhold int 715142c2acSIngo Weinhold sem_close(sem_t* semaphore) 725142c2acSIngo Weinhold { 735142c2acSIngo Weinhold sem_t* deleteSem = NULL; 745142c2acSIngo Weinhold status_t error = _kern_realtime_sem_close(semaphore->id, &deleteSem); 755142c2acSIngo Weinhold if (error == B_OK) 765142c2acSIngo Weinhold free(deleteSem); 775142c2acSIngo Weinhold 785142c2acSIngo Weinhold RETURN_AND_SET_ERRNO(error); 795142c2acSIngo Weinhold } 805142c2acSIngo Weinhold 815142c2acSIngo Weinhold 825142c2acSIngo Weinhold int 835142c2acSIngo Weinhold sem_unlink(const char* name) 845142c2acSIngo Weinhold { 855142c2acSIngo Weinhold RETURN_AND_SET_ERRNO(_kern_realtime_sem_unlink(name)); 865142c2acSIngo Weinhold } 875142c2acSIngo Weinhold 885142c2acSIngo Weinhold 895142c2acSIngo Weinhold int 905142c2acSIngo Weinhold sem_init(sem_t* semaphore, int shared, unsigned value) 915142c2acSIngo Weinhold { 923dfe682fSIngo Weinhold RETURN_AND_SET_ERRNO(_kern_realtime_sem_open(NULL, shared, 0, value, 933dfe682fSIngo Weinhold semaphore, NULL)); 945142c2acSIngo Weinhold } 955142c2acSIngo Weinhold 965142c2acSIngo Weinhold 975142c2acSIngo Weinhold int 985142c2acSIngo Weinhold sem_destroy(sem_t* semaphore) 995142c2acSIngo Weinhold { 1005142c2acSIngo Weinhold RETURN_AND_SET_ERRNO(_kern_realtime_sem_close(semaphore->id, NULL)); 1015142c2acSIngo Weinhold } 1025142c2acSIngo Weinhold 1035142c2acSIngo Weinhold 1045142c2acSIngo Weinhold int 1055142c2acSIngo Weinhold sem_post(sem_t* semaphore) 1065142c2acSIngo Weinhold { 1075142c2acSIngo Weinhold RETURN_AND_SET_ERRNO(_kern_realtime_sem_post(semaphore->id)); 1085142c2acSIngo Weinhold } 1095142c2acSIngo Weinhold 1105142c2acSIngo Weinhold 1115142c2acSIngo Weinhold int 1125142c2acSIngo Weinhold sem_timedwait(sem_t* semaphore, const struct timespec* timeout) 1135142c2acSIngo Weinhold { 1145142c2acSIngo Weinhold bigtime_t timeoutMicros = ((bigtime_t)timeout->tv_sec) * 1000000 1155142c2acSIngo Weinhold + timeout->tv_nsec / 1000; 1165142c2acSIngo Weinhold 1175142c2acSIngo Weinhold RETURN_AND_SET_ERRNO(_kern_realtime_sem_wait(semaphore->id, timeoutMicros)); 1185142c2acSIngo Weinhold } 1195142c2acSIngo Weinhold 1205142c2acSIngo Weinhold 1215142c2acSIngo Weinhold int 1225142c2acSIngo Weinhold sem_trywait(sem_t* semaphore) 1235142c2acSIngo Weinhold { 1245142c2acSIngo Weinhold RETURN_AND_SET_ERRNO(_kern_realtime_sem_wait(semaphore->id, 0)); 1255142c2acSIngo Weinhold } 1265142c2acSIngo Weinhold 1275142c2acSIngo Weinhold 1285142c2acSIngo Weinhold int 1295142c2acSIngo Weinhold sem_wait(sem_t* semaphore) 1305142c2acSIngo Weinhold { 1315142c2acSIngo Weinhold RETURN_AND_SET_ERRNO(_kern_realtime_sem_wait(semaphore->id, 1325142c2acSIngo Weinhold B_INFINITE_TIMEOUT)); 1335142c2acSIngo Weinhold } 1345142c2acSIngo Weinhold 1355142c2acSIngo Weinhold 1365142c2acSIngo Weinhold int 1375142c2acSIngo Weinhold sem_getvalue(sem_t* semaphore, int* value) 1385142c2acSIngo Weinhold { 1395142c2acSIngo Weinhold RETURN_AND_SET_ERRNO(_kern_realtime_sem_get_value(semaphore->id, value)); 1405142c2acSIngo Weinhold } 141