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