Changes in uspace/lib/c/generic/rcu.c [1433ecda:ab6edb6] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/rcu.c
r1433ecda rab6edb6 82 82 #include <thread.h> 83 83 84 #include "private/fibril.h" 85 84 86 85 87 /** RCU sleeps for RCU_SLEEP_MS before polling an active RCU reader again. */ … … 148 150 149 151 150 static void wait_for_readers(size_t reader_group , blocking_mode_t blocking_mode);152 static void wait_for_readers(size_t reader_group); 151 153 static void force_mb_in_all_threads(void); 152 154 static bool is_preexisting_reader(const fibril_rcu_data_t *fib, size_t group); 153 155 154 static void lock_sync( blocking_mode_t blocking_mode);156 static void lock_sync(void); 155 157 static void unlock_sync(void); 156 static void sync_sleep( blocking_mode_t blocking_mode);158 static void sync_sleep(void); 157 159 158 160 static bool is_in_group(size_t nesting_cnt, size_t group); … … 170 172 assert(!fibril_rcu.registered); 171 173 172 futex_ down(&rcu.list_futex);174 futex_lock(&rcu.list_futex); 173 175 list_append(&fibril_rcu.link, &rcu.fibrils_list); 174 futex_u p(&rcu.list_futex);176 futex_unlock(&rcu.list_futex); 175 177 176 178 fibril_rcu.registered = true; … … 195 197 fibril_rcu.nesting_cnt = 0; 196 198 197 futex_ down(&rcu.list_futex);199 futex_lock(&rcu.list_futex); 198 200 list_remove(&fibril_rcu.link); 199 futex_u p(&rcu.list_futex);201 futex_unlock(&rcu.list_futex); 200 202 201 203 fibril_rcu.registered = false; … … 240 242 241 243 /** Blocks until all preexisting readers exit their critical sections. */ 242 void _rcu_synchronize(blocking_mode_t blocking_mode)244 void rcu_synchronize(void) 243 245 { 244 246 assert(!rcu_read_locked()); … … 250 252 size_t gp_in_progress = ACCESS_ONCE(rcu.cur_gp); 251 253 252 lock_sync( blocking_mode);254 lock_sync(); 253 255 254 256 /* … … 298 300 299 301 size_t new_reader_group = get_other_group(rcu.reader_group); 300 wait_for_readers(new_reader_group , blocking_mode);302 wait_for_readers(new_reader_group); 301 303 302 304 /* Separates waiting for readers in new_reader_group from group flip. */ … … 310 312 memory_barrier(); 311 313 312 wait_for_readers(old_reader_group , blocking_mode);314 wait_for_readers(old_reader_group); 313 315 314 316 /* MB_FORCE_U */ … … 330 332 331 333 /** Waits for readers of reader_group to exit their readers sections. */ 332 static void wait_for_readers(size_t reader_group , blocking_mode_t blocking_mode)333 { 334 futex_ down(&rcu.list_futex);334 static void wait_for_readers(size_t reader_group) 335 { 336 futex_lock(&rcu.list_futex); 335 337 336 338 list_t quiescent_fibrils; … … 343 345 344 346 if (is_preexisting_reader(fib, reader_group)) { 345 futex_u p(&rcu.list_futex);346 sync_sleep( blocking_mode);347 futex_ down(&rcu.list_futex);347 futex_unlock(&rcu.list_futex); 348 sync_sleep(); 349 futex_lock(&rcu.list_futex); 348 350 /* Break to while loop. */ 349 351 break; … … 356 358 357 359 list_concat(&rcu.fibrils_list, &quiescent_fibrils); 358 futex_u p(&rcu.list_futex);359 } 360 361 static void lock_sync( blocking_mode_t blocking_mode)362 { 363 futex_ down(&rcu.sync_lock.futex);360 futex_unlock(&rcu.list_futex); 361 } 362 363 static void lock_sync(void) 364 { 365 futex_lock(&rcu.sync_lock.futex); 364 366 if (rcu.sync_lock.locked) { 365 if (blocking_mode == BM_BLOCK_FIBRIL) { 366 blocked_fibril_t blocked_fib; 367 blocked_fib.id = fibril_get_id(); 368 369 list_append(&blocked_fib.link, &rcu.sync_lock.blocked_fibrils); 370 371 do { 372 blocked_fib.is_ready = false; 373 futex_up(&rcu.sync_lock.futex); 374 fibril_switch(FIBRIL_TO_MANAGER); 375 futex_down(&rcu.sync_lock.futex); 376 } while (rcu.sync_lock.locked); 377 378 list_remove(&blocked_fib.link); 379 rcu.sync_lock.locked = true; 380 } else { 381 assert(blocking_mode == BM_BLOCK_THREAD); 382 rcu.sync_lock.blocked_thread_cnt++; 383 futex_up(&rcu.sync_lock.futex); 384 futex_down(&rcu.sync_lock.futex_blocking_threads); 385 } 367 blocked_fibril_t blocked_fib; 368 blocked_fib.id = fibril_get_id(); 369 370 list_append(&blocked_fib.link, &rcu.sync_lock.blocked_fibrils); 371 372 do { 373 blocked_fib.is_ready = false; 374 futex_unlock(&rcu.sync_lock.futex); 375 futex_lock(&async_futex); 376 fibril_switch(FIBRIL_FROM_BLOCKED); 377 futex_unlock(&async_futex); 378 futex_lock(&rcu.sync_lock.futex); 379 } while (rcu.sync_lock.locked); 380 381 list_remove(&blocked_fib.link); 382 rcu.sync_lock.locked = true; 386 383 } else { 387 384 rcu.sync_lock.locked = true; … … 399 396 if (0 < rcu.sync_lock.blocked_thread_cnt) { 400 397 --rcu.sync_lock.blocked_thread_cnt; 401 futex_u p(&rcu.sync_lock.futex_blocking_threads);398 futex_unlock(&rcu.sync_lock.futex_blocking_threads); 402 399 } else { 403 400 /* Unlock but wake up any fibrils waiting for the lock. */ … … 414 411 415 412 rcu.sync_lock.locked = false; 416 futex_u p(&rcu.sync_lock.futex);413 futex_unlock(&rcu.sync_lock.futex); 417 414 } 418 415 } 419 416 420 static void sync_sleep( blocking_mode_t blocking_mode)417 static void sync_sleep(void) 421 418 { 422 419 assert(rcu.sync_lock.locked); … … 425 422 * but keep sync locked. 426 423 */ 427 futex_up(&rcu.sync_lock.futex); 428 429 if (blocking_mode == BM_BLOCK_FIBRIL) { 430 async_usleep(RCU_SLEEP_MS * 1000); 431 } else { 432 thread_usleep(RCU_SLEEP_MS * 1000); 433 } 434 435 futex_down(&rcu.sync_lock.futex); 424 futex_unlock(&rcu.sync_lock.futex); 425 async_usleep(RCU_SLEEP_MS * 1000); 426 futex_lock(&rcu.sync_lock.futex); 436 427 } 437 428
Note:
See TracChangeset
for help on using the changeset viewer.