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