// @(#)root/thread:$Id$ // Authors: Enric Tejedor CERN 12/09/2016 // Philippe Canal FNAL 12/09/2016 /************************************************************************* * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #ifndef ROOT_TReentrantRWLock #define ROOT_TReentrantRWLock #include "ThreadLocalStorage.h" #include "ROOT/TSpinMutex.hxx" #include "TVirtualRWMutex.h" #include #include #include #include namespace ROOT { namespace Internal { struct UniqueLockRecurseCount { using Hint_t = TVirtualRWMutex::Hint_t; struct LocalCounts { size_t fReadersCount = 0; bool fIsWriter = false; }; size_t fWriteRecurse = 0; ///fReadersCount); return reinterpret_cast(&(local->fReadersCount)); } template Hint_t *IncrementReadCount(local_t &local, MutexT &) { return IncrementReadCount(local); } Hint_t *DecrementReadCount(local_t &local) { --(local->fReadersCount); return reinterpret_cast(&(local->fReadersCount)); } template Hint_t *DecrementReadCount(local_t &local, MutexT &) { return DecrementReadCount(local); } void ResetReadCount(local_t &local, int newvalue) { local->fReadersCount = newvalue; } bool IsCurrentWriter(local_t &local) { return local->fIsWriter; } bool IsNotCurrentWriter(local_t &local) { return !local->fIsWriter; } void SetIsWriter(local_t &local) { // if (fWriteRecurse == std::numeric_limits::max()) { // ::Fatal("TRWSpinLock::WriteLock", "Too many recursions in TRWSpinLock!"); // } ++fWriteRecurse; local->fIsWriter = true; } void DecrementWriteCount() { --fWriteRecurse; } void ResetIsWriter(local_t &local) { local->fIsWriter = false; } size_t &GetLocalReadersCount(local_t &local) { return local->fReadersCount; } }; struct RecurseCounts { using Hint_t = TVirtualRWMutex::Hint_t; using ReaderColl_t = std::unordered_map; size_t fWriteRecurse; ///(&count); } template Hint_t *IncrementReadCount(local_t &local, MutexT &mutex) { std::unique_lock lock(mutex); return IncrementReadCount(local); } Hint_t *DecrementReadCount(local_t &local) { auto &count = fReadersCount[local]; --count; return reinterpret_cast(&count); } template Hint_t *DecrementReadCount(local_t &local, MutexT &mutex) { std::unique_lock lock(mutex); return DecrementReadCount(local); } void ResetReadCount(local_t &local, int newvalue) { fReadersCount[local] = newvalue; } bool IsCurrentWriter(local_t &local) const { return fWriterThread == local; } bool IsNotCurrentWriter(local_t &local) const { return fWriterThread != local; } void SetIsWriter(local_t &local) { // if (fWriteRecurse == std::numeric_limits::max()) { // ::Fatal("TRWSpinLock::WriteLock", "Too many recursions in TRWSpinLock!"); // } ++fWriteRecurse; fWriterThread = local; } void DecrementWriteCount() { --fWriteRecurse; } void ResetIsWriter(local_t & /* local */) { fWriterThread = std::thread::id(); } size_t &GetLocalReadersCount(local_t &local) { return fReadersCount[local]; } }; } // Internal template class TReentrantRWLock { private: std::atomic fReaders; /// fReaderReservation; /// fWriterReservation; /// fWriter; /// GetStateBefore(); std::unique_ptr Rewind(const State &earlierState); void Apply(std::unique_ptr &&delta); }; } // end of namespace ROOT #endif