2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
9 #include <util/AutoLock.h>
12 vnode::Bucket
vnode::sBuckets
[kBucketCount
];
15 vnode::Bucket::Bucket()
17 mutex_init(&lock
, "vnode bucket");
24 for (uint32 i
= 0; i
< kBucketCount
; i
++)
25 new(&sBuckets
[i
]) Bucket
;
33 waiter
.thread
= thread_get_current_thread();
36 Bucket
& bucket
= _Bucket();
37 MutexLocker
bucketLocker(bucket
.lock
);
39 if ((atomic_or(&fFlags
, kFlagsWaitingLocker
)
40 & (kFlagsLocked
| kFlagsWaitingLocker
)) == 0) {
41 // The lock holder dropped it in the meantime and no-one else was faster
42 // than us, so it's ours now. Just mark the node locked and clear the
43 // waiting flag again.
44 atomic_or(&fFlags
, kFlagsLocked
);
45 atomic_and(&fFlags
, ~kFlagsWaitingLocker
);
49 // prepare for waiting
50 bucket
.waiters
.Add(&waiter
);
51 thread_prepare_to_block(waiter
.thread
, 0, THREAD_BLOCK_TYPE_OTHER
,
55 bucketLocker
.Unlock();
61 vnode::_WakeUpLocker()
63 Bucket
& bucket
= _Bucket();
64 MutexLocker
bucketLocker(bucket
.lock
);
66 // mark the node locked again
67 atomic_or(&fFlags
, kFlagsLocked
);
69 // get the first waiter from the list
70 LockWaiter
* waiter
= NULL
;
71 bool onlyWaiter
= true;
72 for (LockWaiterList::Iterator it
= bucket
.waiters
.GetIterator();
73 LockWaiter
* someWaiter
= it
.Next();) {
74 if (someWaiter
->vnode
== this) {
84 ASSERT(waiter
!= NULL
);
86 // if that's the only waiter, clear the flag
88 atomic_and(&fFlags
, ~kFlagsWaitingLocker
);
91 thread_unblock(waiter
->thread
, B_OK
);