SharedMutex.h 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724
  1. /*
  2. * Copyright 2015-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. // @author Nathan Bronson (ngbronson@fb.com)
  17. #pragma once
  18. #include <stdint.h>
  19. #include <atomic>
  20. #include <thread>
  21. #include <type_traits>
  22. #include <folly/CPortability.h>
  23. #include <folly/Likely.h>
  24. #include <folly/concurrency/CacheLocality.h>
  25. #include <folly/detail/Futex.h>
  26. #include <folly/portability/Asm.h>
  27. #include <folly/portability/SysResource.h>
  28. #include <folly/synchronization/SanitizeThread.h>
  29. // SharedMutex is a reader-writer lock. It is small, very fast, scalable
  30. // on multi-core, and suitable for use when readers or writers may block.
  31. // Unlike most other reader-writer locks, its throughput with concurrent
  32. // readers scales linearly; it is able to acquire and release the lock
  33. // in shared mode without cache line ping-ponging. It is suitable for
  34. // a wide range of lock hold times because it starts with spinning,
  35. // proceeds to using sched_yield with a preemption heuristic, and then
  36. // waits using futex and precise wakeups.
  37. //
  38. // SharedMutex provides all of the methods of folly::RWSpinLock,
  39. // boost::shared_mutex, boost::upgrade_mutex, and C++14's
  40. // std::shared_timed_mutex. All operations that can block are available
  41. // in try, try-for, and try-until (system_clock or steady_clock) versions.
  42. //
  43. // SharedMutexReadPriority gives priority to readers,
  44. // SharedMutexWritePriority gives priority to writers. SharedMutex is an
  45. // alias for SharedMutexWritePriority, because writer starvation is more
  46. // likely than reader starvation for the read-heavy workloads targetted
  47. // by SharedMutex.
  48. //
  49. // In my tests SharedMutex is as good or better than the other
  50. // reader-writer locks in use at Facebook for almost all use cases,
  51. // sometimes by a wide margin. (If it is rare that there are actually
  52. // concurrent readers then RWSpinLock can be a few nanoseconds faster.)
  53. // I compared it to folly::RWSpinLock, folly::RWTicketSpinLock64,
  54. // boost::shared_mutex, pthread_rwlock_t, and a RWLock that internally uses
  55. // spinlocks to guard state and pthread_mutex_t+pthread_cond_t to block.
  56. // (Thrift's ReadWriteMutex is based underneath on pthread_rwlock_t.)
  57. // It is generally as good or better than the rest when evaluating size,
  58. // speed, scalability, or latency outliers. In the corner cases where
  59. // it is not the fastest (such as single-threaded use or heavy write
  60. // contention) it is never very much worse than the best. See the bottom
  61. // of folly/test/SharedMutexTest.cpp for lots of microbenchmark results.
  62. //
  63. // Comparison to folly::RWSpinLock:
  64. //
  65. // * SharedMutex is faster than RWSpinLock when there are actually
  66. // concurrent read accesses (sometimes much faster), and ~5 nanoseconds
  67. // slower when there is not actually any contention. SharedMutex is
  68. // faster in every (benchmarked) scenario where the shared mode of
  69. // the lock is actually useful.
  70. //
  71. // * Concurrent shared access to SharedMutex scales linearly, while total
  72. // RWSpinLock throughput drops as more threads try to access the lock
  73. // in shared mode. Under very heavy read contention SharedMutex can
  74. // be two orders of magnitude faster than RWSpinLock (or any reader
  75. // writer lock that doesn't use striping or deferral).
  76. //
  77. // * SharedMutex can safely protect blocking calls, because after an
  78. // initial period of spinning it waits using futex().
  79. //
  80. // * RWSpinLock prioritizes readers, SharedMutex has both reader- and
  81. // writer-priority variants, but defaults to write priority.
  82. //
  83. // * RWSpinLock's upgradeable mode blocks new readers, while SharedMutex's
  84. // doesn't. Both semantics are reasonable. The boost documentation
  85. // doesn't explicitly talk about this behavior (except by omitting
  86. // any statement that those lock modes conflict), but the boost
  87. // implementations do allow new readers while the upgradeable mode
  88. // is held. See https://github.com/boostorg/thread/blob/master/
  89. // include/boost/thread/pthread/shared_mutex.hpp
  90. //
  91. // * RWSpinLock::UpgradedHolder maps to SharedMutex::UpgradeHolder
  92. // (UpgradeableHolder would be even more pedantically correct).
  93. // SharedMutex's holders have fewer methods (no reset) and are less
  94. // tolerant (promotion and downgrade crash if the donor doesn't own
  95. // the lock, and you must use the default constructor rather than
  96. // passing a nullptr to the pointer constructor).
  97. //
  98. // Both SharedMutex and RWSpinLock provide "exclusive", "upgrade",
  99. // and "shared" modes. At all times num_threads_holding_exclusive +
  100. // num_threads_holding_upgrade <= 1, and num_threads_holding_exclusive ==
  101. // 0 || num_threads_holding_shared == 0. RWSpinLock has the additional
  102. // constraint that num_threads_holding_shared cannot increase while
  103. // num_threads_holding_upgrade is non-zero.
  104. //
  105. // Comparison to the internal RWLock:
  106. //
  107. // * SharedMutex doesn't allow a maximum reader count to be configured,
  108. // so it can't be used as a semaphore in the same way as RWLock.
  109. //
  110. // * SharedMutex is 4 bytes, RWLock is 256.
  111. //
  112. // * SharedMutex is as fast or faster than RWLock in all of my
  113. // microbenchmarks, and has positive rather than negative scalability.
  114. //
  115. // * RWLock and SharedMutex are both writer priority locks.
  116. //
  117. // * SharedMutex avoids latency outliers as well as RWLock.
  118. //
  119. // * SharedMutex uses different names (t != 0 below):
  120. //
  121. // RWLock::lock(0) => SharedMutex::lock()
  122. //
  123. // RWLock::lock(t) => SharedMutex::try_lock_for(milliseconds(t))
  124. //
  125. // RWLock::tryLock() => SharedMutex::try_lock()
  126. //
  127. // RWLock::unlock() => SharedMutex::unlock()
  128. //
  129. // RWLock::enter(0) => SharedMutex::lock_shared()
  130. //
  131. // RWLock::enter(t) =>
  132. // SharedMutex::try_lock_shared_for(milliseconds(t))
  133. //
  134. // RWLock::tryEnter() => SharedMutex::try_lock_shared()
  135. //
  136. // RWLock::leave() => SharedMutex::unlock_shared()
  137. //
  138. // * RWLock allows the reader count to be adjusted by a value other
  139. // than 1 during enter() or leave(). SharedMutex doesn't currently
  140. // implement this feature.
  141. //
  142. // * RWLock's methods are marked const, SharedMutex's aren't.
  143. //
  144. // Reader-writer locks have the potential to allow concurrent access
  145. // to shared read-mostly data, but in practice they often provide no
  146. // improvement over a mutex. The problem is the cache coherence protocol
  147. // of modern CPUs. Coherence is provided by making sure that when a cache
  148. // line is written it is present in only one core's cache. Since a memory
  149. // write is required to acquire a reader-writer lock in shared mode, the
  150. // cache line holding the lock is invalidated in all of the other caches.
  151. // This leads to cache misses when another thread wants to acquire or
  152. // release the lock concurrently. When the RWLock is colocated with the
  153. // data it protects (common), cache misses can also continue occur when
  154. // a thread that already holds the lock tries to read the protected data.
  155. //
  156. // Ideally, a reader-writer lock would allow multiple cores to acquire
  157. // and release the lock in shared mode without incurring any cache misses.
  158. // This requires that each core records its shared access in a cache line
  159. // that isn't read or written by other read-locking cores. (Writers will
  160. // have to check all of the cache lines.) Typical server hardware when
  161. // this comment was written has 16 L1 caches and cache lines of 64 bytes,
  162. // so a lock striped over all L1 caches would occupy a prohibitive 1024
  163. // bytes. Nothing says that we need a separate set of per-core memory
  164. // locations for each lock, however. Each SharedMutex instance is only
  165. // 4 bytes, but all locks together share a 2K area in which they make a
  166. // core-local record of lock acquisitions.
  167. //
  168. // SharedMutex's strategy of using a shared set of core-local stripes has
  169. // a potential downside, because it means that acquisition of any lock in
  170. // write mode can conflict with acquisition of any lock in shared mode.
  171. // If a lock instance doesn't actually experience concurrency then this
  172. // downside will outweight the upside of improved scalability for readers.
  173. // To avoid this problem we dynamically detect concurrent accesses to
  174. // SharedMutex, and don't start using the deferred mode unless we actually
  175. // observe concurrency. See kNumSharedToStartDeferring.
  176. //
  177. // It is explicitly allowed to call unlock_shared() from a different
  178. // thread than lock_shared(), so long as they are properly paired.
  179. // unlock_shared() needs to find the location at which lock_shared()
  180. // recorded the lock, which might be in the lock itself or in any of
  181. // the shared slots. If you can conveniently pass state from lock
  182. // acquisition to release then the fastest mechanism is to std::move
  183. // the SharedMutex::ReadHolder instance or an SharedMutex::Token (using
  184. // lock_shared(Token&) and unlock_shared(Token&)). The guard or token
  185. // will tell unlock_shared where in deferredReaders[] to look for the
  186. // deferred lock. The Token-less version of unlock_shared() works in all
  187. // cases, but is optimized for the common (no inter-thread handoff) case.
  188. //
  189. // In both read- and write-priority mode, a waiting lock() (exclusive mode)
  190. // only blocks readers after it has waited for an active upgrade lock to be
  191. // released; until the upgrade lock is released (or upgraded or downgraded)
  192. // readers will still be able to enter. Preferences about lock acquisition
  193. // are not guaranteed to be enforced perfectly (even if they were, there
  194. // is theoretically the chance that a thread could be arbitrarily suspended
  195. // between calling lock() and SharedMutex code actually getting executed).
  196. //
  197. // try_*_for methods always try at least once, even if the duration
  198. // is zero or negative. The duration type must be compatible with
  199. // std::chrono::steady_clock. try_*_until methods also always try at
  200. // least once. std::chrono::system_clock and std::chrono::steady_clock
  201. // are supported.
  202. //
  203. // If you have observed by profiling that your SharedMutex-s are getting
  204. // cache misses on deferredReaders[] due to another SharedMutex user, then
  205. // you can use the tag type to create your own instantiation of the type.
  206. // The contention threshold (see kNumSharedToStartDeferring) should make
  207. // this unnecessary in all but the most extreme cases. Make sure to check
  208. // that the increased icache and dcache footprint of the tagged result is
  209. // worth it.
  210. // SharedMutex's use of thread local storage is an optimization, so
  211. // for the case where thread local storage is not supported, define it
  212. // away.
  213. // Note about TSAN (ThreadSanitizer): the SharedMutexWritePriority version
  214. // (the default) of this mutex is annotated appropriately so that TSAN can
  215. // perform lock inversion analysis. However, the SharedMutexReadPriority version
  216. // is not annotated. This is because TSAN's lock order heuristic
  217. // assumes that two calls to lock_shared must be ordered, which leads
  218. // to too many false positives for the reader-priority case.
  219. //
  220. // Suppose thread A holds a SharedMutexWritePriority lock in shared mode and an
  221. // independent thread B is waiting for exclusive access. Then a thread C's
  222. // lock_shared can't proceed until A has released the lock. Discounting
  223. // situations that never use exclusive mode (so no lock is necessary at all)
  224. // this means that without higher-level reasoning it is not safe to ignore
  225. // reader <-> reader interactions.
  226. //
  227. // This reasoning does not apply to SharedMutexReadPriority, because there are
  228. // no actions by a thread B that can make C need to wait for A. Since the
  229. // overwhelming majority of SharedMutex instances use write priority, we
  230. // restrict the TSAN annotations to only SharedMutexWritePriority.
  231. #ifndef FOLLY_SHAREDMUTEX_TLS
  232. #if !FOLLY_MOBILE
  233. #define FOLLY_SHAREDMUTEX_TLS FOLLY_TLS
  234. #else
  235. #define FOLLY_SHAREDMUTEX_TLS
  236. #endif
  237. #endif
  238. namespace folly {
  239. struct SharedMutexToken {
  240. enum class Type : uint16_t {
  241. INVALID = 0,
  242. INLINE_SHARED,
  243. DEFERRED_SHARED,
  244. };
  245. Type type_;
  246. uint16_t slot_;
  247. };
  248. namespace detail {
  249. // Returns a guard that gives permission for the current thread to
  250. // annotate, and adjust the annotation bits in, the SharedMutex at ptr.
  251. std::unique_lock<std::mutex> sharedMutexAnnotationGuard(void* ptr);
  252. } // namespace detail
  253. template <
  254. bool ReaderPriority,
  255. typename Tag_ = void,
  256. template <typename> class Atom = std::atomic,
  257. bool BlockImmediately = false,
  258. bool AnnotateForThreadSanitizer = kIsSanitizeThread && !ReaderPriority>
  259. class SharedMutexImpl {
  260. public:
  261. static constexpr bool kReaderPriority = ReaderPriority;
  262. typedef Tag_ Tag;
  263. typedef SharedMutexToken Token;
  264. class ReadHolder;
  265. class UpgradeHolder;
  266. class WriteHolder;
  267. constexpr SharedMutexImpl() noexcept : state_(0) {}
  268. SharedMutexImpl(const SharedMutexImpl&) = delete;
  269. SharedMutexImpl(SharedMutexImpl&&) = delete;
  270. SharedMutexImpl& operator=(const SharedMutexImpl&) = delete;
  271. SharedMutexImpl& operator=(SharedMutexImpl&&) = delete;
  272. // It is an error to destroy an SharedMutex that still has
  273. // any outstanding locks. This is checked if NDEBUG isn't defined.
  274. // SharedMutex's exclusive mode can be safely used to guard the lock's
  275. // own destruction. If, for example, you acquire the lock in exclusive
  276. // mode and then observe that the object containing the lock is no longer
  277. // needed, you can unlock() and then immediately destroy the lock.
  278. // See https://sourceware.org/bugzilla/show_bug.cgi?id=13690 for a
  279. // description about why this property needs to be explicitly mentioned.
  280. ~SharedMutexImpl() {
  281. auto state = state_.load(std::memory_order_relaxed);
  282. if (UNLIKELY((state & kHasS) != 0)) {
  283. cleanupTokenlessSharedDeferred(state);
  284. }
  285. #ifndef NDEBUG
  286. // These asserts check that everybody has released the lock before it
  287. // is destroyed. If you arrive here while debugging that is likely
  288. // the problem. (You could also have general heap corruption.)
  289. // if a futexWait fails to go to sleep because the value has been
  290. // changed, we don't necessarily clean up the wait bits, so it is
  291. // possible they will be set here in a correct system
  292. assert((state & ~(kWaitingAny | kMayDefer | kAnnotationCreated)) == 0);
  293. if ((state & kMayDefer) != 0) {
  294. for (uint32_t slot = 0; slot < kMaxDeferredReaders; ++slot) {
  295. auto slotValue = deferredReader(slot)->load(std::memory_order_relaxed);
  296. assert(!slotValueIsThis(slotValue));
  297. }
  298. }
  299. #endif
  300. annotateDestroy();
  301. }
  302. void lock() {
  303. WaitForever ctx;
  304. (void)lockExclusiveImpl(kHasSolo, ctx);
  305. annotateAcquired(annotate_rwlock_level::wrlock);
  306. }
  307. bool try_lock() {
  308. WaitNever ctx;
  309. auto result = lockExclusiveImpl(kHasSolo, ctx);
  310. annotateTryAcquired(result, annotate_rwlock_level::wrlock);
  311. return result;
  312. }
  313. template <class Rep, class Period>
  314. bool try_lock_for(const std::chrono::duration<Rep, Period>& duration) {
  315. WaitForDuration<Rep, Period> ctx(duration);
  316. auto result = lockExclusiveImpl(kHasSolo, ctx);
  317. annotateTryAcquired(result, annotate_rwlock_level::wrlock);
  318. return result;
  319. }
  320. template <class Clock, class Duration>
  321. bool try_lock_until(
  322. const std::chrono::time_point<Clock, Duration>& absDeadline) {
  323. WaitUntilDeadline<Clock, Duration> ctx{absDeadline};
  324. auto result = lockExclusiveImpl(kHasSolo, ctx);
  325. annotateTryAcquired(result, annotate_rwlock_level::wrlock);
  326. return result;
  327. }
  328. void unlock() {
  329. annotateReleased(annotate_rwlock_level::wrlock);
  330. // It is possible that we have a left-over kWaitingNotS if the last
  331. // unlock_shared() that let our matching lock() complete finished
  332. // releasing before lock()'s futexWait went to sleep. Clean it up now
  333. auto state = (state_ &= ~(kWaitingNotS | kPrevDefer | kHasE));
  334. assert((state & ~(kWaitingAny | kAnnotationCreated)) == 0);
  335. wakeRegisteredWaiters(state, kWaitingE | kWaitingU | kWaitingS);
  336. }
  337. // Managing the token yourself makes unlock_shared a bit faster
  338. void lock_shared() {
  339. WaitForever ctx;
  340. (void)lockSharedImpl(nullptr, ctx);
  341. annotateAcquired(annotate_rwlock_level::rdlock);
  342. }
  343. void lock_shared(Token& token) {
  344. WaitForever ctx;
  345. (void)lockSharedImpl(&token, ctx);
  346. annotateAcquired(annotate_rwlock_level::rdlock);
  347. }
  348. bool try_lock_shared() {
  349. WaitNever ctx;
  350. auto result = lockSharedImpl(nullptr, ctx);
  351. annotateTryAcquired(result, annotate_rwlock_level::rdlock);
  352. return result;
  353. }
  354. bool try_lock_shared(Token& token) {
  355. WaitNever ctx;
  356. auto result = lockSharedImpl(&token, ctx);
  357. annotateTryAcquired(result, annotate_rwlock_level::rdlock);
  358. return result;
  359. }
  360. template <class Rep, class Period>
  361. bool try_lock_shared_for(const std::chrono::duration<Rep, Period>& duration) {
  362. WaitForDuration<Rep, Period> ctx(duration);
  363. auto result = lockSharedImpl(nullptr, ctx);
  364. annotateTryAcquired(result, annotate_rwlock_level::rdlock);
  365. return result;
  366. }
  367. template <class Rep, class Period>
  368. bool try_lock_shared_for(
  369. const std::chrono::duration<Rep, Period>& duration,
  370. Token& token) {
  371. WaitForDuration<Rep, Period> ctx(duration);
  372. auto result = lockSharedImpl(&token, ctx);
  373. annotateTryAcquired(result, annotate_rwlock_level::rdlock);
  374. return result;
  375. }
  376. template <class Clock, class Duration>
  377. bool try_lock_shared_until(
  378. const std::chrono::time_point<Clock, Duration>& absDeadline) {
  379. WaitUntilDeadline<Clock, Duration> ctx{absDeadline};
  380. auto result = lockSharedImpl(nullptr, ctx);
  381. annotateTryAcquired(result, annotate_rwlock_level::rdlock);
  382. return result;
  383. }
  384. template <class Clock, class Duration>
  385. bool try_lock_shared_until(
  386. const std::chrono::time_point<Clock, Duration>& absDeadline,
  387. Token& token) {
  388. WaitUntilDeadline<Clock, Duration> ctx{absDeadline};
  389. auto result = lockSharedImpl(&token, ctx);
  390. annotateTryAcquired(result, annotate_rwlock_level::rdlock);
  391. return result;
  392. }
  393. void unlock_shared() {
  394. annotateReleased(annotate_rwlock_level::rdlock);
  395. auto state = state_.load(std::memory_order_acquire);
  396. // kPrevDefer can only be set if HasE or BegunE is set
  397. assert((state & (kPrevDefer | kHasE | kBegunE)) != kPrevDefer);
  398. // lock() strips kMayDefer immediately, but then copies it to
  399. // kPrevDefer so we can tell if the pre-lock() lock_shared() might
  400. // have deferred
  401. if ((state & (kMayDefer | kPrevDefer)) == 0 ||
  402. !tryUnlockTokenlessSharedDeferred()) {
  403. // Matching lock_shared() couldn't have deferred, or the deferred
  404. // lock has already been inlined by applyDeferredReaders()
  405. unlockSharedInline();
  406. }
  407. }
  408. void unlock_shared(Token& token) {
  409. annotateReleased(annotate_rwlock_level::rdlock);
  410. assert(
  411. token.type_ == Token::Type::INLINE_SHARED ||
  412. token.type_ == Token::Type::DEFERRED_SHARED);
  413. if (token.type_ != Token::Type::DEFERRED_SHARED ||
  414. !tryUnlockSharedDeferred(token.slot_)) {
  415. unlockSharedInline();
  416. }
  417. #ifndef NDEBUG
  418. token.type_ = Token::Type::INVALID;
  419. #endif
  420. }
  421. void unlock_and_lock_shared() {
  422. annotateReleased(annotate_rwlock_level::wrlock);
  423. annotateAcquired(annotate_rwlock_level::rdlock);
  424. // We can't use state_ -=, because we need to clear 2 bits (1 of which
  425. // has an uncertain initial state) and set 1 other. We might as well
  426. // clear the relevant wake bits at the same time. Note that since S
  427. // doesn't block the beginning of a transition to E (writer priority
  428. // can cut off new S, reader priority grabs BegunE and blocks deferred
  429. // S) we need to wake E as well.
  430. auto state = state_.load(std::memory_order_acquire);
  431. do {
  432. assert(
  433. (state & ~(kWaitingAny | kPrevDefer | kAnnotationCreated)) == kHasE);
  434. } while (!state_.compare_exchange_strong(
  435. state, (state & ~(kWaitingAny | kPrevDefer | kHasE)) + kIncrHasS));
  436. if ((state & (kWaitingE | kWaitingU | kWaitingS)) != 0) {
  437. futexWakeAll(kWaitingE | kWaitingU | kWaitingS);
  438. }
  439. }
  440. void unlock_and_lock_shared(Token& token) {
  441. unlock_and_lock_shared();
  442. token.type_ = Token::Type::INLINE_SHARED;
  443. }
  444. void lock_upgrade() {
  445. WaitForever ctx;
  446. (void)lockUpgradeImpl(ctx);
  447. // For TSAN: treat upgrade locks as equivalent to read locks
  448. annotateAcquired(annotate_rwlock_level::rdlock);
  449. }
  450. bool try_lock_upgrade() {
  451. WaitNever ctx;
  452. auto result = lockUpgradeImpl(ctx);
  453. annotateTryAcquired(result, annotate_rwlock_level::rdlock);
  454. return result;
  455. }
  456. template <class Rep, class Period>
  457. bool try_lock_upgrade_for(
  458. const std::chrono::duration<Rep, Period>& duration) {
  459. WaitForDuration<Rep, Period> ctx(duration);
  460. auto result = lockUpgradeImpl(ctx);
  461. annotateTryAcquired(result, annotate_rwlock_level::rdlock);
  462. return result;
  463. }
  464. template <class Clock, class Duration>
  465. bool try_lock_upgrade_until(
  466. const std::chrono::time_point<Clock, Duration>& absDeadline) {
  467. WaitUntilDeadline<Clock, Duration> ctx{absDeadline};
  468. auto result = lockUpgradeImpl(ctx);
  469. annotateTryAcquired(result, annotate_rwlock_level::rdlock);
  470. return result;
  471. }
  472. void unlock_upgrade() {
  473. annotateReleased(annotate_rwlock_level::rdlock);
  474. auto state = (state_ -= kHasU);
  475. assert((state & (kWaitingNotS | kHasSolo)) == 0);
  476. wakeRegisteredWaiters(state, kWaitingE | kWaitingU);
  477. }
  478. void unlock_upgrade_and_lock() {
  479. // no waiting necessary, so waitMask is empty
  480. WaitForever ctx;
  481. (void)lockExclusiveImpl(0, ctx);
  482. annotateReleased(annotate_rwlock_level::rdlock);
  483. annotateAcquired(annotate_rwlock_level::wrlock);
  484. }
  485. void unlock_upgrade_and_lock_shared() {
  486. // No need to annotate for TSAN here because we model upgrade and shared
  487. // locks as the same.
  488. auto state = (state_ -= kHasU - kIncrHasS);
  489. assert((state & (kWaitingNotS | kHasSolo)) == 0);
  490. wakeRegisteredWaiters(state, kWaitingE | kWaitingU);
  491. }
  492. void unlock_upgrade_and_lock_shared(Token& token) {
  493. unlock_upgrade_and_lock_shared();
  494. token.type_ = Token::Type::INLINE_SHARED;
  495. }
  496. void unlock_and_lock_upgrade() {
  497. annotateReleased(annotate_rwlock_level::wrlock);
  498. annotateAcquired(annotate_rwlock_level::rdlock);
  499. // We can't use state_ -=, because we need to clear 2 bits (1 of
  500. // which has an uncertain initial state) and set 1 other. We might
  501. // as well clear the relevant wake bits at the same time.
  502. auto state = state_.load(std::memory_order_acquire);
  503. while (true) {
  504. assert(
  505. (state & ~(kWaitingAny | kPrevDefer | kAnnotationCreated)) == kHasE);
  506. auto after =
  507. (state & ~(kWaitingNotS | kWaitingS | kPrevDefer | kHasE)) + kHasU;
  508. if (state_.compare_exchange_strong(state, after)) {
  509. if ((state & kWaitingS) != 0) {
  510. futexWakeAll(kWaitingS);
  511. }
  512. return;
  513. }
  514. }
  515. }
  516. private:
  517. typedef typename folly::detail::Futex<Atom> Futex;
  518. // Internally we use four kinds of wait contexts. These are structs
  519. // that provide a doWait method that returns true if a futex wake
  520. // was issued that intersects with the waitMask, false if there was a
  521. // timeout and no more waiting should be performed. Spinning occurs
  522. // before the wait context is invoked.
  523. struct WaitForever {
  524. bool canBlock() {
  525. return true;
  526. }
  527. bool canTimeOut() {
  528. return false;
  529. }
  530. bool shouldTimeOut() {
  531. return false;
  532. }
  533. bool doWait(Futex& futex, uint32_t expected, uint32_t waitMask) {
  534. detail::futexWait(&futex, expected, waitMask);
  535. return true;
  536. }
  537. };
  538. struct WaitNever {
  539. bool canBlock() {
  540. return false;
  541. }
  542. bool canTimeOut() {
  543. return true;
  544. }
  545. bool shouldTimeOut() {
  546. return true;
  547. }
  548. bool doWait(
  549. Futex& /* futex */,
  550. uint32_t /* expected */,
  551. uint32_t /* waitMask */) {
  552. return false;
  553. }
  554. };
  555. template <class Rep, class Period>
  556. struct WaitForDuration {
  557. std::chrono::duration<Rep, Period> duration_;
  558. bool deadlineComputed_;
  559. std::chrono::steady_clock::time_point deadline_;
  560. explicit WaitForDuration(const std::chrono::duration<Rep, Period>& duration)
  561. : duration_(duration), deadlineComputed_(false) {}
  562. std::chrono::steady_clock::time_point deadline() {
  563. if (!deadlineComputed_) {
  564. deadline_ = std::chrono::steady_clock::now() + duration_;
  565. deadlineComputed_ = true;
  566. }
  567. return deadline_;
  568. }
  569. bool canBlock() {
  570. return duration_.count() > 0;
  571. }
  572. bool canTimeOut() {
  573. return true;
  574. }
  575. bool shouldTimeOut() {
  576. return std::chrono::steady_clock::now() > deadline();
  577. }
  578. bool doWait(Futex& futex, uint32_t expected, uint32_t waitMask) {
  579. auto result =
  580. detail::futexWaitUntil(&futex, expected, deadline(), waitMask);
  581. return result != folly::detail::FutexResult::TIMEDOUT;
  582. }
  583. };
  584. template <class Clock, class Duration>
  585. struct WaitUntilDeadline {
  586. std::chrono::time_point<Clock, Duration> absDeadline_;
  587. bool canBlock() {
  588. return true;
  589. }
  590. bool canTimeOut() {
  591. return true;
  592. }
  593. bool shouldTimeOut() {
  594. return Clock::now() > absDeadline_;
  595. }
  596. bool doWait(Futex& futex, uint32_t expected, uint32_t waitMask) {
  597. auto result =
  598. detail::futexWaitUntil(&futex, expected, absDeadline_, waitMask);
  599. return result != folly::detail::FutexResult::TIMEDOUT;
  600. }
  601. };
  602. void annotateLazyCreate() {
  603. if (AnnotateForThreadSanitizer &&
  604. (state_.load() & kAnnotationCreated) == 0) {
  605. auto guard = detail::sharedMutexAnnotationGuard(this);
  606. // check again
  607. if ((state_.load() & kAnnotationCreated) == 0) {
  608. state_.fetch_or(kAnnotationCreated);
  609. annotate_benign_race_sized(
  610. &state_, sizeof(state_), "init TSAN", __FILE__, __LINE__);
  611. annotate_rwlock_create(this, __FILE__, __LINE__);
  612. }
  613. }
  614. }
  615. void annotateDestroy() {
  616. if (AnnotateForThreadSanitizer) {
  617. annotateLazyCreate();
  618. annotate_rwlock_destroy(this, __FILE__, __LINE__);
  619. }
  620. }
  621. void annotateAcquired(annotate_rwlock_level w) {
  622. if (AnnotateForThreadSanitizer) {
  623. annotateLazyCreate();
  624. annotate_rwlock_acquired(this, w, __FILE__, __LINE__);
  625. }
  626. }
  627. void annotateTryAcquired(bool result, annotate_rwlock_level w) {
  628. if (AnnotateForThreadSanitizer) {
  629. annotateLazyCreate();
  630. annotate_rwlock_try_acquired(this, w, result, __FILE__, __LINE__);
  631. }
  632. }
  633. void annotateReleased(annotate_rwlock_level w) {
  634. if (AnnotateForThreadSanitizer) {
  635. assert((state_.load() & kAnnotationCreated) != 0);
  636. annotate_rwlock_released(this, w, __FILE__, __LINE__);
  637. }
  638. }
  639. // 32 bits of state
  640. Futex state_{};
  641. // S count needs to be on the end, because we explicitly allow it to
  642. // underflow. This can occur while we are in the middle of applying
  643. // deferred locks (we remove them from deferredReaders[] before
  644. // inlining them), or during token-less unlock_shared() if a racing
  645. // lock_shared();unlock_shared() moves the deferredReaders slot while
  646. // the first unlock_shared() is scanning. The former case is cleaned
  647. // up before we finish applying the locks. The latter case can persist
  648. // until destruction, when it is cleaned up.
  649. static constexpr uint32_t kIncrHasS = 1 << 11;
  650. static constexpr uint32_t kHasS = ~(kIncrHasS - 1);
  651. // Set if annotation has been completed for this instance. That annotation
  652. // (and setting this bit afterward) must be guarded by one of the mutexes in
  653. // annotationCreationGuards.
  654. static constexpr uint32_t kAnnotationCreated = 1 << 10;
  655. // If false, then there are definitely no deferred read locks for this
  656. // instance. Cleared after initialization and when exclusively locked.
  657. static constexpr uint32_t kMayDefer = 1 << 9;
  658. // lock() cleared kMayDefer as soon as it starts draining readers (so
  659. // that it doesn't have to do a second CAS once drain completes), but
  660. // unlock_shared() still needs to know whether to scan deferredReaders[]
  661. // or not. We copy kMayDefer to kPrevDefer when setting kHasE or
  662. // kBegunE, and clear it when clearing those bits.
  663. static constexpr uint32_t kPrevDefer = 1 << 8;
  664. // Exclusive-locked blocks all read locks and write locks. This bit
  665. // may be set before all readers have finished, but in that case the
  666. // thread that sets it won't return to the caller until all read locks
  667. // have been released.
  668. static constexpr uint32_t kHasE = 1 << 7;
  669. // Exclusive-draining means that lock() is waiting for existing readers
  670. // to leave, but that new readers may still acquire shared access.
  671. // This is only used in reader priority mode. New readers during
  672. // drain must be inline. The difference between this and kHasU is that
  673. // kBegunE prevents kMayDefer from being set.
  674. static constexpr uint32_t kBegunE = 1 << 6;
  675. // At most one thread may have either exclusive or upgrade lock
  676. // ownership. Unlike exclusive mode, ownership of the lock in upgrade
  677. // mode doesn't preclude other threads holding the lock in shared mode.
  678. // boost's concept for this doesn't explicitly say whether new shared
  679. // locks can be acquired one lock_upgrade has succeeded, but doesn't
  680. // list that as disallowed. RWSpinLock disallows new read locks after
  681. // lock_upgrade has been acquired, but the boost implementation doesn't.
  682. // We choose the latter.
  683. static constexpr uint32_t kHasU = 1 << 5;
  684. // There are three states that we consider to be "solo", in that they
  685. // cannot coexist with other solo states. These are kHasE, kBegunE,
  686. // and kHasU. Note that S doesn't conflict with any of these, because
  687. // setting the kHasE is only one of the two steps needed to actually
  688. // acquire the lock in exclusive mode (the other is draining the existing
  689. // S holders).
  690. static constexpr uint32_t kHasSolo = kHasE | kBegunE | kHasU;
  691. // Once a thread sets kHasE it needs to wait for the current readers
  692. // to exit the lock. We give this a separate wait identity from the
  693. // waiting to set kHasE so that we can perform partial wakeups (wake
  694. // one instead of wake all).
  695. static constexpr uint32_t kWaitingNotS = 1 << 4;
  696. // When waking writers we can either wake them all, in which case we
  697. // can clear kWaitingE, or we can call futexWake(1). futexWake tells
  698. // us if anybody woke up, but even if we detect that nobody woke up we
  699. // can't clear the bit after the fact without issuing another wakeup.
  700. // To avoid thundering herds when there are lots of pending lock()
  701. // without needing to call futexWake twice when there is only one
  702. // waiter, kWaitingE actually encodes if we have observed multiple
  703. // concurrent waiters. Tricky: ABA issues on futexWait mean that when
  704. // we see kWaitingESingle we can't assume that there is only one.
  705. static constexpr uint32_t kWaitingESingle = 1 << 2;
  706. static constexpr uint32_t kWaitingEMultiple = 1 << 3;
  707. static constexpr uint32_t kWaitingE = kWaitingESingle | kWaitingEMultiple;
  708. // kWaitingU is essentially a 1 bit saturating counter. It always
  709. // requires a wakeAll.
  710. static constexpr uint32_t kWaitingU = 1 << 1;
  711. // All blocked lock_shared() should be awoken, so it is correct (not
  712. // suboptimal) to wakeAll if there are any shared readers.
  713. static constexpr uint32_t kWaitingS = 1 << 0;
  714. // kWaitingAny is a mask of all of the bits that record the state of
  715. // threads, rather than the state of the lock. It is convenient to be
  716. // able to mask them off during asserts.
  717. static constexpr uint32_t kWaitingAny =
  718. kWaitingNotS | kWaitingE | kWaitingU | kWaitingS;
  719. // The reader count at which a reader will attempt to use the lock
  720. // in deferred mode. If this value is 2, then the second concurrent
  721. // reader will set kMayDefer and use deferredReaders[]. kMayDefer is
  722. // cleared during exclusive access, so this threshold must be reached
  723. // each time a lock is held in exclusive mode.
  724. static constexpr uint32_t kNumSharedToStartDeferring = 2;
  725. // The typical number of spins that a thread will wait for a state
  726. // transition. There is no bound on the number of threads that can wait
  727. // for a writer, so we are pretty conservative here to limit the chance
  728. // that we are starving the writer of CPU. Each spin is 6 or 7 nanos,
  729. // almost all of which is in the pause instruction.
  730. static constexpr uint32_t kMaxSpinCount = !BlockImmediately ? 1000 : 2;
  731. // The maximum number of soft yields before falling back to futex.
  732. // If the preemption heuristic is activated we will fall back before
  733. // this. A soft yield takes ~900 nanos (two sched_yield plus a call
  734. // to getrusage, with checks of the goal at each step). Soft yields
  735. // aren't compatible with deterministic execution under test (unlike
  736. // futexWaitUntil, which has a capricious but deterministic back end).
  737. static constexpr uint32_t kMaxSoftYieldCount = !BlockImmediately ? 1000 : 0;
  738. // If AccessSpreader assigns indexes from 0..k*n-1 on a system where some
  739. // level of the memory hierarchy is symmetrically divided into k pieces
  740. // (NUMA nodes, last-level caches, L1 caches, ...), then slot indexes
  741. // that are the same after integer division by k share that resource.
  742. // Our strategy for deferred readers is to probe up to numSlots/4 slots,
  743. // using the full granularity of AccessSpreader for the start slot
  744. // and then search outward. We can use AccessSpreader::current(n)
  745. // without managing our own spreader if kMaxDeferredReaders <=
  746. // AccessSpreader::kMaxCpus, which is currently 128.
  747. //
  748. // Our 2-socket E5-2660 machines have 8 L1 caches on each chip,
  749. // with 64 byte cache lines. That means we need 64*16 bytes of
  750. // deferredReaders[] to give each L1 its own playground. On x86_64
  751. // each DeferredReaderSlot is 8 bytes, so we need kMaxDeferredReaders
  752. // * kDeferredSeparationFactor >= 64 * 16 / 8 == 128. If
  753. // kDeferredSearchDistance * kDeferredSeparationFactor <=
  754. // 64 / 8 then we will search only within a single cache line, which
  755. // guarantees we won't have inter-L1 contention. We give ourselves
  756. // a factor of 2 on the core count, which should hold us for a couple
  757. // processor generations. deferredReaders[] is 2048 bytes currently.
  758. public:
  759. static constexpr uint32_t kMaxDeferredReaders = 64;
  760. static constexpr uint32_t kDeferredSearchDistance = 2;
  761. static constexpr uint32_t kDeferredSeparationFactor = 4;
  762. private:
  763. static_assert(
  764. !(kMaxDeferredReaders & (kMaxDeferredReaders - 1)),
  765. "kMaxDeferredReaders must be a power of 2");
  766. static_assert(
  767. !(kDeferredSearchDistance & (kDeferredSearchDistance - 1)),
  768. "kDeferredSearchDistance must be a power of 2");
  769. // The number of deferred locks that can be simultaneously acquired
  770. // by a thread via the token-less methods without performing any heap
  771. // allocations. Each of these costs 3 pointers (24 bytes, probably)
  772. // per thread. There's not much point in making this larger than
  773. // kDeferredSearchDistance.
  774. static constexpr uint32_t kTokenStackTLSCapacity = 2;
  775. // We need to make sure that if there is a lock_shared()
  776. // and lock_shared(token) followed by unlock_shared() and
  777. // unlock_shared(token), the token-less unlock doesn't null
  778. // out deferredReaders[token.slot_]. If we allowed that, then
  779. // unlock_shared(token) wouldn't be able to assume that its lock
  780. // had been inlined by applyDeferredReaders when it finds that
  781. // deferredReaders[token.slot_] no longer points to this. We accomplish
  782. // this by stealing bit 0 from the pointer to record that the slot's
  783. // element has no token, hence our use of uintptr_t in deferredReaders[].
  784. static constexpr uintptr_t kTokenless = 0x1;
  785. // This is the starting location for Token-less unlock_shared().
  786. static FOLLY_SHAREDMUTEX_TLS uint32_t tls_lastTokenlessSlot;
  787. // Last deferred reader slot used.
  788. static FOLLY_SHAREDMUTEX_TLS uint32_t tls_lastDeferredReaderSlot;
  789. // Only indexes divisible by kDeferredSeparationFactor are used.
  790. // If any of those elements points to a SharedMutexImpl, then it
  791. // should be considered that there is a shared lock on that instance.
  792. // See kTokenless.
  793. public:
  794. typedef Atom<uintptr_t> DeferredReaderSlot;
  795. private:
  796. alignas(hardware_destructive_interference_size) static DeferredReaderSlot
  797. deferredReaders[kMaxDeferredReaders * kDeferredSeparationFactor];
  798. // Performs an exclusive lock, waiting for state_ & waitMask to be
  799. // zero first
  800. template <class WaitContext>
  801. bool lockExclusiveImpl(uint32_t preconditionGoalMask, WaitContext& ctx) {
  802. uint32_t state = state_.load(std::memory_order_acquire);
  803. if (LIKELY(
  804. (state & (preconditionGoalMask | kMayDefer | kHasS)) == 0 &&
  805. state_.compare_exchange_strong(state, (state | kHasE) & ~kHasU))) {
  806. return true;
  807. } else {
  808. return lockExclusiveImpl(state, preconditionGoalMask, ctx);
  809. }
  810. }
  811. template <class WaitContext>
  812. bool lockExclusiveImpl(
  813. uint32_t& state,
  814. uint32_t preconditionGoalMask,
  815. WaitContext& ctx) {
  816. while (true) {
  817. if (UNLIKELY((state & preconditionGoalMask) != 0) &&
  818. !waitForZeroBits(state, preconditionGoalMask, kWaitingE, ctx) &&
  819. ctx.canTimeOut()) {
  820. return false;
  821. }
  822. uint32_t after = (state & kMayDefer) == 0 ? 0 : kPrevDefer;
  823. if (!kReaderPriority || (state & (kMayDefer | kHasS)) == 0) {
  824. // Block readers immediately, either because we are in write
  825. // priority mode or because we can acquire the lock in one
  826. // step. Note that if state has kHasU, then we are doing an
  827. // unlock_upgrade_and_lock() and we should clear it (reader
  828. // priority branch also does this).
  829. after |= (state | kHasE) & ~(kHasU | kMayDefer);
  830. } else {
  831. after |= (state | kBegunE) & ~(kHasU | kMayDefer);
  832. }
  833. if (state_.compare_exchange_strong(state, after)) {
  834. auto before = state;
  835. state = after;
  836. // If we set kHasE (writer priority) then no new readers can
  837. // arrive. If we set kBegunE then they can still enter, but
  838. // they must be inline. Either way we need to either spin on
  839. // deferredReaders[] slots, or inline them so that we can wait on
  840. // kHasS to zero itself. deferredReaders[] is pointers, which on
  841. // x86_64 are bigger than futex() can handle, so we inline the
  842. // deferred locks instead of trying to futexWait on each slot.
  843. // Readers are responsible for rechecking state_ after recording
  844. // a deferred read to avoid atomicity problems between the state_
  845. // CAS and applyDeferredReader's reads of deferredReaders[].
  846. if (UNLIKELY((before & kMayDefer) != 0)) {
  847. applyDeferredReaders(state, ctx);
  848. }
  849. while (true) {
  850. assert((state & (kHasE | kBegunE)) != 0 && (state & kHasU) == 0);
  851. if (UNLIKELY((state & kHasS) != 0) &&
  852. !waitForZeroBits(state, kHasS, kWaitingNotS, ctx) &&
  853. ctx.canTimeOut()) {
  854. // Ugh. We blocked new readers and other writers for a while,
  855. // but were unable to complete. Move on. On the plus side
  856. // we can clear kWaitingNotS because nobody else can piggyback
  857. // on it.
  858. state = (state_ &= ~(kPrevDefer | kHasE | kBegunE | kWaitingNotS));
  859. wakeRegisteredWaiters(state, kWaitingE | kWaitingU | kWaitingS);
  860. return false;
  861. }
  862. if (kReaderPriority && (state & kHasE) == 0) {
  863. assert((state & kBegunE) != 0);
  864. if (!state_.compare_exchange_strong(
  865. state, (state & ~kBegunE) | kHasE)) {
  866. continue;
  867. }
  868. }
  869. return true;
  870. }
  871. }
  872. }
  873. }
  874. template <class WaitContext>
  875. bool waitForZeroBits(
  876. uint32_t& state,
  877. uint32_t goal,
  878. uint32_t waitMask,
  879. WaitContext& ctx) {
  880. uint32_t spinCount = 0;
  881. while (true) {
  882. state = state_.load(std::memory_order_acquire);
  883. if ((state & goal) == 0) {
  884. return true;
  885. }
  886. asm_volatile_pause();
  887. ++spinCount;
  888. if (UNLIKELY(spinCount >= kMaxSpinCount)) {
  889. return ctx.canBlock() &&
  890. yieldWaitForZeroBits(state, goal, waitMask, ctx);
  891. }
  892. }
  893. }
  894. template <class WaitContext>
  895. bool yieldWaitForZeroBits(
  896. uint32_t& state,
  897. uint32_t goal,
  898. uint32_t waitMask,
  899. WaitContext& ctx) {
  900. #ifdef RUSAGE_THREAD
  901. struct rusage usage;
  902. std::memset(&usage, 0, sizeof(usage));
  903. long before = -1;
  904. #endif
  905. for (uint32_t yieldCount = 0; yieldCount < kMaxSoftYieldCount;
  906. ++yieldCount) {
  907. for (int softState = 0; softState < 3; ++softState) {
  908. if (softState < 2) {
  909. std::this_thread::yield();
  910. } else {
  911. #ifdef RUSAGE_THREAD
  912. getrusage(RUSAGE_THREAD, &usage);
  913. #endif
  914. }
  915. if (((state = state_.load(std::memory_order_acquire)) & goal) == 0) {
  916. return true;
  917. }
  918. if (ctx.shouldTimeOut()) {
  919. return false;
  920. }
  921. }
  922. #ifdef RUSAGE_THREAD
  923. if (before >= 0 && usage.ru_nivcsw >= before + 2) {
  924. // One involuntary csw might just be occasional background work,
  925. // but if we get two in a row then we guess that there is someone
  926. // else who can profitably use this CPU. Fall back to futex
  927. break;
  928. }
  929. before = usage.ru_nivcsw;
  930. #endif
  931. }
  932. return futexWaitForZeroBits(state, goal, waitMask, ctx);
  933. }
  934. template <class WaitContext>
  935. bool futexWaitForZeroBits(
  936. uint32_t& state,
  937. uint32_t goal,
  938. uint32_t waitMask,
  939. WaitContext& ctx) {
  940. assert(
  941. waitMask == kWaitingNotS || waitMask == kWaitingE ||
  942. waitMask == kWaitingU || waitMask == kWaitingS);
  943. while (true) {
  944. state = state_.load(std::memory_order_acquire);
  945. if ((state & goal) == 0) {
  946. return true;
  947. }
  948. auto after = state;
  949. if (waitMask == kWaitingE) {
  950. if ((state & kWaitingESingle) != 0) {
  951. after |= kWaitingEMultiple;
  952. } else {
  953. after |= kWaitingESingle;
  954. }
  955. } else {
  956. after |= waitMask;
  957. }
  958. // CAS is better than atomic |= here, because it lets us avoid
  959. // setting the wait flag when the goal is concurrently achieved
  960. if (after != state && !state_.compare_exchange_strong(state, after)) {
  961. continue;
  962. }
  963. if (!ctx.doWait(state_, after, waitMask)) {
  964. // timed out
  965. return false;
  966. }
  967. }
  968. }
  969. // Wakes up waiters registered in state_ as appropriate, clearing the
  970. // awaiting bits for anybody that was awoken. Tries to perform direct
  971. // single wakeup of an exclusive waiter if appropriate
  972. void wakeRegisteredWaiters(uint32_t& state, uint32_t wakeMask) {
  973. if (UNLIKELY((state & wakeMask) != 0)) {
  974. wakeRegisteredWaitersImpl(state, wakeMask);
  975. }
  976. }
  977. void wakeRegisteredWaitersImpl(uint32_t& state, uint32_t wakeMask) {
  978. // If there are multiple lock() pending only one of them will actually
  979. // get to wake up, so issuing futexWakeAll will make a thundering herd.
  980. // There's nothing stopping us from issuing futexWake(1) instead,
  981. // so long as the wait bits are still an accurate reflection of
  982. // the waiters. If we notice (via futexWake's return value) that
  983. // nobody woke up then we can try again with the normal wake-all path.
  984. // Note that we can't just clear the bits at that point; we need to
  985. // clear the bits and then issue another wakeup.
  986. //
  987. // It is possible that we wake an E waiter but an outside S grabs the
  988. // lock instead, at which point we should wake pending U and S waiters.
  989. // Rather than tracking state to make the failing E regenerate the
  990. // wakeup, we just disable the optimization in the case that there
  991. // are waiting U or S that we are eligible to wake.
  992. if ((wakeMask & kWaitingE) == kWaitingE &&
  993. (state & wakeMask) == kWaitingE &&
  994. detail::futexWake(&state_, 1, kWaitingE) > 0) {
  995. // somebody woke up, so leave state_ as is and clear it later
  996. return;
  997. }
  998. if ((state & wakeMask) != 0) {
  999. auto prev = state_.fetch_and(~wakeMask);
  1000. if ((prev & wakeMask) != 0) {
  1001. futexWakeAll(wakeMask);
  1002. }
  1003. state = prev & ~wakeMask;
  1004. }
  1005. }
  1006. void futexWakeAll(uint32_t wakeMask) {
  1007. detail::futexWake(&state_, std::numeric_limits<int>::max(), wakeMask);
  1008. }
  1009. DeferredReaderSlot* deferredReader(uint32_t slot) {
  1010. return &deferredReaders[slot * kDeferredSeparationFactor];
  1011. }
  1012. uintptr_t tokenfulSlotValue() {
  1013. return reinterpret_cast<uintptr_t>(this);
  1014. }
  1015. uintptr_t tokenlessSlotValue() {
  1016. return tokenfulSlotValue() | kTokenless;
  1017. }
  1018. bool slotValueIsThis(uintptr_t slotValue) {
  1019. return (slotValue & ~kTokenless) == tokenfulSlotValue();
  1020. }
  1021. // Clears any deferredReaders[] that point to this, adjusting the inline
  1022. // shared lock count to compensate. Does some spinning and yielding
  1023. // to avoid the work. Always finishes the application, even if ctx
  1024. // times out.
  1025. template <class WaitContext>
  1026. void applyDeferredReaders(uint32_t& state, WaitContext& ctx) {
  1027. uint32_t slot = 0;
  1028. uint32_t spinCount = 0;
  1029. while (true) {
  1030. while (!slotValueIsThis(
  1031. deferredReader(slot)->load(std::memory_order_acquire))) {
  1032. if (++slot == kMaxDeferredReaders) {
  1033. return;
  1034. }
  1035. }
  1036. asm_volatile_pause();
  1037. if (UNLIKELY(++spinCount >= kMaxSpinCount)) {
  1038. applyDeferredReaders(state, ctx, slot);
  1039. return;
  1040. }
  1041. }
  1042. }
  1043. template <class WaitContext>
  1044. void applyDeferredReaders(uint32_t& state, WaitContext& ctx, uint32_t slot) {
  1045. #ifdef RUSAGE_THREAD
  1046. struct rusage usage;
  1047. std::memset(&usage, 0, sizeof(usage));
  1048. long before = -1;
  1049. #endif
  1050. for (uint32_t yieldCount = 0; yieldCount < kMaxSoftYieldCount;
  1051. ++yieldCount) {
  1052. for (int softState = 0; softState < 3; ++softState) {
  1053. if (softState < 2) {
  1054. std::this_thread::yield();
  1055. } else {
  1056. #ifdef RUSAGE_THREAD
  1057. getrusage(RUSAGE_THREAD, &usage);
  1058. #endif
  1059. }
  1060. while (!slotValueIsThis(
  1061. deferredReader(slot)->load(std::memory_order_acquire))) {
  1062. if (++slot == kMaxDeferredReaders) {
  1063. return;
  1064. }
  1065. }
  1066. if (ctx.shouldTimeOut()) {
  1067. // finish applying immediately on timeout
  1068. break;
  1069. }
  1070. }
  1071. #ifdef RUSAGE_THREAD
  1072. if (before >= 0 && usage.ru_nivcsw >= before + 2) {
  1073. // heuristic says run queue is not empty
  1074. break;
  1075. }
  1076. before = usage.ru_nivcsw;
  1077. #endif
  1078. }
  1079. uint32_t movedSlotCount = 0;
  1080. for (; slot < kMaxDeferredReaders; ++slot) {
  1081. auto slotPtr = deferredReader(slot);
  1082. auto slotValue = slotPtr->load(std::memory_order_acquire);
  1083. if (slotValueIsThis(slotValue) &&
  1084. slotPtr->compare_exchange_strong(slotValue, 0)) {
  1085. ++movedSlotCount;
  1086. }
  1087. }
  1088. if (movedSlotCount > 0) {
  1089. state = (state_ += movedSlotCount * kIncrHasS);
  1090. }
  1091. assert((state & (kHasE | kBegunE)) != 0);
  1092. // if state + kIncrHasS overflows (off the end of state) then either
  1093. // we have 2^(32-9) readers (almost certainly an application bug)
  1094. // or we had an underflow (also a bug)
  1095. assert(state < state + kIncrHasS);
  1096. }
  1097. // It is straightfoward to make a token-less lock_shared() and
  1098. // unlock_shared() either by making the token-less version always use
  1099. // INLINE_SHARED mode or by removing the token version. Supporting
  1100. // deferred operation for both types is trickier than it appears, because
  1101. // the purpose of the token it so that unlock_shared doesn't have to
  1102. // look in other slots for its deferred lock. Token-less unlock_shared
  1103. // might place a deferred lock in one place and then release a different
  1104. // slot that was originally used by the token-ful version. If this was
  1105. // important we could solve the problem by differentiating the deferred
  1106. // locks so that cross-variety release wouldn't occur. The best way
  1107. // is probably to steal a bit from the pointer, making deferredLocks[]
  1108. // an array of Atom<uintptr_t>.
  1109. template <class WaitContext>
  1110. bool lockSharedImpl(Token* token, WaitContext& ctx) {
  1111. uint32_t state = state_.load(std::memory_order_relaxed);
  1112. if ((state & (kHasS | kMayDefer | kHasE)) == 0 &&
  1113. state_.compare_exchange_strong(state, state + kIncrHasS)) {
  1114. if (token != nullptr) {
  1115. token->type_ = Token::Type::INLINE_SHARED;
  1116. }
  1117. return true;
  1118. }
  1119. return lockSharedImpl(state, token, ctx);
  1120. }
  1121. template <class WaitContext>
  1122. bool lockSharedImpl(uint32_t& state, Token* token, WaitContext& ctx);
  1123. // Updates the state in/out argument as if the locks were made inline,
  1124. // but does not update state_
  1125. void cleanupTokenlessSharedDeferred(uint32_t& state) {
  1126. for (uint32_t i = 0; i < kMaxDeferredReaders; ++i) {
  1127. auto slotPtr = deferredReader(i);
  1128. auto slotValue = slotPtr->load(std::memory_order_relaxed);
  1129. if (slotValue == tokenlessSlotValue()) {
  1130. slotPtr->store(0, std::memory_order_relaxed);
  1131. state += kIncrHasS;
  1132. if ((state & kHasS) == 0) {
  1133. break;
  1134. }
  1135. }
  1136. }
  1137. }
  1138. bool tryUnlockTokenlessSharedDeferred();
  1139. bool tryUnlockSharedDeferred(uint32_t slot) {
  1140. assert(slot < kMaxDeferredReaders);
  1141. auto slotValue = tokenfulSlotValue();
  1142. return deferredReader(slot)->compare_exchange_strong(slotValue, 0);
  1143. }
  1144. uint32_t unlockSharedInline() {
  1145. uint32_t state = (state_ -= kIncrHasS);
  1146. assert(
  1147. (state & (kHasE | kBegunE | kMayDefer)) != 0 ||
  1148. state < state + kIncrHasS);
  1149. if ((state & kHasS) == 0) {
  1150. // Only the second half of lock() can be blocked by a non-zero
  1151. // reader count, so that's the only thing we need to wake
  1152. wakeRegisteredWaiters(state, kWaitingNotS);
  1153. }
  1154. return state;
  1155. }
  1156. template <class WaitContext>
  1157. bool lockUpgradeImpl(WaitContext& ctx) {
  1158. uint32_t state;
  1159. do {
  1160. if (!waitForZeroBits(state, kHasSolo, kWaitingU, ctx)) {
  1161. return false;
  1162. }
  1163. } while (!state_.compare_exchange_strong(state, state | kHasU));
  1164. return true;
  1165. }
  1166. public:
  1167. class ReadHolder {
  1168. ReadHolder() : lock_(nullptr) {}
  1169. public:
  1170. explicit ReadHolder(const SharedMutexImpl* lock)
  1171. : lock_(const_cast<SharedMutexImpl*>(lock)) {
  1172. if (lock_) {
  1173. lock_->lock_shared(token_);
  1174. }
  1175. }
  1176. explicit ReadHolder(const SharedMutexImpl& lock)
  1177. : lock_(const_cast<SharedMutexImpl*>(&lock)) {
  1178. lock_->lock_shared(token_);
  1179. }
  1180. ReadHolder(ReadHolder&& rhs) noexcept
  1181. : lock_(rhs.lock_), token_(rhs.token_) {
  1182. rhs.lock_ = nullptr;
  1183. }
  1184. // Downgrade from upgrade mode
  1185. explicit ReadHolder(UpgradeHolder&& upgraded) : lock_(upgraded.lock_) {
  1186. assert(upgraded.lock_ != nullptr);
  1187. upgraded.lock_ = nullptr;
  1188. lock_->unlock_upgrade_and_lock_shared(token_);
  1189. }
  1190. // Downgrade from exclusive mode
  1191. explicit ReadHolder(WriteHolder&& writer) : lock_(writer.lock_) {
  1192. assert(writer.lock_ != nullptr);
  1193. writer.lock_ = nullptr;
  1194. lock_->unlock_and_lock_shared(token_);
  1195. }
  1196. ReadHolder& operator=(ReadHolder&& rhs) noexcept {
  1197. std::swap(lock_, rhs.lock_);
  1198. std::swap(token_, rhs.token_);
  1199. return *this;
  1200. }
  1201. ReadHolder(const ReadHolder& rhs) = delete;
  1202. ReadHolder& operator=(const ReadHolder& rhs) = delete;
  1203. ~ReadHolder() {
  1204. unlock();
  1205. }
  1206. void unlock() {
  1207. if (lock_) {
  1208. lock_->unlock_shared(token_);
  1209. lock_ = nullptr;
  1210. }
  1211. }
  1212. private:
  1213. friend class UpgradeHolder;
  1214. friend class WriteHolder;
  1215. SharedMutexImpl* lock_;
  1216. SharedMutexToken token_;
  1217. };
  1218. class UpgradeHolder {
  1219. UpgradeHolder() : lock_(nullptr) {}
  1220. public:
  1221. explicit UpgradeHolder(SharedMutexImpl* lock) : lock_(lock) {
  1222. if (lock_) {
  1223. lock_->lock_upgrade();
  1224. }
  1225. }
  1226. explicit UpgradeHolder(SharedMutexImpl& lock) : lock_(&lock) {
  1227. lock_->lock_upgrade();
  1228. }
  1229. // Downgrade from exclusive mode
  1230. explicit UpgradeHolder(WriteHolder&& writer) : lock_(writer.lock_) {
  1231. assert(writer.lock_ != nullptr);
  1232. writer.lock_ = nullptr;
  1233. lock_->unlock_and_lock_upgrade();
  1234. }
  1235. UpgradeHolder(UpgradeHolder&& rhs) noexcept : lock_(rhs.lock_) {
  1236. rhs.lock_ = nullptr;
  1237. }
  1238. UpgradeHolder& operator=(UpgradeHolder&& rhs) noexcept {
  1239. std::swap(lock_, rhs.lock_);
  1240. return *this;
  1241. }
  1242. UpgradeHolder(const UpgradeHolder& rhs) = delete;
  1243. UpgradeHolder& operator=(const UpgradeHolder& rhs) = delete;
  1244. ~UpgradeHolder() {
  1245. unlock();
  1246. }
  1247. void unlock() {
  1248. if (lock_) {
  1249. lock_->unlock_upgrade();
  1250. lock_ = nullptr;
  1251. }
  1252. }
  1253. private:
  1254. friend class WriteHolder;
  1255. friend class ReadHolder;
  1256. SharedMutexImpl* lock_;
  1257. };
  1258. class WriteHolder {
  1259. WriteHolder() : lock_(nullptr) {}
  1260. public:
  1261. explicit WriteHolder(SharedMutexImpl* lock) : lock_(lock) {
  1262. if (lock_) {
  1263. lock_->lock();
  1264. }
  1265. }
  1266. explicit WriteHolder(SharedMutexImpl& lock) : lock_(&lock) {
  1267. lock_->lock();
  1268. }
  1269. // Promotion from upgrade mode
  1270. explicit WriteHolder(UpgradeHolder&& upgrade) : lock_(upgrade.lock_) {
  1271. assert(upgrade.lock_ != nullptr);
  1272. upgrade.lock_ = nullptr;
  1273. lock_->unlock_upgrade_and_lock();
  1274. }
  1275. // README:
  1276. //
  1277. // It is intended that WriteHolder(ReadHolder&& rhs) do not exist.
  1278. //
  1279. // Shared locks (read) can not safely upgrade to unique locks (write).
  1280. // That upgrade path is a well-known recipe for deadlock, so we explicitly
  1281. // disallow it.
  1282. //
  1283. // If you need to do a conditional mutation, you have a few options:
  1284. // 1. Check the condition under a shared lock and release it.
  1285. // Then maybe check the condition again under a unique lock and maybe do
  1286. // the mutation.
  1287. // 2. Check the condition once under an upgradeable lock.
  1288. // Then maybe upgrade the lock to a unique lock and do the mutation.
  1289. // 3. Check the condition and maybe perform the mutation under a unique
  1290. // lock.
  1291. //
  1292. // Relevant upgradeable lock notes:
  1293. // * At most one upgradeable lock can be held at a time for a given shared
  1294. // mutex, just like a unique lock.
  1295. // * An upgradeable lock may be held concurrently with any number of shared
  1296. // locks.
  1297. // * An upgradeable lock may be upgraded atomically to a unique lock.
  1298. WriteHolder(WriteHolder&& rhs) noexcept : lock_(rhs.lock_) {
  1299. rhs.lock_ = nullptr;
  1300. }
  1301. WriteHolder& operator=(WriteHolder&& rhs) noexcept {
  1302. std::swap(lock_, rhs.lock_);
  1303. return *this;
  1304. }
  1305. WriteHolder(const WriteHolder& rhs) = delete;
  1306. WriteHolder& operator=(const WriteHolder& rhs) = delete;
  1307. ~WriteHolder() {
  1308. unlock();
  1309. }
  1310. void unlock() {
  1311. if (lock_) {
  1312. lock_->unlock();
  1313. lock_ = nullptr;
  1314. }
  1315. }
  1316. private:
  1317. friend class ReadHolder;
  1318. friend class UpgradeHolder;
  1319. SharedMutexImpl* lock_;
  1320. };
  1321. // Adapters for Synchronized<>
  1322. friend void acquireRead(SharedMutexImpl& lock) {
  1323. lock.lock_shared();
  1324. }
  1325. friend void acquireReadWrite(SharedMutexImpl& lock) {
  1326. lock.lock();
  1327. }
  1328. friend void releaseRead(SharedMutexImpl& lock) {
  1329. lock.unlock_shared();
  1330. }
  1331. friend void releaseReadWrite(SharedMutexImpl& lock) {
  1332. lock.unlock();
  1333. }
  1334. friend bool acquireRead(SharedMutexImpl& lock, unsigned int ms) {
  1335. return lock.try_lock_shared_for(std::chrono::milliseconds(ms));
  1336. }
  1337. friend bool acquireReadWrite(SharedMutexImpl& lock, unsigned int ms) {
  1338. return lock.try_lock_for(std::chrono::milliseconds(ms));
  1339. }
  1340. };
  1341. typedef SharedMutexImpl<true> SharedMutexReadPriority;
  1342. typedef SharedMutexImpl<false> SharedMutexWritePriority;
  1343. typedef SharedMutexWritePriority SharedMutex;
  1344. typedef SharedMutexImpl<false, void, std::atomic, false, false>
  1345. SharedMutexSuppressTSAN;
  1346. // Prevent the compiler from instantiating these in other translation units.
  1347. // They are instantiated once in SharedMutex.cpp
  1348. extern template class SharedMutexImpl<true>;
  1349. extern template class SharedMutexImpl<false>;
  1350. template <
  1351. bool ReaderPriority,
  1352. typename Tag_,
  1353. template <typename> class Atom,
  1354. bool BlockImmediately,
  1355. bool AnnotateForThreadSanitizer>
  1356. alignas(hardware_destructive_interference_size) typename SharedMutexImpl<
  1357. ReaderPriority,
  1358. Tag_,
  1359. Atom,
  1360. BlockImmediately,
  1361. AnnotateForThreadSanitizer>::DeferredReaderSlot
  1362. SharedMutexImpl<
  1363. ReaderPriority,
  1364. Tag_,
  1365. Atom,
  1366. BlockImmediately,
  1367. AnnotateForThreadSanitizer>::deferredReaders
  1368. [kMaxDeferredReaders * kDeferredSeparationFactor] = {};
  1369. template <
  1370. bool ReaderPriority,
  1371. typename Tag_,
  1372. template <typename> class Atom,
  1373. bool BlockImmediately,
  1374. bool AnnotateForThreadSanitizer>
  1375. FOLLY_SHAREDMUTEX_TLS uint32_t SharedMutexImpl<
  1376. ReaderPriority,
  1377. Tag_,
  1378. Atom,
  1379. BlockImmediately,
  1380. AnnotateForThreadSanitizer>::tls_lastTokenlessSlot = 0;
  1381. template <
  1382. bool ReaderPriority,
  1383. typename Tag_,
  1384. template <typename> class Atom,
  1385. bool BlockImmediately,
  1386. bool AnnotateForThreadSanitizer>
  1387. FOLLY_SHAREDMUTEX_TLS uint32_t SharedMutexImpl<
  1388. ReaderPriority,
  1389. Tag_,
  1390. Atom,
  1391. BlockImmediately,
  1392. AnnotateForThreadSanitizer>::tls_lastDeferredReaderSlot = 0;
  1393. template <
  1394. bool ReaderPriority,
  1395. typename Tag_,
  1396. template <typename> class Atom,
  1397. bool BlockImmediately,
  1398. bool AnnotateForThreadSanitizer>
  1399. bool SharedMutexImpl<
  1400. ReaderPriority,
  1401. Tag_,
  1402. Atom,
  1403. BlockImmediately,
  1404. AnnotateForThreadSanitizer>::tryUnlockTokenlessSharedDeferred() {
  1405. auto bestSlot = tls_lastTokenlessSlot;
  1406. for (uint32_t i = 0; i < kMaxDeferredReaders; ++i) {
  1407. auto slotPtr = deferredReader(bestSlot ^ i);
  1408. auto slotValue = slotPtr->load(std::memory_order_relaxed);
  1409. if (slotValue == tokenlessSlotValue() &&
  1410. slotPtr->compare_exchange_strong(slotValue, 0)) {
  1411. tls_lastTokenlessSlot = bestSlot ^ i;
  1412. return true;
  1413. }
  1414. }
  1415. return false;
  1416. }
  1417. template <
  1418. bool ReaderPriority,
  1419. typename Tag_,
  1420. template <typename> class Atom,
  1421. bool BlockImmediately,
  1422. bool AnnotateForThreadSanitizer>
  1423. template <class WaitContext>
  1424. bool SharedMutexImpl<
  1425. ReaderPriority,
  1426. Tag_,
  1427. Atom,
  1428. BlockImmediately,
  1429. AnnotateForThreadSanitizer>::
  1430. lockSharedImpl(uint32_t& state, Token* token, WaitContext& ctx) {
  1431. while (true) {
  1432. if (UNLIKELY((state & kHasE) != 0) &&
  1433. !waitForZeroBits(state, kHasE, kWaitingS, ctx) && ctx.canTimeOut()) {
  1434. return false;
  1435. }
  1436. uint32_t slot = tls_lastDeferredReaderSlot;
  1437. uintptr_t slotValue = 1; // any non-zero value will do
  1438. bool canAlreadyDefer = (state & kMayDefer) != 0;
  1439. bool aboveDeferThreshold =
  1440. (state & kHasS) >= (kNumSharedToStartDeferring - 1) * kIncrHasS;
  1441. bool drainInProgress = ReaderPriority && (state & kBegunE) != 0;
  1442. if (canAlreadyDefer || (aboveDeferThreshold && !drainInProgress)) {
  1443. /* Try using the most recent slot first. */
  1444. slotValue = deferredReader(slot)->load(std::memory_order_relaxed);
  1445. if (slotValue != 0) {
  1446. // starting point for our empty-slot search, can change after
  1447. // calling waitForZeroBits
  1448. uint32_t bestSlot =
  1449. (uint32_t)folly::AccessSpreader<Atom>::current(kMaxDeferredReaders);
  1450. // deferred readers are already enabled, or it is time to
  1451. // enable them if we can find a slot
  1452. for (uint32_t i = 0; i < kDeferredSearchDistance; ++i) {
  1453. slot = bestSlot ^ i;
  1454. assert(slot < kMaxDeferredReaders);
  1455. slotValue = deferredReader(slot)->load(std::memory_order_relaxed);
  1456. if (slotValue == 0) {
  1457. // found empty slot
  1458. tls_lastDeferredReaderSlot = slot;
  1459. break;
  1460. }
  1461. }
  1462. }
  1463. }
  1464. if (slotValue != 0) {
  1465. // not yet deferred, or no empty slots
  1466. if (state_.compare_exchange_strong(state, state + kIncrHasS)) {
  1467. // successfully recorded the read lock inline
  1468. if (token != nullptr) {
  1469. token->type_ = Token::Type::INLINE_SHARED;
  1470. }
  1471. return true;
  1472. }
  1473. // state is updated, try again
  1474. continue;
  1475. }
  1476. // record that deferred readers might be in use if necessary
  1477. if ((state & kMayDefer) == 0) {
  1478. if (!state_.compare_exchange_strong(state, state | kMayDefer)) {
  1479. // keep going if CAS failed because somebody else set the bit
  1480. // for us
  1481. if ((state & (kHasE | kMayDefer)) != kMayDefer) {
  1482. continue;
  1483. }
  1484. }
  1485. // state = state | kMayDefer;
  1486. }
  1487. // try to use the slot
  1488. bool gotSlot = deferredReader(slot)->compare_exchange_strong(
  1489. slotValue,
  1490. token == nullptr ? tokenlessSlotValue() : tokenfulSlotValue());
  1491. // If we got the slot, we need to verify that an exclusive lock
  1492. // didn't happen since we last checked. If we didn't get the slot we
  1493. // need to recheck state_ anyway to make sure we don't waste too much
  1494. // work. It is also possible that since we checked state_ someone
  1495. // has acquired and released the write lock, clearing kMayDefer.
  1496. // Both cases are covered by looking for the readers-possible bit,
  1497. // because it is off when the exclusive lock bit is set.
  1498. state = state_.load(std::memory_order_acquire);
  1499. if (!gotSlot) {
  1500. continue;
  1501. }
  1502. if (token == nullptr) {
  1503. tls_lastTokenlessSlot = slot;
  1504. }
  1505. if ((state & kMayDefer) != 0) {
  1506. assert((state & kHasE) == 0);
  1507. // success
  1508. if (token != nullptr) {
  1509. token->type_ = Token::Type::DEFERRED_SHARED;
  1510. token->slot_ = (uint16_t)slot;
  1511. }
  1512. return true;
  1513. }
  1514. // release the slot before retrying
  1515. if (token == nullptr) {
  1516. // We can't rely on slot. Token-less slot values can be freed by
  1517. // any unlock_shared(), so we need to do the full deferredReader
  1518. // search during unlock. Unlike unlock_shared(), we can't trust
  1519. // kPrevDefer here. This deferred lock isn't visible to lock()
  1520. // (that's the whole reason we're undoing it) so there might have
  1521. // subsequently been an unlock() and lock() with no intervening
  1522. // transition to deferred mode.
  1523. if (!tryUnlockTokenlessSharedDeferred()) {
  1524. unlockSharedInline();
  1525. }
  1526. } else {
  1527. if (!tryUnlockSharedDeferred(slot)) {
  1528. unlockSharedInline();
  1529. }
  1530. }
  1531. // We got here not because the lock was unavailable, but because
  1532. // we lost a compare-and-swap. Try-lock is typically allowed to
  1533. // have spurious failures, but there is no lock efficiency gain
  1534. // from exploiting that freedom here.
  1535. }
  1536. }
  1537. } // namespace folly