diff --git a/libcxx/src/debug.cpp b/libcxx/src/debug.cpp --- a/libcxx/src/debug.cpp +++ b/libcxx/src/debug.cpp @@ -14,7 +14,7 @@ #include "cstdio" #include "__hash_table" #ifndef _LIBCPP_HAS_NO_THREADS -#include "mutex" +#include "__threading_support" #if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB) #pragma comment(lib, "pthread") #endif @@ -62,17 +62,22 @@ { #ifndef _LIBCPP_HAS_NO_THREADS -typedef mutex mutex_type; -typedef lock_guard WLock; -typedef lock_guard RLock; - -mutex_type& -mut() -{ - static _LIBCPP_NO_DESTROY mutex_type m; - return m; -} -#endif // !_LIBCPP_HAS_NO_THREADS +_LIBCPP_SAFE_STATIC static __libcpp_mutex_t __db_mut = _LIBCPP_MUTEX_INITIALIZER; + +struct db_guard { + bool owns_lock = true; + db_guard() { __libcpp_mutex_lock(&__db_mut); } + ~db_guard() { + if (owns_lock) + __libcpp_mutex_unlock(&__db_mut); + } + void release() { owns_lock = false; } +}; +#else +struct db_guard { + void release() {}; +}; +#endif } // unnamed namespace @@ -136,9 +141,8 @@ void* __libcpp_db::__find_c_from_i(void* __i) const { -#ifndef _LIBCPP_HAS_NO_THREADS - RLock _(mut()); -#endif + // Read lock + db_guard lk; __i_node* i = __find_iterator(__i); _LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database."); return i->__c_ != nullptr ? i->__c_->__c_ : nullptr; @@ -147,9 +151,8 @@ void __libcpp_db::__insert_ic(void* __i, const void* __c) { -#ifndef _LIBCPP_HAS_NO_THREADS - WLock _(mut()); -#endif + // Write lock + db_guard lk; if (__cbeg_ == __cend_) return; size_t hc = hash()(__c) % static_cast(__cend_ - __cbeg_); @@ -170,9 +173,8 @@ void __libcpp_db::__insert_c(void* __c, __libcpp_db::_InsertConstruct *__fn) { -#ifndef _LIBCPP_HAS_NO_THREADS - WLock _(mut()); -#endif + // Write lock + db_guard lk; if (__csz_ + 1 > static_cast(__cend_ - __cbeg_)) { size_t nc = __next_prime(2*static_cast(__cend_ - __cbeg_) + 1); @@ -209,9 +211,8 @@ void __libcpp_db::__erase_i(void* __i) { -#ifndef _LIBCPP_HAS_NO_THREADS - WLock _(mut()); -#endif + // Write lock + db_guard lk; if (__ibeg_ != __iend_) { size_t hi = hash()(__i) % static_cast(__iend_ - __ibeg_); @@ -242,9 +243,8 @@ void __libcpp_db::__invalidate_all(void* __c) { -#ifndef _LIBCPP_HAS_NO_THREADS - WLock _(mut()); -#endif + // Write lock + db_guard lk; if (__cend_ != __cbeg_) { size_t hc = hash()(__c) % static_cast(__cend_ - __cbeg_); @@ -268,36 +268,23 @@ __c_node* __libcpp_db::__find_c_and_lock(void* __c) const { -#ifndef _LIBCPP_HAS_NO_THREADS - mut().lock(); -#endif + // Write lock - caller is likely to perform a write operation + db_guard lk; if (__cend_ == __cbeg_) - { -#ifndef _LIBCPP_HAS_NO_THREADS - mut().unlock(); -#endif return nullptr; - } + size_t hc = hash()(__c) % static_cast(__cend_ - __cbeg_); __c_node* p = __cbeg_[hc]; if (p == nullptr) - { -#ifndef _LIBCPP_HAS_NO_THREADS - mut().unlock(); -#endif return nullptr; - } + while (p->__c_ != __c) { p = p->__next_; if (p == nullptr) - { -#ifndef _LIBCPP_HAS_NO_THREADS - mut().unlock(); -#endif return nullptr; - } } + lk.release(); return p; } @@ -319,16 +306,15 @@ __libcpp_db::unlock() const { #ifndef _LIBCPP_HAS_NO_THREADS - mut().unlock(); + __libcpp_mutex_unlock(&__db_mut); #endif } void __libcpp_db::__erase_c(void* __c) { -#ifndef _LIBCPP_HAS_NO_THREADS - WLock _(mut()); -#endif + // Write lock + db_guard lk; if (__cend_ != __cbeg_) { size_t hc = hash()(__c) % static_cast(__cend_ - __cbeg_); @@ -363,9 +349,8 @@ void __libcpp_db::__iterator_copy(void* __i, const void* __i0) { -#ifndef _LIBCPP_HAS_NO_THREADS - WLock _(mut()); -#endif + // Write lock + db_guard lk; __i_node* i = __find_iterator(__i); __i_node* i0 = __find_iterator(__i0); __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr; @@ -391,9 +376,8 @@ bool __libcpp_db::__dereferenceable(const void* __i) const { -#ifndef _LIBCPP_HAS_NO_THREADS - RLock _(mut()); -#endif + // Read lock + db_guard lk; __i_node* i = __find_iterator(__i); return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i); } @@ -401,9 +385,8 @@ bool __libcpp_db::__decrementable(const void* __i) const { -#ifndef _LIBCPP_HAS_NO_THREADS - RLock _(mut()); -#endif + // Read lock + db_guard lk; __i_node* i = __find_iterator(__i); return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i); } @@ -411,9 +394,8 @@ bool __libcpp_db::__addable(const void* __i, ptrdiff_t __n) const { -#ifndef _LIBCPP_HAS_NO_THREADS - RLock _(mut()); -#endif + // Read lock + db_guard lk; __i_node* i = __find_iterator(__i); return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n); } @@ -421,9 +403,8 @@ bool __libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const { -#ifndef _LIBCPP_HAS_NO_THREADS - RLock _(mut()); -#endif + // Read lock + db_guard lk; __i_node* i = __find_iterator(__i); return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n); } @@ -431,9 +412,8 @@ bool __libcpp_db::__less_than_comparable(const void* __i, const void* __j) const { -#ifndef _LIBCPP_HAS_NO_THREADS - RLock _(mut()); -#endif + // Read lock + db_guard lk; __i_node* i = __find_iterator(__i); __i_node* j = __find_iterator(__j); __c_node* ci = i != nullptr ? i->__c_ : nullptr; @@ -444,9 +424,8 @@ void __libcpp_db::swap(void* c1, void* c2) { -#ifndef _LIBCPP_HAS_NO_THREADS - WLock _(mut()); -#endif + // Write lock + db_guard lk; size_t hc = hash()(c1) % static_cast(__cend_ - __cbeg_); __c_node* p1 = __cbeg_[hc]; _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A"); @@ -475,9 +454,8 @@ void __libcpp_db::__insert_i(void* __i) { -#ifndef _LIBCPP_HAS_NO_THREADS - WLock _(mut()); -#endif + // Write lock + db_guard lk; __insert_iterator(__i); }