The Pedigree Project 0.1
UnlikelyLock.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/LockGuard.h"
21#include "pedigree/kernel/Log.h"
23
24UnlikelyLock::UnlikelyLock()
25 : m_Lock(), m_Condition(), m_nReaders(0), m_nWaitingWriters(0), m_bActiveWriter(false) {}
26
27UnlikelyLock::~UnlikelyLock() {
28 LockGuard<Mutex> guard(m_Lock);
29 if (m_nReaders || m_nWaitingWriters || m_bActiveWriter) {
30 FATAL("Destroying an owned or contended UnlikelyLock.");
31 }
32}
33
35 LockGuard<Mutex> guard(m_Lock);
36 while (m_bActiveWriter || m_nWaitingWriters) {
37 m_Condition.waitForCompletion(m_Lock);
38 }
39
40 ++m_nReaders;
41}
42
44 LockGuard<Mutex> guard(m_Lock);
45 if (!m_nReaders) {
46 FATAL("UnlikelyLock::leave without a matching enter.");
47 }
48 if (!--m_nReaders) {
49 // A signal can select a reader, which must remain gated while a
50 // writer is pending. Wake the writer set as well.
51 m_Condition.broadcast();
52 }
53}
54
56 LockGuard<Mutex> guard(m_Lock);
57 ++m_nWaitingWriters;
58 while (m_bActiveWriter || m_nReaders) {
59 m_Condition.waitForCompletion(m_Lock);
60 }
61
62 --m_nWaitingWriters;
63 m_bActiveWriter = true;
64}
65
67 LockGuard<Mutex> guard(m_Lock);
68 if (!m_bActiveWriter) {
69 FATAL("UnlikelyLock::release without writer ownership.");
70 }
71 m_bActiveWriter = false;
72 m_Condition.broadcast();
73}
void waitForCompletion(Mutex &mutex)