6 #ifndef DEFERRED_RWLOCK_HPP 7 #define DEFERRED_RWLOCK_HPP 8 #include <core/parallel/pthread_tools.hpp> 9 #include <core/parallel/queued_rwlock.hpp> 10 #include <core/logging/assertions.hpp> 95 __attribute__((may_alias)) uint64_t id : 62;
101 uint16_t reader_count;
107 tail(NULL), reader_count(0),writer(
false) { }
110 inline size_t get_reader_count() {
111 __sync_synchronize();
116 inline bool has_waiters() {
117 return head != NULL || tail != NULL;
120 inline void insert_queue(request *I) {
130 inline void insert_queue_head(request *I) {
149 I->lockclass = QUEUED_RW_LOCK_REQUEST_WRITE;
151 if (reader_count == 0 && writer ==
false) {
158 insert_queue_head(I);
172 I->lockclass = QUEUED_RW_LOCK_REQUEST_WRITE;
174 if (reader_count == 0 && writer ==
false) {
195 if (head == NULL) tail = NULL;
206 size_t numcompleted = 1;
208 request* readertail = released;
209 while (head != NULL && head->lockclass == QUEUED_RW_LOCK_REQUEST_READ) {
214 reader_count += numcompleted;
215 if (head == NULL) tail = NULL;
225 request* latestwriter = head;
226 request* cur = head->next;
228 if (cur->lockclass == QUEUED_RW_LOCK_REQUEST_WRITE) {
232 readertail->next = cur;
236 latestwriter->next = cur->next;
238 if (cur == tail)
break;
256 if (head->lockclass == QUEUED_RW_LOCK_REQUEST_READ) {
258 if (ret == 2) assert(released->next != NULL);
276 inline size_t readlock(request *I, request* &released) {
280 I->lockclass = QUEUED_RW_LOCK_REQUEST_READ;
283 if (head == NULL && writer ==
false) {
293 if (head->lockclass == QUEUED_RW_LOCK_REQUEST_READ && writer ==
false) {
310 I->lockclass = QUEUED_RW_LOCK_REQUEST_READ;
313 if (head == NULL && writer ==
false) {
322 insert_queue_head(I);
323 if (head->lockclass == QUEUED_RW_LOCK_REQUEST_READ && writer ==
false) {
340 if (reader_count == 0) {
343 if (head->lockclass == QUEUED_RW_LOCK_REQUEST_READ) {
void unlock() const
Releases a lock on the spinlock.
size_t readlock_priority(request *I, request *&released)
bool writelock(request *I)
void lock() const
Acquires a lock on the spinlock.
size_t wrunlock(request *&released)
size_t rdunlock(request *&released)
size_t readlock(request *I, request *&released)
size_t complete_rdlock(request *&released)
bool writelock_priority(request *I)