Changeset a35b458 in mainline for uspace/lib/c/generic/rcu.c
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/rcu.c
r3061bc1 ra35b458 169 169 { 170 170 assert(!fibril_rcu.registered); 171 171 172 172 futex_down(&rcu.list_futex); 173 173 list_append(&fibril_rcu.link, &rcu.fibrils_list); 174 174 futex_up(&rcu.list_futex); 175 175 176 176 fibril_rcu.registered = true; 177 177 } … … 185 185 { 186 186 assert(fibril_rcu.registered); 187 187 188 188 /* 189 189 * Forcefully unlock any reader sections. The fibril is exiting … … 194 194 memory_barrier(); 195 195 fibril_rcu.nesting_cnt = 0; 196 196 197 197 futex_down(&rcu.list_futex); 198 198 list_remove(&fibril_rcu.link); … … 209 209 { 210 210 assert(fibril_rcu.registered); 211 211 212 212 size_t nesting_cnt = ACCESS_ONCE(fibril_rcu.nesting_cnt); 213 213 214 214 if (0 == (nesting_cnt >> RCU_NESTING_SHIFT)) { 215 215 ACCESS_ONCE(fibril_rcu.nesting_cnt) = ACCESS_ONCE(rcu.reader_group); … … 226 226 assert(fibril_rcu.registered); 227 227 assert(rcu_read_locked()); 228 228 229 229 /* Required by MB_FORCE_U */ 230 230 compiler_barrier(); /* CC_BAR_U */ … … 243 243 { 244 244 assert(!rcu_read_locked()); 245 245 246 246 /* Contain load of rcu.cur_gp. */ 247 247 memory_barrier(); … … 249 249 /* Approximately the number of the GP in progress. */ 250 250 size_t gp_in_progress = ACCESS_ONCE(rcu.cur_gp); 251 251 252 252 lock_sync(blocking_mode); 253 253 254 254 /* 255 255 * Exit early if we were stuck waiting for the mutex for a full grace … … 264 264 return; 265 265 } 266 266 267 267 ++ACCESS_ONCE(rcu.cur_gp); 268 268 269 269 /* 270 270 * Pairs up with MB_FORCE_L (ie CC_BAR_L). Makes changes prior … … 272 272 */ 273 273 memory_barrier(); /* MB_A */ 274 274 275 275 /* 276 276 * Pairs up with MB_A. … … 290 290 */ 291 291 force_mb_in_all_threads(); /* MB_FORCE_L */ 292 292 293 293 /* 294 294 * Pairs with MB_FORCE_L (ie CC_BAR_L, CC_BAR_U) and makes the most … … 296 296 */ 297 297 read_barrier(); /* MB_B */ 298 298 299 299 size_t new_reader_group = get_other_group(rcu.reader_group); 300 300 wait_for_readers(new_reader_group, blocking_mode); 301 301 302 302 /* Separates waiting for readers in new_reader_group from group flip. */ 303 303 memory_barrier(); 304 304 305 305 /* Flip the group new readers should associate with. */ 306 306 size_t old_reader_group = rcu.reader_group; … … 309 309 /* Flip the group before waiting for preexisting readers in the old group.*/ 310 310 memory_barrier(); 311 311 312 312 wait_for_readers(old_reader_group, blocking_mode); 313 313 314 314 /* MB_FORCE_U */ 315 315 force_mb_in_all_threads(); /* MB_FORCE_U */ 316 316 317 317 unlock_sync(); 318 318 } … … 333 333 { 334 334 futex_down(&rcu.list_futex); 335 335 336 336 list_t quiescent_fibrils; 337 337 list_initialize(&quiescent_fibrils); 338 338 339 339 while (!list_empty(&rcu.fibrils_list)) { 340 340 list_foreach_safe(rcu.fibrils_list, fibril_it, next_fibril) { 341 341 fibril_rcu_data_t *fib = member_to_inst(fibril_it, 342 342 fibril_rcu_data_t, link); 343 343 344 344 if (is_preexisting_reader(fib, reader_group)) { 345 345 futex_up(&rcu.list_futex); … … 354 354 } 355 355 } 356 356 357 357 list_concat(&rcu.fibrils_list, &quiescent_fibrils); 358 358 futex_up(&rcu.list_futex); … … 366 366 blocked_fibril_t blocked_fib; 367 367 blocked_fib.id = fibril_get_id(); 368 368 369 369 list_append(&blocked_fib.link, &rcu.sync_lock.blocked_fibrils); 370 370 371 371 do { 372 372 blocked_fib.is_ready = false; … … 375 375 futex_down(&rcu.sync_lock.futex); 376 376 } while (rcu.sync_lock.locked); 377 377 378 378 list_remove(&blocked_fib.link); 379 379 rcu.sync_lock.locked = true; … … 392 392 { 393 393 assert(rcu.sync_lock.locked); 394 394 395 395 /* 396 396 * Blocked threads have a priority over fibrils when accessing sync(). … … 402 402 } else { 403 403 /* Unlock but wake up any fibrils waiting for the lock. */ 404 404 405 405 if (!list_empty(&rcu.sync_lock.blocked_fibrils)) { 406 406 blocked_fibril_t *blocked_fib = member_to_inst( 407 407 list_first(&rcu.sync_lock.blocked_fibrils), blocked_fibril_t, link); 408 408 409 409 if (!blocked_fib->is_ready) { 410 410 blocked_fib->is_ready = true; … … 412 412 } 413 413 } 414 414 415 415 rcu.sync_lock.locked = false; 416 416 futex_up(&rcu.sync_lock.futex); … … 432 432 thread_usleep(RCU_SLEEP_MS * 1000); 433 433 } 434 434 435 435 futex_down(&rcu.sync_lock.futex); 436 436 } … … 440 440 { 441 441 size_t nesting_cnt = ACCESS_ONCE(fib->nesting_cnt); 442 442 443 443 return is_in_group(nesting_cnt, group) && is_in_reader_section(nesting_cnt); 444 444 }
Note:
See TracChangeset
for help on using the changeset viewer.