1*258b34c5SIngo Weinhold /* 2*258b34c5SIngo Weinhold * Copyright 2009, Michael Lotz, mmlr@mlotz.ch. 3*258b34c5SIngo Weinhold * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. 4*258b34c5SIngo Weinhold * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 5*258b34c5SIngo Weinhold * Distributed under the terms of the MIT License. 6*258b34c5SIngo Weinhold * 7*258b34c5SIngo Weinhold * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 8*258b34c5SIngo Weinhold * Distributed under the terms of the NewOS License. 9*258b34c5SIngo Weinhold */ 10*258b34c5SIngo Weinhold 11*258b34c5SIngo Weinhold 12*258b34c5SIngo Weinhold #include <locks.h> 13*258b34c5SIngo Weinhold 14*258b34c5SIngo Weinhold #include <OS.h> 15*258b34c5SIngo Weinhold 16*258b34c5SIngo Weinhold 17*258b34c5SIngo Weinhold // #pragma mark - recursive lock 18*258b34c5SIngo Weinhold 19*258b34c5SIngo Weinhold 20*258b34c5SIngo Weinhold int32 21*258b34c5SIngo Weinhold recursive_lock_get_recursion(recursive_lock *lock) 22*258b34c5SIngo Weinhold { 23*258b34c5SIngo Weinhold if (lock->holder == find_thread(NULL)) 24*258b34c5SIngo Weinhold return lock->recursion; 25*258b34c5SIngo Weinhold 26*258b34c5SIngo Weinhold return -1; 27*258b34c5SIngo Weinhold } 28*258b34c5SIngo Weinhold 29*258b34c5SIngo Weinhold 30*258b34c5SIngo Weinhold status_t 31*258b34c5SIngo Weinhold recursive_lock_init(recursive_lock *lock, const char *name) 32*258b34c5SIngo Weinhold { 33*258b34c5SIngo Weinhold lock->holder = -1; 34*258b34c5SIngo Weinhold lock->recursion = 0; 35*258b34c5SIngo Weinhold return mutex_init(&lock->lock, name != NULL ? name : "recursive lock"); 36*258b34c5SIngo Weinhold } 37*258b34c5SIngo Weinhold 38*258b34c5SIngo Weinhold 39*258b34c5SIngo Weinhold void 40*258b34c5SIngo Weinhold recursive_lock_destroy(recursive_lock *lock) 41*258b34c5SIngo Weinhold { 42*258b34c5SIngo Weinhold if (lock == NULL) 43*258b34c5SIngo Weinhold return; 44*258b34c5SIngo Weinhold 45*258b34c5SIngo Weinhold mutex_destroy(&lock->lock); 46*258b34c5SIngo Weinhold } 47*258b34c5SIngo Weinhold 48*258b34c5SIngo Weinhold 49*258b34c5SIngo Weinhold status_t 50*258b34c5SIngo Weinhold recursive_lock_lock(recursive_lock *lock) 51*258b34c5SIngo Weinhold { 52*258b34c5SIngo Weinhold thread_id thread = find_thread(NULL); 53*258b34c5SIngo Weinhold 54*258b34c5SIngo Weinhold if (thread != lock->holder) { 55*258b34c5SIngo Weinhold mutex_lock(&lock->lock); 56*258b34c5SIngo Weinhold lock->holder = thread; 57*258b34c5SIngo Weinhold } 58*258b34c5SIngo Weinhold 59*258b34c5SIngo Weinhold lock->recursion++; 60*258b34c5SIngo Weinhold return B_OK; 61*258b34c5SIngo Weinhold } 62*258b34c5SIngo Weinhold 63*258b34c5SIngo Weinhold 64*258b34c5SIngo Weinhold void 65*258b34c5SIngo Weinhold recursive_lock_unlock(recursive_lock *lock) 66*258b34c5SIngo Weinhold { 67*258b34c5SIngo Weinhold if (find_thread(NULL) != lock->holder) { 68*258b34c5SIngo Weinhold debugger("recursive_lock unlocked by non-holder thread!\n"); 69*258b34c5SIngo Weinhold return; 70*258b34c5SIngo Weinhold } 71*258b34c5SIngo Weinhold 72*258b34c5SIngo Weinhold if (--lock->recursion == 0) { 73*258b34c5SIngo Weinhold lock->holder = -1; 74*258b34c5SIngo Weinhold mutex_unlock(&lock->lock); 75*258b34c5SIngo Weinhold } 76*258b34c5SIngo Weinhold } 77*258b34c5SIngo Weinhold 78*258b34c5SIngo Weinhold 79*258b34c5SIngo Weinhold // #pragma mark - lazy recursive lock 80*258b34c5SIngo Weinhold 81*258b34c5SIngo Weinhold 82*258b34c5SIngo Weinhold int32 83*258b34c5SIngo Weinhold lazy_recursive_lock_get_recursion(lazy_recursive_lock *lock) 84*258b34c5SIngo Weinhold { 85*258b34c5SIngo Weinhold if (lock->holder == find_thread(NULL)) 86*258b34c5SIngo Weinhold return lock->recursion; 87*258b34c5SIngo Weinhold 88*258b34c5SIngo Weinhold return -1; 89*258b34c5SIngo Weinhold } 90*258b34c5SIngo Weinhold 91*258b34c5SIngo Weinhold 92*258b34c5SIngo Weinhold status_t 93*258b34c5SIngo Weinhold lazy_recursive_lock_init(lazy_recursive_lock *lock, const char *name) 94*258b34c5SIngo Weinhold { 95*258b34c5SIngo Weinhold lock->holder = -1; 96*258b34c5SIngo Weinhold lock->recursion = 0; 97*258b34c5SIngo Weinhold return lazy_mutex_init(&lock->lock, name != NULL ? name : "recursive lock"); 98*258b34c5SIngo Weinhold } 99*258b34c5SIngo Weinhold 100*258b34c5SIngo Weinhold 101*258b34c5SIngo Weinhold void 102*258b34c5SIngo Weinhold lazy_recursive_lock_destroy(lazy_recursive_lock *lock) 103*258b34c5SIngo Weinhold { 104*258b34c5SIngo Weinhold if (lock == NULL) 105*258b34c5SIngo Weinhold return; 106*258b34c5SIngo Weinhold 107*258b34c5SIngo Weinhold lazy_mutex_destroy(&lock->lock); 108*258b34c5SIngo Weinhold } 109*258b34c5SIngo Weinhold 110*258b34c5SIngo Weinhold 111*258b34c5SIngo Weinhold status_t 112*258b34c5SIngo Weinhold lazy_recursive_lock_lock(lazy_recursive_lock *lock) 113*258b34c5SIngo Weinhold { 114*258b34c5SIngo Weinhold thread_id thread = find_thread(NULL); 115*258b34c5SIngo Weinhold 116*258b34c5SIngo Weinhold if (thread != lock->holder) { 117*258b34c5SIngo Weinhold lazy_mutex_lock(&lock->lock); 118*258b34c5SIngo Weinhold lock->holder = thread; 119*258b34c5SIngo Weinhold } 120*258b34c5SIngo Weinhold 121*258b34c5SIngo Weinhold lock->recursion++; 122*258b34c5SIngo Weinhold return B_OK; 123*258b34c5SIngo Weinhold } 124*258b34c5SIngo Weinhold 125*258b34c5SIngo Weinhold 126*258b34c5SIngo Weinhold void 127*258b34c5SIngo Weinhold lazy_recursive_lock_unlock(lazy_recursive_lock *lock) 128*258b34c5SIngo Weinhold { 129*258b34c5SIngo Weinhold if (find_thread(NULL) != lock->holder) { 130*258b34c5SIngo Weinhold debugger("lazy_recursive_lock unlocked by non-holder thread!\n"); 131*258b34c5SIngo Weinhold return; 132*258b34c5SIngo Weinhold } 133*258b34c5SIngo Weinhold 134*258b34c5SIngo Weinhold if (--lock->recursion == 0) { 135*258b34c5SIngo Weinhold lock->holder = -1; 136*258b34c5SIngo Weinhold lazy_mutex_unlock(&lock->lock); 137*258b34c5SIngo Weinhold } 138*258b34c5SIngo Weinhold } 139