Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/rcu.c

    r1433ecda rab6edb6  
    8282#include <thread.h>
    8383
     84#include "private/fibril.h"
     85
    8486
    8587/** RCU sleeps for RCU_SLEEP_MS before polling an active RCU reader again. */
     
    148150
    149151
    150 static void wait_for_readers(size_t reader_group, blocking_mode_t blocking_mode);
     152static void wait_for_readers(size_t reader_group);
    151153static void force_mb_in_all_threads(void);
    152154static bool is_preexisting_reader(const fibril_rcu_data_t *fib, size_t group);
    153155
    154 static void lock_sync(blocking_mode_t blocking_mode);
     156static void lock_sync(void);
    155157static void unlock_sync(void);
    156 static void sync_sleep(blocking_mode_t blocking_mode);
     158static void sync_sleep(void);
    157159
    158160static bool is_in_group(size_t nesting_cnt, size_t group);
     
    170172        assert(!fibril_rcu.registered);
    171173
    172         futex_down(&rcu.list_futex);
     174        futex_lock(&rcu.list_futex);
    173175        list_append(&fibril_rcu.link, &rcu.fibrils_list);
    174         futex_up(&rcu.list_futex);
     176        futex_unlock(&rcu.list_futex);
    175177
    176178        fibril_rcu.registered = true;
     
    195197        fibril_rcu.nesting_cnt = 0;
    196198
    197         futex_down(&rcu.list_futex);
     199        futex_lock(&rcu.list_futex);
    198200        list_remove(&fibril_rcu.link);
    199         futex_up(&rcu.list_futex);
     201        futex_unlock(&rcu.list_futex);
    200202
    201203        fibril_rcu.registered = false;
     
    240242
    241243/** Blocks until all preexisting readers exit their critical sections. */
    242 void _rcu_synchronize(blocking_mode_t blocking_mode)
     244void rcu_synchronize(void)
    243245{
    244246        assert(!rcu_read_locked());
     
    250252        size_t gp_in_progress = ACCESS_ONCE(rcu.cur_gp);
    251253
    252         lock_sync(blocking_mode);
     254        lock_sync();
    253255
    254256        /*
     
    298300
    299301        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);
    301303
    302304        /* Separates waiting for readers in new_reader_group from group flip. */
     
    310312        memory_barrier();
    311313
    312         wait_for_readers(old_reader_group, blocking_mode);
     314        wait_for_readers(old_reader_group);
    313315
    314316        /* MB_FORCE_U  */
     
    330332
    331333/** 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);
     334static void wait_for_readers(size_t reader_group)
     335{
     336        futex_lock(&rcu.list_futex);
    335337
    336338        list_t quiescent_fibrils;
     
    343345
    344346                        if (is_preexisting_reader(fib, reader_group)) {
    345                                 futex_up(&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);
    348350                                /* Break to while loop. */
    349351                                break;
     
    356358
    357359        list_concat(&rcu.fibrils_list, &quiescent_fibrils);
    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);
     360        futex_unlock(&rcu.list_futex);
     361}
     362
     363static void lock_sync(void)
     364{
     365        futex_lock(&rcu.sync_lock.futex);
    364366        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;
    386383        } else {
    387384                rcu.sync_lock.locked = true;
     
    399396        if (0 < rcu.sync_lock.blocked_thread_cnt) {
    400397                --rcu.sync_lock.blocked_thread_cnt;
    401                 futex_up(&rcu.sync_lock.futex_blocking_threads);
     398                futex_unlock(&rcu.sync_lock.futex_blocking_threads);
    402399        } else {
    403400                /* Unlock but wake up any fibrils waiting for the lock. */
     
    414411
    415412                rcu.sync_lock.locked = false;
    416                 futex_up(&rcu.sync_lock.futex);
     413                futex_unlock(&rcu.sync_lock.futex);
    417414        }
    418415}
    419416
    420 static void sync_sleep(blocking_mode_t blocking_mode)
     417static void sync_sleep(void)
    421418{
    422419        assert(rcu.sync_lock.locked);
     
    425422         * but keep sync locked.
    426423         */
    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);
    436427}
    437428
Note: See TracChangeset for help on using the changeset viewer.