btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / system / kernel / fs / Vnode.cpp
blobcc71aae55108d26accd7bc4d9034548f1709e0bf
1 /*
2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "Vnode.h"
9 #include <util/AutoLock.h>
12 vnode::Bucket vnode::sBuckets[kBucketCount];
15 vnode::Bucket::Bucket()
17 mutex_init(&lock, "vnode bucket");
21 /*static*/ void
22 vnode::StaticInit()
24 for (uint32 i = 0; i < kBucketCount; i++)
25 new(&sBuckets[i]) Bucket;
29 void
30 vnode::_WaitForLock()
32 LockWaiter waiter;
33 waiter.thread = thread_get_current_thread();
34 waiter.vnode = this;
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);
46 return;
49 // prepare for waiting
50 bucket.waiters.Add(&waiter);
51 thread_prepare_to_block(waiter.thread, 0, THREAD_BLOCK_TYPE_OTHER,
52 "vnode lock");
54 // start waiting
55 bucketLocker.Unlock();
56 thread_block();
60 void
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) {
75 if (waiter != NULL) {
76 onlyWaiter = false;
77 break;
79 waiter = someWaiter;
80 it.Remove();
84 ASSERT(waiter != NULL);
86 // if that's the only waiter, clear the flag
87 if (onlyWaiter)
88 atomic_and(&fFlags, ~kFlagsWaitingLocker);
90 // and wake it up
91 thread_unblock(waiter->thread, B_OK);