]>
Commit | Line | Data |
---|---|---|
44c95fcf | 1 | /* |
bbc27441 AJ |
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. | |
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 AR |
14 | |
15 | bool | |
16 | Ipc::ReadWriteLock::lockShared() | |
17 | { | |
92e29797 AR |
18 | ++readLevel; // this locks "new" writers out |
19 | if (!writeLevel || appending) { // nobody is writing, or sharing is OK | |
20 | ++readers; | |
44c95fcf | 21 | return true; |
92e29797 AR |
22 | } |
23 | --readLevel; | |
44c95fcf AR |
24 | return false; |
25 | } | |
26 | ||
27 | bool | |
28 | Ipc::ReadWriteLock::lockExclusive() | |
29 | { | |
92e29797 AR |
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; | |
44c95fcf | 33 | return true; |
92e29797 | 34 | } |
44c95fcf | 35 | } |
92e29797 | 36 | --writeLevel; |
44c95fcf AR |
37 | return false; |
38 | } | |
39 | ||
40 | void | |
41 | Ipc::ReadWriteLock::unlockShared() | |
42 | { | |
92e29797 AR |
43 | assert(readers > 0); |
44 | --readers; | |
45 | --readLevel; | |
44c95fcf AR |
46 | } |
47 | ||
48 | void | |
49 | Ipc::ReadWriteLock::unlockExclusive() | |
50 | { | |
92e29797 AR |
51 | assert(writing); |
52 | appending = false; | |
53 | writing = false; | |
54 | --writeLevel; | |
44c95fcf AR |
55 | } |
56 | ||
57 | void | |
58 | Ipc::ReadWriteLock::switchExclusiveToShared() | |
59 | { | |
92e29797 AR |
60 | assert(writing); |
61 | ++readLevel; // must be done before we release exclusive control | |
62 | ++readers; | |
44c95fcf AR |
63 | unlockExclusive(); |
64 | } | |
65 | ||
ce49546e AR |
66 | void |
67 | Ipc::ReadWriteLock::startAppending() | |
68 | { | |
92e29797 AR |
69 | assert(writing); |
70 | appending = true; | |
ce49546e AR |
71 | } |
72 | ||
44c95fcf AR |
73 | void |
74 | Ipc::ReadWriteLock::updateStats(ReadWriteLockStats &stats) const | |
75 | { | |
76 | if (readers) { | |
77 | ++stats.readable; | |
78 | stats.readers += readers; | |
92e29797 | 79 | } else if (writing) { |
44c95fcf | 80 | ++stats.writeable; |
92e29797 | 81 | ++stats.writers; |
ce49546e | 82 | stats.appenders += appending; |
44c95fcf AR |
83 | } else { |
84 | ++stats.idle; | |
85 | } | |
86 | ++stats.count; | |
87 | } | |
88 | ||
44c95fcf AR |
89 | /* Ipc::ReadWriteLockStats */ |
90 | ||
91 | Ipc::ReadWriteLockStats::ReadWriteLockStats() | |
92 | { | |
93 | memset(this, 0, sizeof(*this)); | |
94 | } | |
9199139f | 95 | |
44c95fcf AR |
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", | |
9199139f | 105 | readable, (100.0 * readable / count)); |
44c95fcf | 106 | storeAppendPrintf(&e, "Writing: %9d %6.2f%%\n", |
9199139f | 107 | writeable, (100.0 * writeable / count)); |
44c95fcf | 108 | storeAppendPrintf(&e, "Idle: %9d %6.2f%%\n", |
9199139f | 109 | idle, (100.0 * idle / count)); |
44c95fcf AR |
110 | |
111 | if (readers || writers) { | |
112 | const int locked = readers + writers; | |
113 | storeAppendPrintf(&e, "Readers: %9d %6.2f%%\n", | |
9199139f | 114 | readers, (100.0 * readers / locked)); |
ce49546e AR |
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); | |
44c95fcf AR |
119 | } |
120 | } |