]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/ReadWriteLock.cc
Merged from trunk 13172.
[thirdparty/squid.git] / src / ipc / ReadWriteLock.cc
1 /*
2 * DEBUG: section 54 Interprocess Communication
3 */
4
5 #include "squid.h"
6 #include "ipc/ReadWriteLock.h"
7 #include "Store.h"
8
9 bool
10 Ipc::ReadWriteLock::lockShared()
11 {
12 ++readLevel; // this locks "new" writers out
13 if (!writeLevel || appending) { // nobody is writing, or sharing is OK
14 ++readers;
15 return true;
16 }
17 --readLevel;
18 return false;
19 }
20
21 bool
22 Ipc::ReadWriteLock::lockExclusive()
23 {
24 if (!writeLevel++) { // we are the first writer + lock "new" readers out
25 if (!readLevel) { // no old readers and nobody is becoming one
26 writing = true;
27 return true;
28 }
29 }
30 --writeLevel;
31 return false;
32 }
33
34 void
35 Ipc::ReadWriteLock::unlockShared()
36 {
37 assert(readers > 0);
38 --readers;
39 --readLevel;
40 }
41
42 void
43 Ipc::ReadWriteLock::unlockExclusive()
44 {
45 assert(writing);
46 appending = false;
47 writing = false;
48 --writeLevel;
49 }
50
51 void
52 Ipc::ReadWriteLock::switchExclusiveToShared()
53 {
54 assert(writing);
55 ++readLevel; // must be done before we release exclusive control
56 ++readers;
57 unlockExclusive();
58 }
59
60 void
61 Ipc::ReadWriteLock::startAppending()
62 {
63 assert(writing);
64 appending = true;
65 }
66
67 void
68 Ipc::ReadWriteLock::updateStats(ReadWriteLockStats &stats) const
69 {
70 if (readers) {
71 ++stats.readable;
72 stats.readers += readers;
73 } else if (writing) {
74 ++stats.writeable;
75 ++stats.writers;
76 stats.appenders += appending;
77 } else {
78 ++stats.idle;
79 }
80 ++stats.count;
81 }
82
83 /* Ipc::ReadWriteLockStats */
84
85 Ipc::ReadWriteLockStats::ReadWriteLockStats()
86 {
87 memset(this, 0, sizeof(*this));
88 }
89
90 void
91 Ipc::ReadWriteLockStats::dump(StoreEntry &e) const
92 {
93 storeAppendPrintf(&e, "Available locks: %9d\n", count);
94
95 if (!count)
96 return;
97
98 storeAppendPrintf(&e, "Reading: %9d %6.2f%%\n",
99 readable, (100.0 * readable / count));
100 storeAppendPrintf(&e, "Writing: %9d %6.2f%%\n",
101 writeable, (100.0 * writeable / count));
102 storeAppendPrintf(&e, "Idle: %9d %6.2f%%\n",
103 idle, (100.0 * idle / count));
104
105 if (readers || writers) {
106 const int locked = readers + writers;
107 storeAppendPrintf(&e, "Readers: %9d %6.2f%%\n",
108 readers, (100.0 * readers / locked));
109 const double appPerc = writers ? (100.0 * appenders / writers) : 0.0;
110 storeAppendPrintf(&e, "Writers: %9d %6.2f%% including Appenders: %9d %6.2f%%\n",
111 writers, (100.0 * writers / locked),
112 appenders, appPerc);
113 }
114 }