1/* 2 * Copyright 2002-2008, Axel D��rfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 6 * Distributed under the terms of the NewOS License. 7 */ 8#ifndef _LIBROOT_LOCK_H 9#define _LIBROOT_LOCK_H 10 11#include <OS.h> 12 13 14// TODO: Copied from the kernel private lock.h/lock.c. We should somehow make 15// that code reusable. 16 17 18namespace BPrivate { 19 20 21typedef struct benaphore { 22 sem_id sem; 23 int32 count; 24} benaphore; 25 26 27static inline status_t 28benaphore_init(benaphore *ben, const char *name) 29{ 30 if (ben == NULL || name == NULL) 31 return B_BAD_VALUE; 32 33 ben->count = 1; 34 ben->sem = create_sem(0, name); 35 if (ben->sem >= B_OK) 36 return B_OK; 37 38 return ben->sem; 39} 40 41 42static inline status_t 43benaphore_lock_etc(benaphore *ben, uint32 flags, bigtime_t timeout) 44{ 45// TODO: This function really shouldn't be used, since timeouts screw the 46// benaphore behavior. 47 if (atomic_add(&ben->count, -1) <= 0) 48 return acquire_sem_etc(ben->sem, 1, flags, timeout); 49 50 return B_OK; 51} 52 53 54static inline status_t 55benaphore_lock(benaphore *ben) 56{ 57 if (atomic_add(&ben->count, -1) <= 0) { 58 status_t error; 59 do { 60 error = acquire_sem(ben->sem); 61 } while (error == B_INTERRUPTED); 62 63 return error; 64 } 65 66 return B_OK; 67} 68 69 70static inline status_t 71benaphore_unlock(benaphore *ben) 72{ 73 if (atomic_add(&ben->count, 1) < 0) 74 return release_sem(ben->sem); 75 76 return B_OK; 77} 78 79 80} // namespace BPrivate 81 82 83using BPrivate::benaphore; 84using BPrivate::benaphore_init; 85using BPrivate::benaphore_lock_etc; 86using BPrivate::benaphore_lock; 87using BPrivate::benaphore_unlock; 88 89 90#endif // _LIBROOT_LOCK_H 91