| 159 | } |
| 160 | |
| 161 | void reader_writer_lock::set_next_writer(scoped_lock *W) { |
| 162 | writer_head = W; |
| 163 | if (W->status == waiting_nonblocking) { |
| 164 | if (rdr_count_and_flags.compare_and_swap(WFLAG1+WFLAG2, 0) == 0) { |
| 165 | W->status = active; |
| 166 | } |
| 167 | } |
| 168 | else { |
| 169 | if (fetch_and_or(rdr_count_and_flags, WFLAG1) & RFLAG) { // reader present |
| 170 | spin_wait_until_and(rdr_count_and_flags, WFLAG2); // block until readers set WFLAG2 |
| 171 | } |
| 172 | else { // no reader in timing window |
| 173 | __TBB_AtomicOR(&rdr_count_and_flags, WFLAG2); |
| 174 | } |
| 175 | spin_wait_while_geq(rdr_count_and_flags, RC_INCR); // block until readers finish |
| 176 | W->status = active; |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | // Acquires the reader_writer_lock for read. If the lock is currently held by a writer, |
| 181 | // this reader will block and wait until the writers are done. |
nothing calls this directly
no test coverage detected