ReadWriteLock.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 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 void 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 
23 bool
25 {
26  ++readLevel; // this locks "new" writers out
27  if (!writeLevel || appending) { // nobody is writing, or sharing is OK
28  ++readers;
29  return true;
30  }
31  --readLevel;
32  return false;
33 }
34 
35 bool
37 {
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;
41  return true;
42  }
43  }
44  --writeLevel;
45  return false;
46 }
47 
48 bool
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 
60 void
62 {
63  assert(readers > 0);
64  --readers;
65  --readLevel;
66 }
67 
68 void
70 {
71  assert(writing);
72  appending = false;
73  writing = false;
74  --writeLevel;
75 }
76 
77 void
79 {
80  AssertFlagIsSet(updating);
81  updating.clear(std::memory_order_release);
82  unlockShared();
83 }
84 
85 void
87 {
88  assert(writing);
89  ++readLevel; // must be done before we release exclusive control
90  ++readers;
91  unlockExclusive();
92 }
93 
94 void
96 {
97  assert(writing);
98  appending = true;
99 }
100 
101 void
103 {
104  if (readers) {
105  ++stats.readable;
106  stats.readers += readers;
107  } else if (writing) {
108  ++stats.writeable;
109  ++stats.writers;
110  stats.appenders += appending;
111  } else {
112  ++stats.idle;
113  }
114  ++stats.count;
115 }
116 
117 /* Ipc::ReadWriteLockStats */
118 
120 {
121  memset(this, 0, sizeof(*this));
122 }
123 
124 void
126 {
127  storeAppendPrintf(&e, "Available locks: %9d\n", count);
128 
129  if (!count)
130  return;
131 
132  storeAppendPrintf(&e, "Reading: %9d %6.2f%%\n",
133  readable, (100.0 * readable / count));
134  storeAppendPrintf(&e, "Writing: %9d %6.2f%%\n",
135  writeable, (100.0 * writeable / count));
136  storeAppendPrintf(&e, "Idle: %9d %6.2f%%\n",
137  idle, (100.0 * idle / count));
138 
139  if (readers || writers) {
140  const int locked = readers + writers;
141  storeAppendPrintf(&e, "Readers: %9d %6.2f%%\n",
142  readers, (100.0 * readers / locked));
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);
147  }
148 }
149 
#define assert(EX)
Definition: assert.h:17
int writers
sum of lock.writers
Definition: ReadWriteLock.h:68
void unlockHeaders()
undo successful lockHeaders()
class Ping::pingStats_ stats
int idle
number of unlocked locks
Definition: ReadWriteLock.h:66
approximate stats of a set of ReadWriteLocks
Definition: ReadWriteLock.h:56
bool lockHeaders()
lock for [readable] metadata update or return false
void switchExclusiveToShared()
stop writing, start reading
std::atomic< uint32_t > readLevel
number of users reading (or trying to)
Definition: ReadWriteLock.h:51
int writeable
number of locks locked for writing
Definition: ReadWriteLock.h:65
int readers
sum of lock.readers
Definition: ReadWriteLock.h:67
bool lockExclusive()
lock for modification or return false
void unlockExclusive()
undo successful exclusiveLock()
int count
the total number of locks
Definition: ReadWriteLock.h:63
bool lockShared()
lock for reading or return false
void AssertFlagIsSet(std::atomic_flag &flag)
std::atomic< bool > appending
the writer has promised to only append
Definition: ReadWriteLock.h:47
void unlockShared()
undo successful sharedLock()
void updateStats(ReadWriteLockStats &stats) const
adds approximate current stats to the supplied ones
std::atomic< uint32_t > readers
number of reading users
Definition: ReadWriteLock.h:45
void startAppending()
writer keeps its lock but also allows reading
int appenders
number of appending writers
Definition: ReadWriteLock.h:69
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:904
std::atomic< uint32_t > writeLevel
number of users writing (or trying to write)
Definition: ReadWriteLock.h:52
int readable
number of locks locked for reading
Definition: ReadWriteLock.h:64
void dump(StoreEntry &e) const

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors