Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/synch/rcu.c

    r1b20da0 ra35b458  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28  
    29  
     28
     29
    3030/** @addtogroup sync
    3131 * @{
     
    182182         */
    183183        rcu_gp_t completed_gp;
    184        
     184
    185185        /** Protects the following 3 fields. */
    186186        IRQ_SPINLOCK_DECLARE(preempt_lock);
     
    195195         */
    196196        bool preempt_blocking_det;
    197        
     197
    198198#ifdef RCU_PREEMPT_A
    199        
     199
    200200        /**
    201201         * The detector waits on this semaphore for any preempted readers
     
    205205
    206206#elif defined(RCU_PREEMPT_PODZIMEK)
    207        
     207
    208208        /** Reclaimers notify the detector when they request more grace periods.*/
    209209        condvar_t req_gp_changed;
     
    228228        semaphore_t remaining_readers;
    229229#endif
    230        
     230
    231231        /** Excludes simultaneous rcu_barrier() calls. */
    232232        mutex_t barrier_mtx;
     
    235235        /** rcu_barrier() waits for the completion of barrier callbacks on this wq.*/
    236236        waitq_t barrier_wq;
    237        
     237
    238238        /** Interruptible attached detector thread pointer. */
    239239        thread_t *detector_thr;
    240        
     240
    241241        /* Some statistics. */
    242242        size_t stat_expedited_cnt;
     
    305305        _rcu_cur_gp = 0;
    306306        rcu.completed_gp = 0;
    307        
     307
    308308        irq_spinlock_initialize(&rcu.preempt_lock, "rcu.preempt_lock");
    309309        list_initialize(&rcu.cur_preempted);
    310310        list_initialize(&rcu.next_preempted);
    311311        rcu.preempt_blocking_det = false;
    312        
     312
    313313        mutex_initialize(&rcu.barrier_mtx, MUTEX_PASSIVE);
    314314        atomic_set(&rcu.barrier_wait_cnt, 0);
     
    316316
    317317        semaphore_initialize(&rcu.remaining_readers, 0);
    318        
     318
    319319#ifdef RCU_PREEMPT_PODZIMEK
    320320        condvar_initialize(&rcu.req_gp_changed);
    321        
     321
    322322        rcu.req_gp_end_cnt = 0;
    323323        rcu.req_expedited_cnt = 0;
    324324        atomic_set(&rcu.delaying_cpu_cnt, 0);
    325325#endif
    326        
     326
    327327        rcu.detector_thr = NULL;
    328        
     328
    329329        rcu.stat_expedited_cnt = 0;
    330330        rcu.stat_delayed_cnt = 0;
     
    347347        CPU->rcu.signal_unlock = false;
    348348#endif
    349        
     349
    350350        CPU->rcu.cur_cbs = NULL;
    351351        CPU->rcu.cur_cbs_cnt = 0;
     
    358358        CPU->rcu.cur_cbs_gp = 0;
    359359        CPU->rcu.next_cbs_gp = 0;
    360        
     360
    361361        semaphore_initialize(&CPU->rcu.arrived_flag, 0);
    362362
     
    364364        if (config.cpu_active == 1)
    365365                CPU->rcu.reclaimer_thr = NULL;
    366        
     366
    367367        CPU->rcu.stat_max_cbs = 0;
    368368        CPU->rcu.stat_avg_cbs = 0;
     
    379379        start_detector();
    380380#endif
    381        
     381
    382382        start_reclaimers();
    383383}
     
    391391        thread->rcu.was_preempted = false;
    392392#endif
    393        
     393
    394394        link_initialize(&thread->rcu.preempt_link);
    395395}
     
    406406        for (unsigned int cpu_id = 0; cpu_id < config.cpu_active; ++cpu_id) {
    407407                assert(cpus[cpu_id].rcu.reclaimer_thr != NULL);
    408        
     408
    409409                if (cpus[cpu_id].rcu.reclaimer_thr) {
    410410                        thread_interrupt(cpus[cpu_id].rcu.reclaimer_thr);
     
    432432        uint64_t completed = rcu.completed_gp;
    433433        spinlock_unlock(&rcu.gp_lock);
    434        
     434
    435435        return completed;
    436436}
     
    441441        for (unsigned int cpu_id = 0; cpu_id < config.cpu_count; ++cpu_id) {
    442442                char name[THREAD_NAME_BUFLEN] = {0};
    443                
     443
    444444                snprintf(name, THREAD_NAME_BUFLEN - 1, "rcu-rec/%u", cpu_id);
    445                
     445
    446446                cpus[cpu_id].rcu.reclaimer_thr =
    447447                        thread_create(reclaimer, NULL, TASK, THREAD_FLAG_NONE, name);
     
    462462        rcu.detector_thr =
    463463                thread_create(detector, NULL, TASK, THREAD_FLAG_NONE, "rcu-det");
    464        
     464
    465465        if (!rcu.detector_thr)
    466466                panic("Failed to create RCU detector thread.");
    467        
     467
    468468        thread_ready(rcu.detector_thr);
    469469}
     
    475475        bool locked = 0 < CPU->rcu.nesting_cnt;
    476476        preemption_enable();
    477        
     477
    478478        return locked;
    479479}
     
    489489{
    490490        assert(PREEMPTION_DISABLED || interrupts_disabled());
    491        
     491
    492492        if (0 == --(*pnesting_cnt)) {
    493493                _rcu_record_qs();
    494                
     494
    495495                /*
    496496                 * The thread was preempted while in a critical section or
     
    511511{
    512512        assert(PREEMPTION_DISABLED || interrupts_disabled());
    513        
     513
    514514        /*
    515515         * If an interrupt occurs here (even a NMI) it may beat us to
     
    517517         * for us.
    518518         */
    519        
     519
    520520        /*
    521521         * If the detector is eagerly waiting for this cpu's reader to unlock,
     
    525525                semaphore_up(&rcu.remaining_readers);
    526526        }
    527        
     527
    528528        /*
    529529         * This reader was preempted while in a reader section.
     
    536536                rm_preempted_reader();
    537537        }
    538        
     538
    539539        /* If there was something to signal to the detector we have done so. */
    540540        CPU->rcu.signal_unlock = false;
     
    565565        /* Calling from a reader section will deadlock. */
    566566        assert(!rcu_read_locked());
    567        
     567
    568568        synch_item_t completion;
    569569
     
    589589         */
    590590        mutex_lock(&rcu.barrier_mtx);
    591        
     591
    592592        /*
    593593         * Ensure we queue a barrier callback on all cpus before the already
     
    598598        DEFINE_CPU_MASK(cpu_mask);
    599599        cpu_mask_active(cpu_mask);
    600        
     600
    601601        cpu_mask_for_each(*cpu_mask, cpu_id) {
    602602                smp_call(cpu_id, add_barrier_cb, NULL);
    603603        }
    604        
     604
    605605        if (0 < atomic_predec(&rcu.barrier_wait_cnt)) {
    606606                waitq_sleep(&rcu.barrier_wq);
    607607        }
    608        
     608
    609609        mutex_unlock(&rcu.barrier_mtx);
    610610}
     
    659659{
    660660        assert(rcu_item);
    661        
     661
    662662        rcu_item->func = func;
    663663        rcu_item->next = NULL;
    664        
     664
    665665        preemption_disable();
    666666
     
    670670                = local_atomic_exchange(&r->parriving_cbs_tail, &rcu_item->next);
    671671        *prev_tail = rcu_item;
    672        
     672
    673673        /* Approximate the number of callbacks present. */
    674674        ++r->arriving_cbs_cnt;
    675        
     675
    676676        if (expedite) {
    677677                r->expedite_arriving = true;
    678678        }
    679        
     679
    680680        bool first_cb = (prev_tail == &CPU->rcu.arriving_cbs);
    681        
     681
    682682        /* Added first callback - notify the reclaimer. */
    683683        if (first_cb && !semaphore_count_get(&r->arrived_flag)) {
    684684                semaphore_up(&r->arrived_flag);
    685685        }
    686        
     686
    687687        preemption_enable();
    688688}
     
    725725        rcu_gp_t last_compl_gp = 0;
    726726        bool ok = true;
    727        
     727
    728728        while (ok && wait_for_pending_cbs()) {
    729729                assert(CPU->rcu.reclaimer_thr == THREAD);
    730                
     730
    731731                exec_completed_cbs(last_compl_gp);
    732732
    733733                bool expedite = advance_cbs();
    734                
     734
    735735                ok = wait_for_cur_cbs_gp_end(expedite, &last_compl_gp);
    736736        }
     
    744744
    745745        bool ok = true;
    746        
     746
    747747        while (arriving_cbs_empty() && ok) {
    748748                ok = semaphore_down_interruptable(&CPU->rcu.arrived_flag);
    749749        }
    750        
     750
    751751        return ok;
    752752}
     
    763763{
    764764        upd_stat_missed_gp(last_completed_gp);
    765        
     765
    766766        /* Both next_cbs and cur_cbs GP elapsed. */
    767767        if (CPU->rcu.next_cbs_gp <= last_completed_gp) {
    768768                assert(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
    769                
     769
    770770                size_t exec_cnt = CPU->rcu.cur_cbs_cnt + CPU->rcu.next_cbs_cnt;
    771                
     771
    772772                if (exec_cnt < CRITICAL_THRESHOLD) {
    773773                        exec_cbs(&CPU->rcu.cur_cbs);
     
    784784                        preemption_enable();
    785785                }
    786                
     786
    787787                CPU->rcu.cur_cbs_cnt = 0;
    788788                CPU->rcu.next_cbs_cnt = 0;
     
    815815                rcu_item_t *next = rcu_item->next;
    816816                rcu_func_t func = rcu_item->func;
    817                
     817
    818818                func(rcu_item);
    819                
     819
    820820                rcu_item = next;
    821821        }
    822        
     822
    823823        *phead = NULL;
    824824}
     
    843843        CPU->rcu.cur_cbs_cnt = CPU->rcu.next_cbs_cnt;
    844844        CPU->rcu.cur_cbs_gp = CPU->rcu.next_cbs_gp;
    845        
     845
    846846        /* Move arriving_cbs to next_cbs. */
    847        
     847
    848848        CPU->rcu.next_cbs_cnt = CPU->rcu.arriving_cbs_cnt;
    849849        CPU->rcu.arriving_cbs_cnt = 0;
    850        
     850
    851851        /*
    852852         * Too many callbacks queued. Better speed up the detection
     
    859859        /* Start moving the arriving_cbs list to next_cbs. */
    860860        CPU->rcu.next_cbs = CPU->rcu.arriving_cbs;
    861        
     861
    862862        /*
    863863         * At least one callback arrived. The tail therefore does not point
     
    866866        if (CPU->rcu.next_cbs) {
    867867                assert(CPU->rcu.parriving_cbs_tail != &CPU->rcu.arriving_cbs);
    868                
     868
    869869                CPU->rcu.arriving_cbs = NULL;
    870870                /* Reset arriving_cbs before updating the tail pointer. */
     
    883883        /* Update statistics of arrived callbacks. */
    884884        upd_stat_cb_cnts(CPU->rcu.next_cbs_cnt);
    885        
     885
    886886        /*
    887887         * Make changes prior to queuing next_cbs visible to readers.
     
    891891
    892892        /* At the end of next_cbs_gp, exec next_cbs. Determine what GP that is. */
    893        
     893
    894894        if (!next_cbs_empty()) {
    895895                spinlock_lock(&rcu.gp_lock);
    896        
     896
    897897                /* Exec next_cbs at the end of the next GP. */
    898898                CPU->rcu.next_cbs_gp = _rcu_cur_gp + 1;
    899                
     899
    900900                /*
    901901                 * There are no callbacks to invoke before next_cbs. Instruct
     
    908908                        CPU->rcu.cur_cbs_gp = rcu.completed_gp + 1;
    909909                }
    910                
     910
    911911                spinlock_unlock(&rcu.gp_lock);
    912912        } else {
    913913                CPU->rcu.next_cbs_gp = CPU->rcu.cur_cbs_gp;
    914914        }
    915        
     915
    916916        assert(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
    917        
     917
    918918        return expedite;
    919919}
     
    936936        assert(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
    937937        assert(CPU->rcu.cur_cbs_gp <= _rcu_cur_gp + 1);
    938        
     938
    939939        while (rcu.completed_gp < CPU->rcu.cur_cbs_gp) {
    940940                /* GP has not yet started - start a new one. */
     
    952952                } else {
    953953                        /* GP detection is in progress.*/
    954                        
     954
    955955                        if (expedite)
    956956                                condvar_signal(&rcu.expedite_now);
    957                        
     957
    958958                        /* Wait for the GP to complete. */
    959959                        errno_t ret = _condvar_wait_timeout_spinlock(&rcu.gp_ended, &rcu.gp_lock,
    960960                                SYNCH_NO_TIMEOUT, SYNCH_FLAGS_INTERRUPTIBLE);
    961                        
     961
    962962                        if (ret == EINTR) {
    963963                                spinlock_unlock(&rcu.gp_lock);
     
    966966                }
    967967        }
    968        
     968
    969969        upd_missed_gp_in_wait(rcu.completed_gp);
    970        
     970
    971971        *completed_gp = rcu.completed_gp;
    972972        spinlock_unlock(&rcu.gp_lock);
    973        
     973
    974974        return true;
    975975}
     
    978978{
    979979        DEFINE_CPU_MASK(reader_cpus);
    980        
     980
    981981        cpu_mask_active(reader_cpus);
    982982        rm_quiescent_cpus(reader_cpus);
    983        
     983
    984984        while (!cpu_mask_is_none(reader_cpus)) {
    985985                /* Give cpus a chance to context switch (a QS) and batch callbacks. */
    986986                if(!gp_sleep(&expedite))
    987987                        return false;
    988                
     988
    989989                rm_quiescent_cpus(reader_cpus);
    990990                sample_cpus(reader_cpus, reader_cpus);
    991991        }
    992        
     992
    993993        /* Update statistic. */
    994994        if (expedite) {
    995995                ++rcu.stat_expedited_cnt;
    996996        }
    997        
     997
    998998        /*
    999999         * All cpus have passed through a QS and see the most recent _rcu_cur_gp.
     
    10321032        assert(interrupts_disabled());
    10331033        cpu_mask_t *reader_cpus = (cpu_mask_t *)arg;
    1034        
     1034
    10351035        bool locked = RCU_CNT_INC <= THE->rcu_nesting;
    10361036        /* smp_call machinery makes the most current _rcu_cur_gp visible. */
    10371037        bool passed_qs = (CPU->rcu.last_seen_gp == _rcu_cur_gp);
    1038                
     1038
    10391039        if (locked && !passed_qs) {
    10401040                /*
     
    10621062         */
    10631063        size_t nesting_cnt = local_atomic_exchange(&THE->rcu_nesting, 0);
    1064        
     1064
    10651065        /*
    10661066         * Ensures NMIs see .rcu_nesting without the WAS_PREEMPTED mark and
     
    10681068         */
    10691069        compiler_barrier();
    1070        
     1070
    10711071        /* Preempted a reader critical section for the first time. */
    10721072        if (RCU_CNT_INC <= nesting_cnt && !(nesting_cnt & RCU_WAS_PREEMPTED)) {
     
    10741074                note_preempted_reader();
    10751075        }
    1076        
     1076
    10771077        /* Save the thread's nesting count when it is not running. */
    10781078        THREAD->rcu.nesting_cnt = nesting_cnt;
     
    11101110                THREAD->priority = -1;
    11111111        }
    1112        
     1112
    11131113        upd_max_cbs_in_slice(CPU->rcu.arriving_cbs_cnt);
    11141114}
     
    11181118{
    11191119        assert(!rcu_read_locked());
    1120        
     1120
    11211121        /* Load the thread's saved nesting count from before it was preempted. */
    11221122        THE->rcu_nesting = THREAD->rcu.nesting_cnt;
     
    11311131{
    11321132        assert(THE->rcu_nesting == 0);
    1133        
     1133
    11341134        /*
    11351135         * The thread forgot to exit its reader critical section.
     
    11591159{
    11601160        assert(0 == THE->rcu_nesting || RCU_WAS_PREEMPTED == THE->rcu_nesting);
    1161        
     1161
    11621162        size_t prev = local_atomic_exchange(&THE->rcu_nesting, 0);
    11631163        if (prev == RCU_WAS_PREEMPTED) {
     
    12121212                return true;
    12131213        }
    1214        
     1214
    12151215        spinlock_lock(&rcu.gp_lock);
    1216        
     1216
    12171217        if (CPU->rcu.cur_cbs_gp <= rcu.completed_gp) {
    12181218                *completed_gp = rcu.completed_gp;
     
    12201220                return true;
    12211221        }
    1222        
     1222
    12231223        assert(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
    12241224        assert(_rcu_cur_gp <= CPU->rcu.cur_cbs_gp);
    1225        
     1225
    12261226        /*
    12271227         * Notify the detector of how many GP ends we intend to wait for, so
     
    12311231        size_t remaining_gp_ends = (size_t) (CPU->rcu.next_cbs_gp - _rcu_cur_gp);
    12321232        req_detection(remaining_gp_ends + (arriving_cbs_empty() ? 0 : 1));
    1233        
     1233
    12341234        /*
    12351235         * Ask the detector to speed up GP detection if there are too many
     
    12391239                if(0 == rcu.req_expedited_cnt)
    12401240                        condvar_signal(&rcu.expedite_now);
    1241                
     1241
    12421242                /*
    12431243                 * Expedite only cub_cbs. If there really is a surge of callbacks
     
    12501250        /* Wait for cur_cbs_gp to end. */
    12511251        bool interrupted = cv_wait_for_gp(CPU->rcu.cur_cbs_gp);
    1252        
     1252
    12531253        *completed_gp = rcu.completed_gp;
    12541254        spinlock_unlock(&rcu.gp_lock);
    1255        
     1255
    12561256        if (!interrupted)
    12571257                upd_missed_gp_in_wait(*completed_gp);
    1258        
     1258
    12591259        return !interrupted;
    12601260}
     
    12641264{
    12651265        assert(spinlock_locked(&rcu.gp_lock));
    1266        
     1266
    12671267        bool interrupted = false;
    1268        
     1268
    12691269        /* Wait until wait_on_gp ends. */
    12701270        while (rcu.completed_gp < wait_on_gp && !interrupted) {
     
    12731273                interrupted = (ret == EINTR);
    12741274        }
    1275        
     1275
    12761276        return interrupted;
    12771277}
     
    12961296{
    12971297        spinlock_lock(&rcu.gp_lock);
    1298        
     1298
    12991299        while (wait_for_detect_req()) {
    13001300                /*
     
    13031303                 */
    13041304                start_new_gp();
    1305                
     1305
    13061306                spinlock_unlock(&rcu.gp_lock);
    1307                
     1307
    13081308                if (!wait_for_readers())
    13091309                        goto unlocked_out;
    1310                
     1310
    13111311                spinlock_lock(&rcu.gp_lock);
    13121312
     
    13141314                end_cur_gp();
    13151315        }
    1316        
     1316
    13171317        spinlock_unlock(&rcu.gp_lock);
    1318        
     1318
    13191319unlocked_out:
    13201320        return;
     
    13251325{
    13261326        assert(spinlock_locked(&rcu.gp_lock));
    1327        
     1327
    13281328        bool interrupted = false;
    1329        
     1329
    13301330        while (0 == rcu.req_gp_end_cnt && !interrupted) {
    13311331                int ret = _condvar_wait_timeout_spinlock(&rcu.req_gp_changed,
    13321332                        &rcu.gp_lock, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_INTERRUPTIBLE);
    1333                
     1333
    13341334                interrupted = (ret == EINTR);
    13351335        }
    1336        
     1336
    13371337        return !interrupted;
    13381338}
     
    13421342{
    13431343        assert(spinlock_locked(&rcu.gp_lock));
    1344        
     1344
    13451345        rcu.completed_gp = _rcu_cur_gp;
    13461346        --rcu.req_gp_end_cnt;
    1347        
     1347
    13481348        condvar_broadcast(&rcu.gp_ended);
    13491349}
     
    13531353{
    13541354        DEFINE_CPU_MASK(reading_cpus);
    1355        
     1355
    13561356        /* All running cpus have potential readers. */
    13571357        cpu_mask_active(reading_cpus);
     
    13631363        if (!gp_sleep())
    13641364                return false;
    1365        
     1365
    13661366        /* Non-intrusively determine which cpus have yet to pass a QS. */
    13671367        rm_quiescent_cpus(reading_cpus);
    1368        
     1368
    13691369        /* Actively interrupt cpus delaying the current GP and demand a QS. */
    13701370        interrupt_delaying_cpus(reading_cpus);
    1371        
     1371
    13721372        /* Wait for the interrupted cpus to notify us that they reached a QS. */
    13731373        if (!wait_for_delaying_cpus())
     
    13781378         * monotonically descreases.
    13791379         */
    1380        
     1380
    13811381        /* Wait for the last reader in cur_preempted to notify us it is done. */
    13821382        if (!wait_for_preempt_reader())
    13831383                return false;
    1384        
     1384
    13851385        return true;
    13861386}
     
    13971397                        DETECT_SLEEP_MS * 1000, SYNCH_FLAGS_INTERRUPTIBLE);
    13981398        }
    1399        
     1399
    14001400        if (0 < rcu.req_expedited_cnt) {
    14011401                --rcu.req_expedited_cnt;
     
    14031403                ++rcu.stat_expedited_cnt;
    14041404        }
    1405        
     1405
    14061406        spinlock_unlock(&rcu.gp_lock);
    1407        
     1407
    14081408        return (ret != EINTR);
    14091409}
     
    14131413{
    14141414        atomic_set(&rcu.delaying_cpu_cnt, 0);
    1415        
     1415
    14161416        sample_cpus(cpu_mask, NULL);
    14171417}
     
    14261426        assert(interrupts_disabled());
    14271427        assert(!CPU->rcu.is_delaying_gp);
    1428        
     1428
    14291429        /* Cpu did not pass a quiescent state yet. */
    14301430        if (CPU->rcu.last_seen_gp != _rcu_cur_gp) {
     
    14401440                        ACCESS_ONCE(CPU->rcu.is_delaying_gp) = true;
    14411441                        CPU->rcu.signal_unlock = true;
    1442                        
     1442
    14431443                        atomic_inc(&rcu.delaying_cpu_cnt);
    14441444                } else {
     
    14661466                 */
    14671467        }
    1468        
     1468
    14691469        /*
    14701470         * smp_call() makes sure any changes propagate back to the caller.
     
    14831483                        return false;
    14841484        }
    1485        
     1485
    14861486        /* Update statistic. */
    14871487        rcu.stat_delayed_cnt += delaying_cpu_cnt;
    1488        
     1488
    14891489        return true;
    14901490}
     
    15061506         */
    15071507        compiler_barrier();
    1508        
     1508
    15091509        /* Save the thread's nesting count when it is not running. */
    15101510        THREAD->rcu.nesting_cnt = CPU->rcu.nesting_cnt;
    1511        
     1511
    15121512        /* Preempted a reader critical section for the first time. */
    15131513        if (0 < THREAD->rcu.nesting_cnt && !THREAD->rcu.was_preempted) {
     
    15151515                note_preempted_reader();
    15161516        }
    1517        
     1517
    15181518        /*
    15191519         * The preempted reader has been noted globally. There are therefore
     
    15281528         */
    15291529        CPU->rcu.nesting_cnt = 0;
    1530        
     1530
    15311531        /*
    15321532         * This cpu is holding up the current GP. Let the detector know
     
    15531553                THREAD->priority = -1;
    15541554        }
    1555        
     1555
    15561556        upd_max_cbs_in_slice(CPU->rcu.arriving_cbs_cnt);
    15571557}
     
    15621562        assert(PREEMPTION_DISABLED || interrupts_disabled());
    15631563        assert(0 == CPU->rcu.nesting_cnt);
    1564        
     1564
    15651565        /* Load the thread's saved nesting count from before it was preempted. */
    15661566        CPU->rcu.nesting_cnt = THREAD->rcu.nesting_cnt;
    1567        
     1567
    15681568        /*
    15691569         * Ensures NMI see the proper nesting count before .signal_unlock.
     
    15721572         */
    15731573        compiler_barrier();
    1574        
     1574
    15751575        /*
    15761576         * In the unlikely event that a NMI occurs between the loading of the
     
    15941594        assert(THREAD->state == Exiting);
    15951595        assert(PREEMPTION_DISABLED || interrupts_disabled());
    1596        
     1596
    15971597        /*
    15981598         * The thread forgot to exit its reader critical section.
     
    16171617{
    16181618        assert(spinlock_locked(&rcu.gp_lock));
    1619        
     1619
    16201620        irq_spinlock_lock(&rcu.preempt_lock, true);
    1621        
     1621
    16221622        /* Start a new GP. Announce to readers that a quiescent state is needed. */
    16231623        ++_rcu_cur_gp;
    1624        
     1624
    16251625        /*
    16261626         * Readers preempted before the start of this GP (next_preempted)
     
    16321632         */
    16331633        list_concat(&rcu.cur_preempted, &rcu.next_preempted);
    1634        
     1634
    16351635        irq_spinlock_unlock(&rcu.preempt_lock, true);
    16361636}
     
    16941694         */
    16951695        memory_barrier(); /* MB C */
    1696        
     1696
    16971697        cpu_mask_for_each(*cpu_mask, cpu_id) {
    16981698                /*
     
    17071707                 */
    17081708                bool cpu_acked_gp = (cpus[cpu_id].rcu.last_seen_gp == _rcu_cur_gp);
    1709                
     1709
    17101710                /*
    17111711                 * Either the cpu is idle or it is exiting away from idle mode
     
    17141714                 */
    17151715                bool cpu_idle = cpus[cpu_id].idle;
    1716                
     1716
    17171717                if (cpu_acked_gp || cpu_idle) {
    17181718                        cpu_mask_reset(cpu_mask, cpu_id);
     
    17361736{
    17371737        assert(CPU->rcu.cur_cbs_gp <= completed_gp);
    1738        
     1738
    17391739        size_t delta = (size_t)(completed_gp - CPU->rcu.cur_cbs_gp);
    17401740        CPU->rcu.stat_missed_gp_in_wait += delta;
     
    17641764{
    17651765        irq_spinlock_lock(&rcu.preempt_lock, true);
    1766        
     1766
    17671767        assert(link_used(&THREAD->rcu.preempt_link));
    17681768
     
    17931793        bool reader_exists = !list_empty(&rcu.cur_preempted);
    17941794        rcu.preempt_blocking_det = reader_exists;
    1795        
     1795
    17961796        irq_spinlock_unlock(&rcu.preempt_lock, true);
    1797        
     1797
    17981798        if (reader_exists) {
    17991799                /* Update statistic. */
    18001800                ++rcu.stat_preempt_blocking_cnt;
    1801                
     1801
    18021802                return semaphore_down_interruptable(&rcu.remaining_readers);
    18031803        }
    1804        
     1804
    18051805        return true;
    18061806}
     
    18091809{
    18101810        rcu_cpu_data_t *cr = &CPU->rcu;
    1811        
     1811
    18121812        if (arriving_cbs_cnt > cr->last_arriving_cnt) {
    18131813                size_t arrived_cnt = arriving_cbs_cnt - cr->last_arriving_cnt;
    18141814                cr->stat_max_slice_cbs = max(arrived_cnt, cr->stat_max_slice_cbs);
    18151815        }
    1816        
     1816
    18171817        cr->last_arriving_cnt = arriving_cbs_cnt;
    18181818}
     
    18261826         * are no locks to lock in order to get up-to-date values.
    18271827         */
    1828        
     1828
    18291829#ifdef RCU_PREEMPT_PODZIMEK
    18301830        const char *algo = "podzimek-preempt-rcu";
     
    18321832        const char *algo = "a-preempt-rcu";
    18331833#endif
    1834        
     1834
    18351835        printf("Config: expedite_threshold=%d, critical_threshold=%d,"
    18361836                " detect_sleep=%dms, %s\n",
     
    18431843                "running or not)\n", rcu.stat_preempt_blocking_cnt);
    18441844        printf("Smp calls:     %zu\n", rcu.stat_smp_call_cnt);
    1845        
     1845
    18461846        printf("Max arrived callbacks per GP and CPU:\n");
    18471847        for (unsigned int i = 0; i < config.cpu_count; ++i) {
     
    18531853                printf(" %zu", cpus[i].rcu.stat_avg_cbs);
    18541854        }
    1855        
     1855
    18561856        printf("\nMax arrived callbacks per time slice and CPU:\n");
    18571857        for (unsigned int i = 0; i < config.cpu_count; ++i) {
Note: See TracChangeset for help on using the changeset viewer.