From 508426ec50d1feb710ba0a12e2dd60483f360244 Mon Sep 17 00:00:00 2001 From: Bike Date: Sat, 7 Dec 2024 09:18:39 -0500 Subject: [PATCH] Use C++ standard names for shared lock operations the SharedLockable requirements. This _should_ let us use std::shared_lock and stuff, but I haven't worked that out just yet. --- include/clasp/core/mpPackage.fwd.h | 43 ++++++++++++++++++++++-------- include/clasp/core/mpPackage.h | 15 +++++------ src/core/hashTable.cc | 8 +++--- src/core/mpPackage.cc | 10 +++---- src/gctools/gcweak.cc | 8 +++--- 5 files changed, 52 insertions(+), 32 deletions(-) diff --git a/include/clasp/core/mpPackage.fwd.h b/include/clasp/core/mpPackage.fwd.h index cfaedadb7b..f46c7b35cf 100644 --- a/include/clasp/core/mpPackage.fwd.h +++ b/include/clasp/core/mpPackage.fwd.h @@ -354,6 +354,7 @@ struct Mutex { } return pthread_mutex_trylock(&this->_Mutex) == 0; }; + bool try_lock() { return lock(false); } // for C++ Lockable void unlock() { #ifdef DEBUG_THREADS debug_mutex_unlock(this); @@ -372,13 +373,24 @@ struct SharedMutex { size_t _b; SharedMutex(uint64_t nameword) : _r(nameword,false), _g(nameword,false), _b(0) {}; // shared access - void shared_lock() { + void lock_shared() { this->_r.lock(true); ++this->_b; if (this->_b==256) this->_g.lock(true); this->_r.unlock(); } - void shared_unlock() { + bool try_lock_shared() { + if (this->_r.try_lock()) { + if (this->_b>=255) { + this->_r.unlock(); + return false; + } else { + ++this->_b; + return true; + } + } else return false; + } + void unlock_shared() { this->_r.lock(true); --this->_b; if (this->_b==0) this->_g.unlock(); @@ -397,9 +409,6 @@ struct SharedMutex : public sf::contention_free_shared_mutex<> { SharedMutex(){}; uint64_t _r; SharedMutex(uint64_t nameword) : _r(nameword){}; - // shared access - void shared_lock() { this->lock_shared(); } - void shared_unlock() { this->unlock_shared(); } }; #endif @@ -423,8 +432,8 @@ class UpgradableSharedMutex { UpgradableSharedMutex(uint64_t nameword, uint maxReaders = 64, uint64_t writenameword = 0) : mReadMutex(nameword), mWriteMutex(writenameword ? writenameword : nameword), mReadsBlocked(false), mMaxReaders(maxReaders), mReaders(0){}; - void readLock() { - while (1) { + void lock_shared() { + while (true) { mReadMutex._value.lock(); if ((!mReadsBlocked) && (mReaders < mMaxReaders)) { mReaders++; @@ -436,7 +445,19 @@ class UpgradableSharedMutex { } assert(0); }; - void readUnlock() { + bool try_lock_shared() { + if (mReadMutex._value.try_lock()) { + if ((!mReadsBlocked) && (mReaders < mMaxReaders)) { + mReaders++; + mReadMutex._value.unlock(); + return true; + } else { + mReadMutex._value.unlock(); + return false; + } + } else return false; + } + void unlock_shared() { mReadMutex._value.lock(); assert(mReaders); mReaders--; @@ -447,19 +468,19 @@ class UpgradableSharedMutex { Be careful though!!!! If two threads try to upgrade at the same time there will be a deadlock unless they do it in a loop using withTryLock(true). */ - bool writeTryLock(bool upgrade = false) { + bool try_lock(bool upgrade = false) { if (!mWriteMutex._value.lock(false)) return false; waitReaders(upgrade ? 1 : 0); return true; } - void writeLock(bool upgrade = false) { + void lock(bool upgrade = false) { mWriteMutex._value.lock(); waitReaders(upgrade ? 1 : 0); } /*! Pass true releaseReadLock if when you release the write lock it also releases the read lock */ - void writeUnlock(bool releaseReadLock = false) { + void unlock(bool releaseReadLock = false) { mReadMutex._value.lock(); if (releaseReadLock) { assert(mReaders <= 1); diff --git a/include/clasp/core/mpPackage.h b/include/clasp/core/mpPackage.h index d1a0ceb68d..b482ec8c26 100644 --- a/include/clasp/core/mpPackage.h +++ b/include/clasp/core/mpPackage.h @@ -227,14 +227,13 @@ class SharedMutex_O : public core::CxxObject_O { SharedMutex_O(core::T_sp readName, core::T_sp writeName = nil()) : _Name(readName), _Owner(nil()), _SharedMutex(lisp_nameword(readName), 256, writeName.nilp() ? lisp_nameword(readName) : lisp_nameword(writeName)){}; - void write_lock(bool upgrade = false) { this->_SharedMutex.writeLock(upgrade); }; - bool write_try_lock(bool upgrade = false) { return this->_SharedMutex.writeTryLock(upgrade); }; - void write_unlock(bool release_read_lock = false) { this->_SharedMutex.writeUnlock(release_read_lock); }; - - void read_lock() { this->_SharedMutex.readLock(); }; - void read_unlock() { this->_SharedMutex.readUnlock(); }; - void shared_lock() { this->_SharedMutex.readLock(); }; - void shared_unlock() { this->_SharedMutex.readUnlock(); }; + void lock(bool upgrade = false) { this->_SharedMutex.lock(upgrade); }; + bool try_lock(bool upgrade = false) { return this->_SharedMutex.try_lock(upgrade); }; + void unlock(bool release_read_lock = false) { this->_SharedMutex.unlock(release_read_lock); }; + + void lock_shared() { this->_SharedMutex.lock_shared(); }; + bool try_lock_shared() { return this->_SharedMutex.try_lock_shared(); } + void unlock_shared() { this->_SharedMutex.unlock_shared(); }; void setLockNames(core::SimpleBaseString_sp readLockName, core::SimpleBaseString_sp writeLockName); string __repr__() const override; diff --git a/src/core/hashTable.cc b/src/core/hashTable.cc index 366fb6f8e7..4ee39679fc 100644 --- a/src/core/hashTable.cc +++ b/src/core/hashTable.cc @@ -160,12 +160,12 @@ struct HashTableReadLock { const HashTable_O* _hashTable; HashTableReadLock(const HashTable_O* ht) : _hashTable(ht) { if (this->_hashTable->_Mutex) { - this->_hashTable->_Mutex->shared_lock(); + this->_hashTable->_Mutex->lock_shared(); } } ~HashTableReadLock() { if (this->_hashTable->_Mutex) { - this->_hashTable->_Mutex->shared_unlock(); + this->_hashTable->_Mutex->unlock_shared(); } } }; @@ -173,12 +173,12 @@ struct HashTableWriteLock { const HashTable_O* _hashTable; HashTableWriteLock(const HashTable_O* ht, bool upgrade = false) : _hashTable(ht) { if (this->_hashTable->_Mutex) { - this->_hashTable->_Mutex->write_lock(upgrade); + this->_hashTable->_Mutex->lock(upgrade); } } ~HashTableWriteLock() { if (this->_hashTable->_Mutex) { - this->_hashTable->_Mutex->write_unlock(); + this->_hashTable->_Mutex->unlock(); } } }; diff --git a/src/core/mpPackage.cc b/src/core/mpPackage.cc index 411d60f8c7..94ad1ea466 100644 --- a/src/core/mpPackage.cc +++ b/src/core/mpPackage.cc @@ -224,29 +224,29 @@ CL_LAMBDA(mutex &optional (upgrade nil)); CL_DOCSTRING( R"dx(Obtain the write lock for this mutex. upgradep should be true if and only if this thread currently holds the shared lock for the same mutex.)dx"); DOCGROUP(clasp); -CL_DEFUN void mp__write_lock(SharedMutex_sp m, bool upgrade) { m->write_lock(upgrade); } +CL_DEFUN void mp__write_lock(SharedMutex_sp m, bool upgrade) { m->lock(upgrade); } CL_LAMBDA(mutex &optional (upgrade nil)); CL_DOCSTRING( R"dx(Try to obtain the write lock for this mutex. If it cannot be obtained immediately, return false. Otherwise, return true.)dx"); DOCGROUP(clasp); -CL_DEFUN bool mp__write_try_lock(SharedMutex_sp m, bool upgrade) { return m->write_try_lock(upgrade); } +CL_DEFUN bool mp__write_try_lock(SharedMutex_sp m, bool upgrade) { return m->try_lock(upgrade); } CL_LAMBDA(mutex &optional (release_read_lock nil)); CL_DOCSTRING( R"dx(Release the write lock. If releasep is true and the current thread holds the shared lock, it is released as well.)dx"); DOCGROUP(clasp); -CL_DEFUN void mp__write_unlock(SharedMutex_sp m, bool release_read_lock) { m->write_unlock(release_read_lock); } +CL_DEFUN void mp__write_unlock(SharedMutex_sp m, bool release_read_lock) { m->unlock(release_read_lock); } CL_LAMBDA(mutex); CL_DOCSTRING(R"dx(Obtain the shared lock for this mutex.)dx"); DOCGROUP(clasp); -CL_DEFUN void mp__shared_lock(SharedMutex_sp m) { m->read_lock(); } +CL_DEFUN void mp__shared_lock(SharedMutex_sp m) { m->lock_shared(); } CL_LAMBDA(mutex); CL_DOCSTRING(R"dx(Release the shared lock for this mutex.)dx"); DOCGROUP(clasp); -CL_DEFUN void mp__shared_unlock(SharedMutex_sp m) { m->read_unlock(); } +CL_DEFUN void mp__shared_unlock(SharedMutex_sp m) { m->unlock_shared(); } void SharedMutex_O::setLockNames(core::SimpleBaseString_sp readLockName, core::SimpleBaseString_sp writeLockName) { this->_SharedMutex.mReadMutex._value._NameWord = lisp_nameword(readLockName); diff --git a/src/gctools/gcweak.cc b/src/gctools/gcweak.cc index 36ea7c145a..fca1f72fd5 100644 --- a/src/gctools/gcweak.cc +++ b/src/gctools/gcweak.cc @@ -45,12 +45,12 @@ struct WeakKeyHashTableReadLock { const WeakKeyHashTable* _hashTable; WeakKeyHashTableReadLock(const WeakKeyHashTable* ht) : _hashTable(ht) { if (this->_hashTable->_Mutex) { - this->_hashTable->_Mutex->shared_lock(); + this->_hashTable->_Mutex->lock_shared(); } } ~WeakKeyHashTableReadLock() { if (this->_hashTable->_Mutex) { - this->_hashTable->_Mutex->shared_unlock(); + this->_hashTable->_Mutex->unlock_shared(); } } }; @@ -58,12 +58,12 @@ struct WeakKeyHashTableWriteLock { const WeakKeyHashTable* _hashTable; WeakKeyHashTableWriteLock(const WeakKeyHashTable* ht, bool upgrade = false) : _hashTable(ht) { if (this->_hashTable->_Mutex) { - this->_hashTable->_Mutex->write_lock(upgrade); + this->_hashTable->_Mutex->lock(upgrade); } } ~WeakKeyHashTableWriteLock() { if (this->_hashTable->_Mutex) { - this->_hashTable->_Mutex->write_unlock(); + this->_hashTable->_Mutex->unlock(); } } };