]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/ReadWriteLock.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / ipc / ReadWriteLock.cc
CommitLineData
44c95fcf 1/*
77b1029d 2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
bbc27441
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
44c95fcf
AR
7 */
8
bbc27441
AJ
9/* DEBUG: section 54 Interprocess Communication */
10
582c2af2 11#include "squid.h"
44c95fcf 12#include "ipc/ReadWriteLock.h"
602d9612 13#include "Store.h"
44c95fcf 14
abf396ec
AR
15void Ipc::AssertFlagIsSet(std::atomic_flag &flag)
16{
17 // If the flag was false, then we set it to true and assert. A true flag
18 // may help keep other processes away from this broken entry.
19 // Otherwise, we just set an already set flag, which is probably a no-op.
20 assert(flag.test_and_set(std::memory_order_relaxed));
21}
22
44c95fcf
AR
23bool
24Ipc::ReadWriteLock::lockShared()
25{
92e29797
AR
26 ++readLevel; // this locks "new" writers out
27 if (!writeLevel || appending) { // nobody is writing, or sharing is OK
28 ++readers;
44c95fcf 29 return true;
92e29797
AR
30 }
31 --readLevel;
44c95fcf
AR
32 return false;
33}
34
35bool
36Ipc::ReadWriteLock::lockExclusive()
37{
92e29797
AR
38 if (!writeLevel++) { // we are the first writer + lock "new" readers out
39 if (!readLevel) { // no old readers and nobody is becoming one
40 writing = true;
44c95fcf 41 return true;
92e29797 42 }
44c95fcf 43 }
92e29797 44 --writeLevel;
44c95fcf
AR
45 return false;
46}
47
abf396ec
AR
48bool
49Ipc::ReadWriteLock::lockHeaders()
50{
51 if (lockShared()) {
52 if (!updating.test_and_set(std::memory_order_acquire))
53 return true; // we got here first
54 // the updating lock was already set by somebody else
55 unlockShared();
56 }
57 return false;
58}
59
44c95fcf
AR
60void
61Ipc::ReadWriteLock::unlockShared()
62{
92e29797
AR
63 assert(readers > 0);
64 --readers;
65 --readLevel;
44c95fcf
AR
66}
67
68void
69Ipc::ReadWriteLock::unlockExclusive()
70{
92e29797
AR
71 assert(writing);
72 appending = false;
73 writing = false;
74 --writeLevel;
44c95fcf
AR
75}
76
abf396ec
AR
77void
78Ipc::ReadWriteLock::unlockHeaders()
79{
80 AssertFlagIsSet(updating);
81 updating.clear(std::memory_order_release);
82 unlockShared();
83}
84
44c95fcf
AR
85void
86Ipc::ReadWriteLock::switchExclusiveToShared()
87{
92e29797
AR
88 assert(writing);
89 ++readLevel; // must be done before we release exclusive control
90 ++readers;
44c95fcf
AR
91 unlockExclusive();
92}
93
ce49546e
AR
94void
95Ipc::ReadWriteLock::startAppending()
96{
92e29797
AR
97 assert(writing);
98 appending = true;
ce49546e
AR
99}
100
44c95fcf
AR
101void
102Ipc::ReadWriteLock::updateStats(ReadWriteLockStats &stats) const
103{
104 if (readers) {
105 ++stats.readable;
106 stats.readers += readers;
92e29797 107 } else if (writing) {
44c95fcf 108 ++stats.writeable;
92e29797 109 ++stats.writers;
ce49546e 110 stats.appenders += appending;
44c95fcf
AR
111 } else {
112 ++stats.idle;
113 }
114 ++stats.count;
115}
116
44c95fcf
AR
117/* Ipc::ReadWriteLockStats */
118
119Ipc::ReadWriteLockStats::ReadWriteLockStats()
120{
121 memset(this, 0, sizeof(*this));
122}
9199139f 123
44c95fcf
AR
124void
125Ipc::ReadWriteLockStats::dump(StoreEntry &e) const
126{
127 storeAppendPrintf(&e, "Available locks: %9d\n", count);
128
129 if (!count)
130 return;
131
132 storeAppendPrintf(&e, "Reading: %9d %6.2f%%\n",
9199139f 133 readable, (100.0 * readable / count));
44c95fcf 134 storeAppendPrintf(&e, "Writing: %9d %6.2f%%\n",
9199139f 135 writeable, (100.0 * writeable / count));
44c95fcf 136 storeAppendPrintf(&e, "Idle: %9d %6.2f%%\n",
9199139f 137 idle, (100.0 * idle / count));
44c95fcf
AR
138
139 if (readers || writers) {
140 const int locked = readers + writers;
141 storeAppendPrintf(&e, "Readers: %9d %6.2f%%\n",
9199139f 142 readers, (100.0 * readers / locked));
ce49546e
AR
143 const double appPerc = writers ? (100.0 * appenders / writers) : 0.0;
144 storeAppendPrintf(&e, "Writers: %9d %6.2f%% including Appenders: %9d %6.2f%%\n",
145 writers, (100.0 * writers / locked),
146 appenders, appPerc);
44c95fcf
AR
147 }
148}
f53969cc 149