1258b34c5SIngo Weinhold /*
2258b34c5SIngo Weinhold * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3f7127458SIngo Weinhold * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
4258b34c5SIngo Weinhold * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
5258b34c5SIngo Weinhold * Distributed under the terms of the MIT License.
6258b34c5SIngo Weinhold *
7258b34c5SIngo Weinhold * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
8258b34c5SIngo Weinhold * Distributed under the terms of the NewOS License.
9258b34c5SIngo Weinhold */
10258b34c5SIngo Weinhold
11258b34c5SIngo Weinhold
12258b34c5SIngo Weinhold #include <locks.h>
13258b34c5SIngo Weinhold
14258b34c5SIngo Weinhold #include <OS.h>
15258b34c5SIngo Weinhold
16258b34c5SIngo Weinhold
17258b34c5SIngo Weinhold // #pragma mark - recursive lock
18258b34c5SIngo Weinhold
19258b34c5SIngo Weinhold
20258b34c5SIngo Weinhold int32
__recursive_lock_get_recursion(recursive_lock * lock)21*b916156aSJulian Harnath __recursive_lock_get_recursion(recursive_lock *lock)
22258b34c5SIngo Weinhold {
23258b34c5SIngo Weinhold if (lock->holder == find_thread(NULL))
24258b34c5SIngo Weinhold return lock->recursion;
25258b34c5SIngo Weinhold
26258b34c5SIngo Weinhold return -1;
27258b34c5SIngo Weinhold }
28258b34c5SIngo Weinhold
29258b34c5SIngo Weinhold
30f7127458SIngo Weinhold void
__recursive_lock_init(recursive_lock * lock,const char * name)31*b916156aSJulian Harnath __recursive_lock_init(recursive_lock *lock, const char *name)
32258b34c5SIngo Weinhold {
33f7127458SIngo Weinhold recursive_lock_init_etc(lock, name, 0);
34f7127458SIngo Weinhold }
35f7127458SIngo Weinhold
36f7127458SIngo Weinhold
37f7127458SIngo Weinhold void
__recursive_lock_init_etc(recursive_lock * lock,const char * name,uint32 flags)38*b916156aSJulian Harnath __recursive_lock_init_etc(recursive_lock *lock, const char *name, uint32 flags)
39f7127458SIngo Weinhold {
40258b34c5SIngo Weinhold lock->holder = -1;
41258b34c5SIngo Weinhold lock->recursion = 0;
42f7127458SIngo Weinhold mutex_init_etc(&lock->lock, name, flags);
43258b34c5SIngo Weinhold }
44258b34c5SIngo Weinhold
45258b34c5SIngo Weinhold
46258b34c5SIngo Weinhold void
__recursive_lock_destroy(recursive_lock * lock)47*b916156aSJulian Harnath __recursive_lock_destroy(recursive_lock *lock)
48258b34c5SIngo Weinhold {
49258b34c5SIngo Weinhold if (lock == NULL)
50258b34c5SIngo Weinhold return;
51258b34c5SIngo Weinhold
52258b34c5SIngo Weinhold mutex_destroy(&lock->lock);
53258b34c5SIngo Weinhold }
54258b34c5SIngo Weinhold
55258b34c5SIngo Weinhold
56258b34c5SIngo Weinhold status_t
__recursive_lock_lock(recursive_lock * lock)57*b916156aSJulian Harnath __recursive_lock_lock(recursive_lock *lock)
58258b34c5SIngo Weinhold {
59258b34c5SIngo Weinhold thread_id thread = find_thread(NULL);
60258b34c5SIngo Weinhold
61258b34c5SIngo Weinhold if (thread != lock->holder) {
62258b34c5SIngo Weinhold mutex_lock(&lock->lock);
63258b34c5SIngo Weinhold lock->holder = thread;
64258b34c5SIngo Weinhold }
65258b34c5SIngo Weinhold
66258b34c5SIngo Weinhold lock->recursion++;
67258b34c5SIngo Weinhold return B_OK;
68258b34c5SIngo Weinhold }
69258b34c5SIngo Weinhold
70258b34c5SIngo Weinhold
71258b34c5SIngo Weinhold void
__recursive_lock_unlock(recursive_lock * lock)72*b916156aSJulian Harnath __recursive_lock_unlock(recursive_lock *lock)
73258b34c5SIngo Weinhold {
74258b34c5SIngo Weinhold if (find_thread(NULL) != lock->holder) {
75258b34c5SIngo Weinhold debugger("recursive_lock unlocked by non-holder thread!\n");
76258b34c5SIngo Weinhold return;
77258b34c5SIngo Weinhold }
78258b34c5SIngo Weinhold
79258b34c5SIngo Weinhold if (--lock->recursion == 0) {
80258b34c5SIngo Weinhold lock->holder = -1;
81258b34c5SIngo Weinhold mutex_unlock(&lock->lock);
82258b34c5SIngo Weinhold }
83258b34c5SIngo Weinhold }
84