Skip to content

Commit

Permalink
support SharedMutex.
Browse files Browse the repository at this point in the history
  • Loading branch information
liyichao committed Oct 30, 2022
1 parent 123be90 commit 3a2ceb4
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/bthread/shared_mutex.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "shared_mutex.h"
namespace bthread {
SharedMutex::SharedMutex(): _reader_count(0), _reader_wait(0) {
_writer_butex = butex_create();
_reader_butex = butex_create();
}

void SharedMutex::lock_shared() {
if (_reader_count.fetch_add(1) < 0) {
butex_wait(_reader_butex, _reader_butex, nullptr);
}
}

void SharedMutex::unlock_shared() {
int32_t r = _reader_count.fetch_add(-1);
if (r < 0) {
runlock_slow(r);
}
}

void SharedMutex::unlock_shared_slow(r int32) {
if (r == 0 || r == -max_readers) {
throw std::system_error(std::errc::operation_not_permitted, "unlock of unlocked SharedMutex");
}
if (_reader_wait.fetch_add(-1) == 1) {
butex_wake(_writer_butex);
}
}

void SharedMutex::lock() {
_w.lock();
int32_t r = _reader_count.fetch_add(-max_readers);
if (r != 0 && _reader_wait.fetch_add(r) + r != 0) {
butex_wait(_writer_butex);
}
}

void SharedMutex::unlock() {
int32_t r = _reader_count.fetch_add(max_readers);
for(int32_t i = 0; i < r; i++) {
butex_wake(_reader_butex);
}
_w.unlock();
}



30 changes: 30 additions & 0 deletions src/bthread/shared_mutex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef BTHREAD_SHARED_MUTEX_H
#define BTHREAD_SHARED_MUTEX_H
#include "mutex.h"

namespace bthread {

// compatible with c++17 std::shared_mutex, migration from golang
// see https://github.com/golang/go/blob/master/src/sync/rwmutex.go
class SharedMutex {
public:
SharedMutex();
void lock_shared();
void unlock_shared();
void lock();
void unlock();

private:
DISALLOW_COPY_AND_ASSIGN(SharedMutex);
void unlock_shared_slow(r int32);

static constexpr int32_t max_readers = 1 << 30;
Mutex _w;
void* _writer_butex;
void* _reader_butex;
butil::atomic<int32_t> _reader_count;
butil::atomic<int32_t> _reader_wait;
};
}

#endif //BTHREAD_SHARED_MUTEX_H

0 comments on commit 3a2ceb4

Please sign in to comment.