Skip to content

Commit

Permalink
Use C++ standard names for shared lock operations
Browse files Browse the repository at this point in the history
the SharedLockable requirements. This _should_ let us use
std::shared_lock and stuff, but I haven't worked that out just yet.
  • Loading branch information
Bike committed Dec 7, 2024
1 parent fd84053 commit 508426e
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 32 deletions.
43 changes: 32 additions & 11 deletions include/clasp/core/mpPackage.fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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();
Expand All @@ -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

Expand All @@ -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++;
Expand All @@ -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--;
Expand All @@ -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);
Expand Down
15 changes: 7 additions & 8 deletions include/clasp/core/mpPackage.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,13 @@ class SharedMutex_O : public core::CxxObject_O {
SharedMutex_O(core::T_sp readName, core::T_sp writeName = nil<core::T_O>())
: _Name(readName), _Owner(nil<T_O>()),
_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;

Expand Down
8 changes: 4 additions & 4 deletions src/core/hashTable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,25 +160,25 @@ 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();
}
}
};
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();
}
}
};
Expand Down
10 changes: 5 additions & 5 deletions src/core/mpPackage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions src/gctools/gcweak.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,25 @@ 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();
}
}
};
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();
}
}
};
Expand Down

0 comments on commit 508426e

Please sign in to comment.