1 /* 2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch. 3 * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. 4 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 5 * Distributed under the terms of the MIT License. 6 * 7 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 8 * Distributed under the terms of the NewOS License. 9 */ 10 11 12 #include <locks.h> 13 14 #include <stdlib.h> 15 #include <string.h> 16 17 #include <syscalls.h> 18 #include <user_mutex_defs.h> 19 20 21 // #pragma mark - mutex 22 23 24 void 25 mutex_init(mutex *lock, const char *name) 26 { 27 lock->name = name; 28 lock->lock = 0; 29 lock->flags = 0; 30 } 31 32 33 void 34 mutex_init_etc(mutex *lock, const char *name, uint32 flags) 35 { 36 lock->name = (flags & MUTEX_FLAG_CLONE_NAME) != 0 ? strdup(name) : name; 37 lock->lock = 0; 38 lock->flags = flags; 39 } 40 41 42 void 43 mutex_destroy(mutex *lock) 44 { 45 if ((lock->flags & MUTEX_FLAG_CLONE_NAME) != 0) 46 free(const_cast<char*>(lock->name)); 47 } 48 49 50 status_t 51 mutex_lock(mutex *lock) 52 { 53 // set the locked flag 54 int32 oldValue = atomic_or(&lock->lock, B_USER_MUTEX_LOCKED); 55 56 if ((oldValue & (B_USER_MUTEX_LOCKED | B_USER_MUTEX_WAITING)) == 0 57 || (oldValue & B_USER_MUTEX_DISABLED) != 0) { 58 // No one has the lock or is waiting for it, or the mutex has been 59 // disabled. 60 return B_OK; 61 } 62 63 // we have to call the kernel 64 status_t error; 65 do { 66 error = _kern_mutex_lock(&lock->lock, lock->name, 0, 0); 67 } while (error == B_INTERRUPTED); 68 69 return error; 70 } 71 72 73 void 74 mutex_unlock(mutex *lock) 75 { 76 // clear the locked flag 77 int32 oldValue = atomic_and(&lock->lock, ~(int32)B_USER_MUTEX_LOCKED); 78 if ((oldValue & B_USER_MUTEX_WAITING) != 0 79 && (oldValue & B_USER_MUTEX_DISABLED) == 0) { 80 _kern_mutex_unlock(&lock->lock, 0); 81 } 82 } 83