24 #ifndef DEFERRED_RWLOCK_HPP
25 #define DEFERRED_RWLOCK_HPP
26 #include <graphlab/parallel/pthread_tools.hpp>
27 #include <graphlab/parallel/queued_rwlock.hpp>
28 #include <graphlab/logger/assertions.hpp>
30 class deferred_rwlock{
35 __attribute__((may_alias)) uint64_t
id : 62;
41 uint16_t reader_count;
46 deferred_rwlock(): head(NULL),
47 tail(NULL), reader_count(0),writer(false) { }
50 inline size_t get_reader_count() {
56 inline bool has_waiters() {
57 return head != NULL || tail != NULL;
60 inline void insert_queue(request *I) {
70 inline void insert_queue_head(request *I) {
81 inline bool writelock_priority(request *I) {
83 I->lockclass = QUEUED_RW_LOCK_REQUEST_WRITE;
85 if (reader_count == 0 && writer ==
false) {
98 inline bool writelock(request *I) {
100 I->lockclass = QUEUED_RW_LOCK_REQUEST_WRITE;
102 if (reader_count == 0 && writer ==
false) {
117 inline void complete_wrlock() {
120 if (head == NULL) tail = NULL;
126 inline size_t complete_rdlock(request* &released) {
128 size_t numcompleted = 1;
130 request* readertail = released;
131 while (head != NULL && head->lockclass == QUEUED_RW_LOCK_REQUEST_READ) {
136 reader_count += numcompleted;
137 if (head == NULL) tail = NULL;
147 request* latestwriter = head;
148 request* cur = head->next;
150 if (cur->lockclass == QUEUED_RW_LOCK_REQUEST_WRITE) {
154 readertail->next = cur;
158 latestwriter->next = cur->next;
160 if (cur == tail)
break;
167 inline size_t wrunlock(request* &released) {
173 if (head->lockclass == QUEUED_RW_LOCK_REQUEST_READ) {
174 ret = complete_rdlock(released);
175 if (ret == 2) assert(released->next != NULL);
188 inline size_t readlock(request *I, request* &released) {
192 I->lockclass = QUEUED_RW_LOCK_REQUEST_READ;
195 if (head == NULL && writer ==
false) {
205 if (head->lockclass == QUEUED_RW_LOCK_REQUEST_READ && writer ==
false) {
206 ret = complete_rdlock(released);
213 inline size_t readlock_priority(request *I, request* &released) {
217 I->lockclass = QUEUED_RW_LOCK_REQUEST_READ;
220 if (head == NULL && writer ==
false) {
229 insert_queue_head(I);
230 if (head->lockclass == QUEUED_RW_LOCK_REQUEST_READ && writer ==
false) {
231 ret = complete_rdlock(released);
238 inline size_t rdunlock(request* &released) {
242 if (reader_count == 0) {
245 if (head->lockclass == QUEUED_RW_LOCK_REQUEST_READ) {
246 ret = complete_rdlock(released);