Changeset 3679f51a in mainline
- Timestamp:
- 2018-06-25T20:41:09Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 95838f1
- Parents:
- d73d992
- git-author:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-25 20:30:35)
- git-committer:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-25 20:41:09)
- Location:
- uspace/lib/c
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril.c
rd73d992 r3679f51a 51 51 #include "private/fibril.h" 52 52 53 #ifdef FUTEX_UPGRADABLE54 #include <rcu.h>55 #endif56 53 57 54 /** … … 78 75 79 76 fibril_t *fibril = fibril_self(); 80 81 #ifdef FUTEX_UPGRADABLE82 rcu_register_fibril();83 #endif84 77 85 78 /* Call the implementing function. */ … … 203 196 break; 204 197 } 205 206 #ifdef FUTEX_UPGRADABLE207 if (stype == FIBRIL_FROM_DEAD) {208 rcu_deregister_fibril();209 }210 #endif211 198 212 199 /* Swap to the next fibril. */ -
uspace/lib/c/generic/futex.c
rd73d992 r3679f51a 47 47 } 48 48 49 50 #ifdef FUTEX_UPGRADABLE51 52 int _upgrade_futexes = 0;53 static futex_t upg_and_wait_futex = FUTEX_INITIALIZER;54 55 void futex_upgrade_all_and_wait(void)56 {57 futex_down(&upg_and_wait_futex);58 59 if (!_upgrade_futexes) {60 rcu_assign(_upgrade_futexes, 1);61 _rcu_synchronize(BM_BLOCK_THREAD);62 }63 64 futex_up(&upg_and_wait_futex);65 }66 67 #endif68 69 49 /** @} 70 50 */ -
uspace/lib/c/generic/libc.c
rd73d992 r3679f51a 57 57 #include "private/fibril.h" 58 58 59 #ifdef FUTEX_UPGRADABLE60 #include <rcu.h>61 #endif62 63 59 #ifdef CONFIG_RTLD 64 60 #include <rtld/rtld.h> … … 90 86 91 87 __tcb_set(fibril->tcb); 92 93 94 #ifdef FUTEX_UPGRADABLE95 rcu_register_fibril();96 #endif97 88 98 89 __async_server_init(); -
uspace/lib/c/generic/rcu.c
rd73d992 r3679f51a 150 150 151 151 152 static void wait_for_readers(size_t reader_group , blocking_mode_t blocking_mode);152 static void wait_for_readers(size_t reader_group); 153 153 static void force_mb_in_all_threads(void); 154 154 static bool is_preexisting_reader(const fibril_rcu_data_t *fib, size_t group); 155 155 156 static void lock_sync( blocking_mode_t blocking_mode);156 static void lock_sync(void); 157 157 static void unlock_sync(void); 158 static void sync_sleep( blocking_mode_t blocking_mode);158 static void sync_sleep(void); 159 159 160 160 static bool is_in_group(size_t nesting_cnt, size_t group); … … 242 242 243 243 /** Blocks until all preexisting readers exit their critical sections. */ 244 void _rcu_synchronize(blocking_mode_t blocking_mode)244 void rcu_synchronize(void) 245 245 { 246 246 assert(!rcu_read_locked()); … … 252 252 size_t gp_in_progress = ACCESS_ONCE(rcu.cur_gp); 253 253 254 lock_sync( blocking_mode);254 lock_sync(); 255 255 256 256 /* … … 300 300 301 301 size_t new_reader_group = get_other_group(rcu.reader_group); 302 wait_for_readers(new_reader_group , blocking_mode);302 wait_for_readers(new_reader_group); 303 303 304 304 /* Separates waiting for readers in new_reader_group from group flip. */ … … 312 312 memory_barrier(); 313 313 314 wait_for_readers(old_reader_group , blocking_mode);314 wait_for_readers(old_reader_group); 315 315 316 316 /* MB_FORCE_U */ … … 332 332 333 333 /** Waits for readers of reader_group to exit their readers sections. */ 334 static void wait_for_readers(size_t reader_group , blocking_mode_t blocking_mode)334 static void wait_for_readers(size_t reader_group) 335 335 { 336 336 futex_down(&rcu.list_futex); … … 346 346 if (is_preexisting_reader(fib, reader_group)) { 347 347 futex_up(&rcu.list_futex); 348 sync_sleep( blocking_mode);348 sync_sleep(); 349 349 futex_down(&rcu.list_futex); 350 350 /* Break to while loop. */ … … 361 361 } 362 362 363 static void lock_sync( blocking_mode_t blocking_mode)363 static void lock_sync(void) 364 364 { 365 365 futex_down(&rcu.sync_lock.futex); 366 366 if (rcu.sync_lock.locked) { 367 if (blocking_mode == BM_BLOCK_FIBRIL) { 368 blocked_fibril_t blocked_fib; 369 blocked_fib.id = fibril_get_id(); 370 371 list_append(&blocked_fib.link, &rcu.sync_lock.blocked_fibrils); 372 373 do { 374 blocked_fib.is_ready = false; 375 futex_up(&rcu.sync_lock.futex); 376 fibril_switch(FIBRIL_TO_MANAGER); 377 futex_down(&rcu.sync_lock.futex); 378 } while (rcu.sync_lock.locked); 379 380 list_remove(&blocked_fib.link); 381 rcu.sync_lock.locked = true; 382 } else { 383 assert(blocking_mode == BM_BLOCK_THREAD); 384 rcu.sync_lock.blocked_thread_cnt++; 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; 385 374 futex_up(&rcu.sync_lock.futex); 386 futex_down(&rcu.sync_lock.futex_blocking_threads); 387 } 375 fibril_switch(FIBRIL_TO_MANAGER); 376 futex_down(&rcu.sync_lock.futex); 377 } while (rcu.sync_lock.locked); 378 379 list_remove(&blocked_fib.link); 380 rcu.sync_lock.locked = true; 388 381 } else { 389 382 rcu.sync_lock.locked = true; … … 420 413 } 421 414 422 static void sync_sleep( blocking_mode_t blocking_mode)415 static void sync_sleep(void) 423 416 { 424 417 assert(rcu.sync_lock.locked); … … 428 421 */ 429 422 futex_up(&rcu.sync_lock.futex); 430 431 if (blocking_mode == BM_BLOCK_FIBRIL) { 432 async_usleep(RCU_SLEEP_MS * 1000); 433 } else { 434 thread_usleep(RCU_SLEEP_MS * 1000); 435 } 436 423 async_usleep(RCU_SLEEP_MS * 1000); 437 424 futex_down(&rcu.sync_lock.futex); 438 425 } -
uspace/lib/c/generic/thread.c
rd73d992 r3679f51a 48 48 #include "private/fibril.h" 49 49 50 #ifdef FUTEX_UPGRADABLE51 #include <rcu.h>52 #endif53 54 55 50 /** Main thread function. 56 51 * … … 69 64 70 65 __tcb_set(fibril->tcb); 71 72 #ifdef FUTEX_UPGRADABLE73 rcu_register_fibril();74 futex_upgrade_all_and_wait();75 #endif76 66 77 67 uarg->uspace_thread_function(uarg->uspace_thread_arg); … … 85 75 /* If there is a manager, destroy it */ 86 76 async_destroy_manager(); 87 88 #ifdef FUTEX_UPGRADABLE89 rcu_deregister_fibril();90 #endif91 77 92 78 fibril_teardown(fibril, false); -
uspace/lib/c/include/futex.h
rd73d992 r3679f51a 42 42 typedef struct futex { 43 43 atomic_t val; 44 #ifdef FUTEX_UPGRADABLE45 int upgraded;46 #endif47 44 } futex_t; 48 49 45 50 46 extern void futex_initialize(futex_t *futex, int value); 51 47 52 #ifdef FUTEX_UPGRADABLE53 #include <rcu.h>54 55 #define FUTEX_INITIALIZE(val) {{ (val) }, 0}56 57 #define futex_lock(fut) \58 ({ \59 rcu_read_lock(); \60 (fut)->upgraded = rcu_access(_upgrade_futexes); \61 if ((fut)->upgraded) \62 (void) futex_down((fut)); \63 })64 65 #define futex_trylock(fut) \66 ({ \67 rcu_read_lock(); \68 int _upgraded = rcu_access(_upgrade_futexes); \69 if (_upgraded) { \70 int _acquired = futex_trydown((fut)); \71 if (!_acquired) { \72 rcu_read_unlock(); \73 } else { \74 (fut)->upgraded = true; \75 } \76 _acquired; \77 } else { \78 (fut)->upgraded = false; \79 1; \80 } \81 })82 83 #define futex_unlock(fut) \84 ({ \85 if ((fut)->upgraded) \86 (void) futex_up((fut)); \87 rcu_read_unlock(); \88 })89 90 extern int _upgrade_futexes;91 92 extern void futex_upgrade_all_and_wait(void);93 94 #else95 96 48 #define FUTEX_INITIALIZE(val) {{ (val) }} 49 #define FUTEX_INITIALIZER FUTEX_INITIALIZE(1) 97 50 98 51 #define futex_lock(fut) (void) futex_down((fut)) 99 52 #define futex_trylock(fut) futex_trydown((fut)) 100 53 #define futex_unlock(fut) (void) futex_up((fut)) 101 102 #endif103 104 #define FUTEX_INITIALIZER FUTEX_INITIALIZE(1)105 54 106 55 /** Try to down the futex. -
uspace/lib/c/include/rcu.h
rd73d992 r3679f51a 92 92 #define rcu_access(ptr) ACCESS_ONCE(ptr) 93 93 94 typedef enum blocking_mode {95 BM_BLOCK_FIBRIL,96 BM_BLOCK_THREAD97 } blocking_mode_t;98 99 94 extern void rcu_register_fibril(void); 100 95 extern void rcu_deregister_fibril(void); … … 105 100 extern bool rcu_read_locked(void); 106 101 107 #define rcu_synchronize() _rcu_synchronize(BM_BLOCK_FIBRIL) 108 109 extern void _rcu_synchronize(blocking_mode_t); 102 extern void rcu_synchronize(void); 110 103 111 104 #endif
Note:
See TracChangeset
for help on using the changeset viewer.