| 211 | } |
| 212 | |
| 213 | void reader_writer_lock::start_read(scoped_lock_read *I) { |
| 214 | ITT_NOTIFY(sync_prepare, this); |
| 215 | I->next = reader_head.fetch_and_store(I); |
| 216 | if (!I->next) { // first arriving reader in my group; set RFLAG, test writer flags |
| 217 | // unblock and/or update statuses of non-blocking readers |
| 218 | if (!(fetch_and_or(rdr_count_and_flags, RFLAG) & (WFLAG1+WFLAG2))) { // no writers |
| 219 | unblock_readers(); |
| 220 | } |
| 221 | } |
| 222 | __TBB_ASSERT(I->status == waiting || I->status == active, "Lock requests should be waiting or active before blocking."); |
| 223 | spin_wait_while_eq(I->status, waiting); // block |
| 224 | if (I->next) { |
| 225 | __TBB_ASSERT(I->next->status == waiting, NULL); |
| 226 | rdr_count_and_flags += RC_INCR; |
| 227 | I->next->status = active; // wake successor |
| 228 | } |
| 229 | ITT_NOTIFY(sync_acquired, this); |
| 230 | } |
| 231 | |
| 232 | void reader_writer_lock::unblock_readers() { |
| 233 | // clear rdr interest flag, increment rdr count |
no test coverage detected