Changeset 8565a42 in mainline for kernel/generic/src/synch


Ignore:
Timestamp:
2018-03-02T20:34:50Z (8 years ago)
Author:
GitHub <noreply@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a1a81f69, d5e5fd1
Parents:
3061bc1 (diff), 34e1206 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:34:50)
git-committer:
GitHub <noreply@…> (2018-03-02 20:34:50)
Message:

Remove all trailing whitespace, everywhere.

See individual commit messages for details.

Location:
kernel/generic/src/synch
Files:
8 edited

Legend:

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

    r3061bc1 r8565a42  
    143143        /* Lock only after releasing the waitq to avoid a possible deadlock. */
    144144        spinlock_lock(lock);
    145        
     145
    146146        return rc;
    147147}
     
    168168        ipl_t ipl = irq_lock->ipl;
    169169        bool guard = irq_lock->guard;
    170        
     170
    171171        irq_lock->guard = false;
    172        
     172
    173173        /*
    174174         * waitq_prepare() restores interrupts to the current state,
     
    182182         */
    183183        rc = _condvar_wait_timeout_spinlock(cv, &irq_lock->lock, usec, flags);
    184        
     184
    185185        irq_lock->guard = guard;
    186186        irq_lock->ipl = ipl;
    187        
     187
    188188        return rc;
    189189}
  • kernel/generic/src/synch/futex.c

    r3061bc1 r8565a42  
    157157{
    158158        task->futexes = malloc(sizeof(struct futex_cache), 0);
    159        
     159
    160160        cht_create(&task->futexes->ht, 0, 0, 0, true, &task_futex_ht_ops);
    161        
     161
    162162        list_initialize(&task->futexes->list);
    163163        spinlock_initialize(&task->futexes->list_lock, "futex-list-lock");
     
    183183        struct futex_cache *cache =
    184184                member_to_inst(work, struct futex_cache, destroy_work);
    185        
     185
    186186        /*
    187187         * Destroy the cache before manually freeing items of the cache in case
     
    189189         */
    190190        cht_destroy_unsafe(&cache->ht);
    191        
     191
    192192        /* Manually free futex_ptr cache items. */
    193193        list_foreach_safe(cache->list, cur_link, next_link) {
     
    197197                free(fut_ptr);
    198198        }
    199        
     199
    200200        free(cache);
    201201}
     
    205205{
    206206        struct futex_cache *futexes = TASK->futexes;
    207        
     207
    208208        /* All threads of this task have terminated. This is the last thread. */
    209209        spinlock_lock(&futexes->list_lock);
    210        
     210
    211211        list_foreach_safe(futexes->list, cur_link, next_link) {
    212212                futex_ptr_t *fut_ptr = member_to_inst(cur_link, futex_ptr_t, all_link);
     
    222222                futex_release_ref_locked(fut_ptr->futex);
    223223        }
    224        
     224
    225225        spinlock_unlock(&futexes->list_lock);
    226226}
     
    252252        assert(spinlock_locked(&futex_ht_lock));
    253253        assert(0 < futex->refcount);
    254        
     254
    255255        --futex->refcount;
    256        
     256
    257257        if (0 == futex->refcount) {
    258258                hash_table_remove(&futex_ht, &futex->paddr);
     
    272272{
    273273        futex_t *futex = find_cached_futex(uaddr);
    274        
     274
    275275        if (futex)
    276276                return futex;
     
    303303                    (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE));
    304304        }
    305        
     305
    306306        spinlock_unlock(&futex_ht_lock);
    307307        page_table_unlock(AS, false);
    308        
     308
    309309        return success;
    310310}
     
    314314{
    315315        cht_read_lock();
    316        
     316
    317317        futex_t *futex;
    318318        cht_link_t *futex_ptr_link = cht_find_lazy(&TASK->futexes->ht, &uaddr);
     
    321321                futex_ptr_t *futex_ptr
    322322                        = member_to_inst(futex_ptr_link, futex_ptr_t, cht_link);
    323                
     323
    324324                futex = futex_ptr->futex;
    325325        } else {
    326326                futex = NULL;
    327327        }
    328        
     328
    329329        cht_read_unlock();
    330        
     330
    331331        return futex;
    332332}
     
    340340{
    341341        futex_t *futex = malloc(sizeof(futex_t), 0);
    342        
     342
    343343        /*
    344344         * Find the futex object in the global futex table (or insert it
     
    346346         */
    347347        spinlock_lock(&futex_ht_lock);
    348        
     348
    349349        ht_link_t *fut_link = hash_table_find(&futex_ht, &phys_addr);
    350        
     350
    351351        if (fut_link) {
    352352                free(futex);
     
    357357                hash_table_insert(&futex_ht, &futex->ht_link);
    358358        }
    359        
     359
    360360        spinlock_unlock(&futex_ht_lock);
    361        
     361
    362362        /*
    363363         * Cache the link to the futex object for this task.
     
    365365        futex_ptr_t *fut_ptr = malloc(sizeof(futex_ptr_t), 0);
    366366        cht_link_t *dup_link;
    367        
     367
    368368        fut_ptr->futex = futex;
    369369        fut_ptr->uaddr = uaddr;
    370        
     370
    371371        cht_read_lock();
    372        
     372
    373373        /* Cache the mapping from the virtual address to the futex for this task. */
    374374        if (cht_insert_unique(&TASK->futexes->ht, &fut_ptr->cht_link, &dup_link)) {
     
    380380                free(fut_ptr);
    381381                futex_release_ref_locked(futex);
    382                
     382
    383383                futex_ptr_t *dup = member_to_inst(dup_link, futex_ptr_t, cht_link);
    384384                futex = dup->futex;
     
    386386
    387387        cht_read_unlock();
    388        
     388
    389389        return futex;
    390390}
     
    401401{
    402402        futex_t *futex = get_futex(uaddr);
    403        
     403
    404404        if (!futex)
    405405                return (sys_errno_t) ENOENT;
     
    428428{
    429429        futex_t *futex = get_futex(uaddr);
    430        
     430
    431431        if (futex) {
    432432                waitq_wakeup(&futex->wq, WAKEUP_FIRST);
     
    492492        const futex_ptr_t *fut_ptr1 = member_to_inst(item1, futex_ptr_t, cht_link);
    493493        const futex_ptr_t *fut_ptr2 = member_to_inst(item2, futex_ptr_t, cht_link);
    494        
     494
    495495        return fut_ptr1->uaddr == fut_ptr2->uaddr;
    496496}
     
    500500        const futex_ptr_t *fut_ptr = member_to_inst(item, futex_ptr_t, cht_link);
    501501        uintptr_t uaddr = *(uintptr_t*)key;
    502        
     502
    503503        return fut_ptr->uaddr == uaddr;
    504504}
  • kernel/generic/src/synch/mutex.c

    r3061bc1 r8565a42  
    108108                assert(usec == SYNCH_NO_TIMEOUT);
    109109                assert(!(flags & SYNCH_FLAGS_INTERRUPTIBLE));
    110                
     110
    111111                unsigned int cnt = 0;
    112112                bool deadlock_reported = false;
  • kernel/generic/src/synch/rcu.c

    r3061bc1 r8565a42  
    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) {
  • kernel/generic/src/synch/smp_memory_barrier.c

    r3061bc1 r8565a42  
    5656                smp_call(cpu_id, issue_mem_bar, NULL);
    5757        }
    58        
     58
    5959        return 0;
    6060}
  • kernel/generic/src/synch/spinlock.c

    r3061bc1 r8565a42  
    7777        size_t i = 0;
    7878        bool deadlock_reported = false;
    79        
     79
    8080        preemption_disable();
    8181        while (test_and_set(&lock->val)) {
     
    101101                if (lock->name[0] == '*')
    102102                        continue;
    103                
     103
    104104                if (i++ > DEADLOCK_THRESHOLD) {
    105105                        printf("cpu%u: looping on spinlock %p:%s, "
     
    107107                            (void *) CALLER, symtab_fmt_name_lookup(CALLER));
    108108                        stack_trace();
    109                        
     109
    110110                        i = 0;
    111111                        deadlock_reported = true;
    112112                }
    113113        }
    114        
     114
    115115        if (deadlock_reported)
    116116                printf("cpu%u: not deadlocked\n", CPU->id);
    117        
     117
    118118        /*
    119119         * Prevent critical section code from bleeding out this way up.
     
    131131{
    132132        ASSERT_SPINLOCK(spinlock_locked(lock), lock);
    133        
     133
    134134        /*
    135135         * Prevent critical section code from bleeding out this way down.
    136136         */
    137137        CS_LEAVE_BARRIER();
    138        
     138
    139139        atomic_set(&lock->val, 0);
    140140        preemption_enable();
     
    157157        preemption_disable();
    158158        bool ret = !test_and_set(&lock->val);
    159        
     159
    160160        /*
    161161         * Prevent critical section code from bleeding out this way up.
    162162         */
    163163        CS_ENTER_BARRIER();
    164        
     164
    165165        if (!ret)
    166166                preemption_enable();
    167        
     167
    168168        return ret;
    169169}
     
    208208                ipl_t ipl = interrupts_disable();
    209209                spinlock_lock(&(lock->lock));
    210                
     210
    211211                lock->guard = true;
    212212                lock->ipl = ipl;
    213213        } else {
    214214                ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
    215                
     215
    216216                spinlock_lock(&(lock->lock));
    217217                ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
     
    231231{
    232232        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
    233        
     233
    234234        if (irq_res) {
    235235                ASSERT_IRQ_SPINLOCK(lock->guard, lock);
    236                
     236
    237237                lock->guard = false;
    238238                ipl_t ipl = lock->ipl;
    239                
     239
    240240                spinlock_unlock(&(lock->lock));
    241241                interrupts_restore(ipl);
     
    261261        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
    262262        bool ret = spinlock_trylock(&(lock->lock));
    263        
     263
    264264        ASSERT_IRQ_SPINLOCK((!ret) || (!lock->guard), lock);
    265265        return ret;
     
    280280{
    281281        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
    282        
     282
    283283        /* Pass guard from unlock to lock */
    284284        bool guard = unlock->guard;
    285285        ipl_t ipl = unlock->ipl;
    286286        unlock->guard = false;
    287        
     287
    288288        spinlock_unlock(&(unlock->lock));
    289289        spinlock_lock(&(lock->lock));
    290        
     290
    291291        ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    292        
     292
    293293        if (guard) {
    294294                lock->guard = true;
     
    311311{
    312312        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
    313        
     313
    314314        spinlock_lock(&(lock->lock));
    315315        ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    316        
     316
    317317        /* Pass guard from unlock to lock */
    318318        if (unlock->guard) {
     
    321321                unlock->guard = false;
    322322        }
    323        
     323
    324324        spinlock_unlock(&(unlock->lock));
    325325}
  • kernel/generic/src/synch/waitq.c

    r3061bc1 r8565a42  
    9494        bool do_wakeup = false;
    9595        DEADLOCK_PROBE_INIT(p_wqlock);
    96        
     96
    9797        irq_spinlock_lock(&threads_lock, false);
    9898        if (!thread_exists(thread))
    9999                goto out;
    100        
     100
    101101grab_locks:
    102102        irq_spinlock_lock(&thread->lock, false);
    103        
     103
    104104        waitq_t *wq;
    105105        if ((wq = thread->sleep_queue)) {  /* Assignment */
     
    110110                        goto grab_locks;
    111111                }
    112                
     112
    113113                list_remove(&thread->wq_link);
    114114                thread->saved_context = thread->sleep_timeout_context;
     
    117117                irq_spinlock_unlock(&wq->lock, false);
    118118        }
    119        
     119
    120120        thread->timeout_pending = false;
    121121        irq_spinlock_unlock(&thread->lock, false);
    122        
     122
    123123        if (do_wakeup)
    124124                thread_ready(thread);
    125        
     125
    126126out:
    127127        irq_spinlock_unlock(&threads_lock, false);
     
    144144        bool do_wakeup = false;
    145145        DEADLOCK_PROBE_INIT(p_wqlock);
    146        
     146
    147147        /*
    148148         * The thread is quaranteed to exist because
    149149         * threads_lock is held.
    150150         */
    151        
     151
    152152grab_locks:
    153153        irq_spinlock_lock(&thread->lock, false);
    154        
     154
    155155        waitq_t *wq;
    156156        if ((wq = thread->sleep_queue)) {  /* Assignment */
     
    162162                        return;
    163163                }
    164                
     164
    165165                if (!irq_spinlock_trylock(&wq->lock)) {
    166166                        /* Avoid deadlock */
     
    169169                        goto grab_locks;
    170170                }
    171                
     171
    172172                if ((thread->timeout_pending) &&
    173173                    (timeout_unregister(&thread->sleep_timeout)))
    174174                        thread->timeout_pending = false;
    175                
     175
    176176                list_remove(&thread->wq_link);
    177177                thread->saved_context = thread->sleep_interruption_context;
     
    180180                irq_spinlock_unlock(&wq->lock, false);
    181181        }
    182        
     182
    183183        irq_spinlock_unlock(&thread->lock, false);
    184        
     184
    185185        if (do_wakeup)
    186186                thread_ready(thread);
     
    198198{
    199199        irq_spinlock_lock(&wq->lock, true);
    200        
     200
    201201        if (!list_empty(&wq->sleepers)) {
    202202                thread_t *thread = list_get_instance(list_first(&wq->sleepers),
    203203                    thread_t, wq_link);
    204                
     204
    205205                irq_spinlock_lock(&thread->lock, false);
    206                
     206
    207207                assert(thread->sleep_interruptible);
    208                
     208
    209209                if ((thread->timeout_pending) &&
    210210                    (timeout_unregister(&thread->sleep_timeout)))
    211211                        thread->timeout_pending = false;
    212                
     212
    213213                list_remove(&thread->wq_link);
    214214                thread->saved_context = thread->sleep_interruption_context;
    215215                thread->sleep_queue = NULL;
    216                
     216
    217217                irq_spinlock_unlock(&thread->lock, false);
    218218                thread_ready(thread);
    219219        }
    220        
     220
    221221        irq_spinlock_unlock(&wq->lock, true);
    222222}
     
    271271{
    272272        assert((!PREEMPTION_DISABLED) || (PARAM_NON_BLOCKING(flags, usec)));
    273        
     273
    274274        ipl_t ipl = waitq_sleep_prepare(wq);
    275275        bool nblocked;
     
    296296{
    297297        ipl_t ipl;
    298        
     298
    299299restart:
    300300        ipl = interrupts_disable();
    301        
     301
    302302        if (THREAD) {  /* Needed during system initiailzation */
    303303                /*
     
    310310                 */
    311311                irq_spinlock_lock(&THREAD->lock, false);
    312                
     312
    313313                if (THREAD->timeout_pending) {
    314314                        irq_spinlock_unlock(&THREAD->lock, false);
     
    316316                        goto restart;
    317317                }
    318                
     318
    319319                irq_spinlock_unlock(&THREAD->lock, false);
    320320        }
    321        
     321
    322322        irq_spinlock_lock(&wq->lock, false);
    323323        return ipl;
     
    354354                irq_spinlock_unlock(&wq->lock, false);
    355355        }
    356        
     356
    357357        interrupts_restore(ipl);
    358358}
     
    387387                }
    388388        }
    389        
     389
    390390        /*
    391391         * Now we are firmly decided to go to sleep.
     
    393393         */
    394394        irq_spinlock_lock(&THREAD->lock, false);
    395        
     395
    396396        if (flags & SYNCH_FLAGS_INTERRUPTIBLE) {
    397397                /*
     
    403403                        return EINTR;
    404404                }
    405                
     405
    406406                /*
    407407                 * Set context that will be restored if the sleep
     
    417417        } else
    418418                THREAD->sleep_interruptible = false;
    419        
     419
    420420        if (usec) {
    421421                /* We use the timeout variant. */
     
    426426                        return ETIMEOUT;
    427427                }
    428                
     428
    429429                THREAD->timeout_pending = true;
    430430                timeout_register(&THREAD->sleep_timeout, (uint64_t) usec,
    431431                    waitq_sleep_timed_out, THREAD);
    432432        }
    433        
     433
    434434        list_append(&THREAD->wq_link, &wq->sleepers);
    435        
     435
    436436        /*
    437437         * Suspend execution.
     
    440440        THREAD->state = Sleeping;
    441441        THREAD->sleep_queue = wq;
    442        
     442
    443443        /* Must be before entry to scheduler, because there are multiple
    444444         * return vectors.
    445445         */
    446446        *blocked = true;
    447        
     447
    448448        irq_spinlock_unlock(&THREAD->lock, false);
    449        
     449
    450450        /* wq->lock is released in scheduler_separated_stack() */
    451451        scheduler();
    452        
     452
    453453        return EOK;
    454454}
     
    511511{
    512512        assert(interrupts_disabled());
    513        
     513
    514514        irq_spinlock_lock(&wq->lock, false);
    515515        irq_spinlock_unlock(&wq->lock, false);
     
    536536        assert(interrupts_disabled());
    537537        assert(irq_spinlock_locked(&wq->lock));
    538        
     538
    539539loop:
    540540        if (list_empty(&wq->sleepers)) {
     
    542542                if ((count) && (mode == WAKEUP_ALL))
    543543                        wq->missed_wakeups--;
    544                
     544
    545545                return;
    546546        }
    547        
     547
    548548        count++;
    549549        thread_t *thread = list_get_instance(list_first(&wq->sleepers),
    550550            thread_t, wq_link);
    551        
     551
    552552        /*
    553553         * Lock the thread prior to removing it from the wq.
     
    569569        irq_spinlock_lock(&thread->lock, false);
    570570        list_remove(&thread->wq_link);
    571        
     571
    572572        if ((thread->timeout_pending) &&
    573573            (timeout_unregister(&thread->sleep_timeout)))
    574574                thread->timeout_pending = false;
    575        
     575
    576576        thread->sleep_queue = NULL;
    577577        irq_spinlock_unlock(&thread->lock, false);
    578        
     578
    579579        thread_ready(thread);
    580        
     580
    581581        if (mode == WAKEUP_ALL)
    582582                goto loop;
  • kernel/generic/src/synch/workqueue.c

    r3061bc1 r8565a42  
    5959         */
    6060        IRQ_SPINLOCK_DECLARE(lock);
    61        
     61
    6262        /* Activates a worker if new work arrives or if shutting down the queue. */
    6363        condvar_t activate_worker;
    64        
     64
    6565        /* Queue of work_items ready to be dispatched. */
    6666        list_t queue;
    67        
     67
    6868        /* List of worker threads. */
    6969        list_t workers;
    70        
     70
    7171        /* Number of work items queued. */
    7272        size_t item_cnt;
    73        
     73
    7474        /* Indicates the work queue is shutting down. */
    7575        bool stopping;
     
    8484        /* Number of blocked workers sleeping in work func() (ie not idle). */
    8585        size_t blocked_worker_cnt;
    86        
     86
    8787        /* Number of pending signal_worker_op() operations. */
    8888        size_t pending_op_cnt;
    89        
     89
    9090        link_t nb_link;
    91        
     91
    9292#ifdef CONFIG_DEBUG
    9393        /* Magic cookie for integrity checks. Immutable. Accessed without lock. */
     
    105105/** Max number of work items per active worker before a new worker is activated.*/
    106106static const size_t max_items_per_worker = 8;
    107        
     107
    108108/** System wide work queue. */
    109109static struct work_queue g_work_queue;
     
    157157         */
    158158        booting = false;
    159        
     159
    160160        nonblock_init();
    161        
     161
    162162        if (!add_worker(&g_work_queue))
    163163                panic("Could not create a single global work queue worker!\n");
    164        
     164
    165165}
    166166
     
    174174        /* Maximum concurrency without slowing down the system. */
    175175        max_concurrent_workers = max(2, config.cpu_count);
    176        
     176
    177177        workq_preinit(&g_work_queue, "kworkq");
    178178}
     
    188188{
    189189        struct work_queue *workq = malloc(sizeof(struct work_queue), 0);
    190        
     190
    191191        if (workq) {
    192192                if (workq_init(workq, name)) {
     
    194194                        return workq;
    195195                }
    196                
     196
    197197                free(workq);
    198198        }
    199        
     199
    200200        return NULL;
    201201}
     
    205205{
    206206        assert(!workq_corrupted(workq));
    207        
     207
    208208        irq_spinlock_lock(&workq->lock, true);
    209209        bool stopped = workq->stopping;
     
    212212#endif
    213213        irq_spinlock_unlock(&workq->lock, true);
    214        
     214
    215215        if (!stopped) {
    216216                workq_stop(workq);
     
    218218                assert(0 == running_workers);
    219219        }
    220        
     220
    221221#ifdef CONFIG_DEBUG
    222222        workq->cookie = 0;
    223223#endif
    224        
     224
    225225        free(workq);
    226226}
     
    232232        workq->cookie = WORKQ_MAGIC;
    233233#endif
    234        
     234
    235235        irq_spinlock_initialize(&workq->lock, name);
    236236        condvar_initialize(&workq->activate_worker);
    237        
     237
    238238        list_initialize(&workq->queue);
    239239        list_initialize(&workq->workers);
    240        
     240
    241241        workq->item_cnt = 0;
    242242        workq->stopping = false;
    243243        workq->name = name;
    244        
     244
    245245        workq->cur_worker_cnt = 1;
    246246        workq->idle_worker_cnt = 0;
    247247        workq->activate_pending = 0;
    248248        workq->blocked_worker_cnt = 0;
    249        
     249
    250250        workq->pending_op_cnt = 0;
    251251        link_initialize(&workq->nb_link);
     
    270270        thread_t *thread = thread_create(worker_thread, workq, TASK,
    271271                THREAD_FLAG_NONE, workq->name);
    272        
     272
    273273        if (!thread) {
    274274                irq_spinlock_lock(&workq->lock, true);
    275                
     275
    276276                /* cur_worker_cnt proactively increased in signal_worker_logic() .*/
    277277                assert(0 < workq->cur_worker_cnt);
    278278                --workq->cur_worker_cnt;
    279                
     279
    280280                irq_spinlock_unlock(&workq->lock, true);
    281281                return false;
    282282        }
    283        
     283
    284284        /* Respect lock ordering. */
    285285        irq_spinlock_lock(&thread->lock, true);
     
    290290        if (!workq->stopping) {
    291291                success = true;
    292                
     292
    293293                /* Try to distribute workers among cpus right away. */
    294294                unsigned int cpu_id = (workq->cur_worker_cnt) % config.cpu_active;
    295                
     295
    296296                if (!cpus[cpu_id].active)
    297297                        cpu_id = CPU->id;
     
    312312                 */
    313313                success = false;
    314                
     314
    315315                /* cur_worker_cnt proactively increased in signal_worker() .*/
    316316                assert(0 < workq->cur_worker_cnt);
    317317                --workq->cur_worker_cnt;
    318318        }
    319        
     319
    320320        irq_spinlock_unlock(&workq->lock, false);
    321321        irq_spinlock_unlock(&thread->lock, true);
     
    324324                thread_interrupt(thread);
    325325        }
    326                
     326
    327327        thread_ready(thread);
    328        
     328
    329329        return success;
    330330}
     
    337337{
    338338        assert(!workq_corrupted(workq));
    339        
     339
    340340        interrupt_workers(workq);
    341341        wait_for_workers(workq);
     
    350350        assert(!workq->stopping);
    351351        workq->stopping = true;
    352        
     352
    353353        /* Respect lock ordering - do not hold workq->lock during broadcast. */
    354354        irq_spinlock_unlock(&workq->lock, true);
    355        
     355
    356356        condvar_broadcast(&workq->activate_worker);
    357357}
     
    361361{
    362362        assert(!PREEMPTION_DISABLED);
    363        
     363
    364364        irq_spinlock_lock(&workq->lock, true);
    365        
     365
    366366        list_foreach_safe(workq->workers, cur_worker, next_worker) {
    367367                thread_t *worker = list_get_instance(cur_worker, thread_t, workq_link);
     
    370370                /* Wait without the lock. */
    371371                irq_spinlock_unlock(&workq->lock, true);
    372                
     372
    373373                thread_join(worker);
    374374                thread_detach(worker);
    375                
     375
    376376                irq_spinlock_lock(&workq->lock, true);
    377377        }
    378        
     378
    379379        assert(list_empty(&workq->workers));
    380        
     380
    381381        /* Wait for deferred add_worker_op(), signal_worker_op() to finish. */
    382382        while (0 < workq->cur_worker_cnt || 0 < workq->pending_op_cnt) {
    383383                irq_spinlock_unlock(&workq->lock, true);
    384                
     384
    385385                scheduler();
    386                
     386
    387387                irq_spinlock_lock(&workq->lock, true);
    388388        }
    389        
     389
    390390        irq_spinlock_unlock(&workq->lock, true);
    391391}
     
    422422 *                  until func() is entered.
    423423 * @param func      User supplied function to invoke in a worker thread.
    424  
     424
    425425 * @return false if work queue is shutting down; function is not
    426426 *               queued for further processing.
     
    442442 *                  until func() is entered.
    443443 * @param func      User supplied function to invoke in a worker thread.
    444  
     444
    445445 * @return false if work queue is shutting down; function is not
    446446 *               queued for further processing.
     
    467467 * @param func      User supplied function to invoke in a worker thread.
    468468 * @param can_block May adding this work item block?
    469  
     469
    470470 * @return false if work queue is shutting down; function is not
    471471 *               queued for further processing.
     
    476476{
    477477        assert(!workq_corrupted(workq));
    478        
     478
    479479        bool success = true;
    480480        signal_op_t signal_op = NULL;
    481        
     481
    482482        irq_spinlock_lock(&workq->lock, true);
    483        
     483
    484484        if (workq->stopping) {
    485485                success = false;
     
    489489                ++workq->item_cnt;
    490490                success = true;
    491                
     491
    492492                if (!booting) {
    493493                        signal_op = signal_worker_logic(workq, can_block);
     
    499499                }
    500500        }
    501        
     501
    502502        irq_spinlock_unlock(&workq->lock, true);
    503503
     
    505505                signal_op(workq);
    506506        }
    507        
     507
    508508        return success;
    509509}
     
    515515        work_item->cookie = WORK_ITEM_MAGIC;
    516516#endif
    517        
     517
    518518        link_initialize(&work_item->queue_link);
    519519        work_item->func = func;
     
    524524{
    525525        assert(irq_spinlock_locked(&workq->lock));
    526        
     526
    527527        /* Workers blocked are sleeping in the work function (ie not idle). */
    528528        assert(workq->blocked_worker_cnt <= workq->cur_worker_cnt);
    529529        /* Idle workers are waiting for more work to arrive in condvar_wait. */
    530530        assert(workq->idle_worker_cnt <= workq->cur_worker_cnt);
    531        
     531
    532532        /* Idle + blocked workers == sleeping worker threads. */
    533533        size_t sleeping_workers = workq->blocked_worker_cnt + workq->idle_worker_cnt;
    534        
     534
    535535        assert(sleeping_workers <= workq->cur_worker_cnt);
    536536        /* Workers pending activation are idle workers not yet given a time slice. */
    537537        assert(workq->activate_pending <= workq->idle_worker_cnt);
    538        
     538
    539539        /*
    540540         * Workers actively running the work func() this very moment and
     
    553553{
    554554        assert(irq_spinlock_locked(&workq->lock));
    555        
     555
    556556        /*
    557557         * Workers actively running the work func() and are neither blocked nor
     
    578578
    579579        condvar_signal(&workq->activate_worker);
    580        
     580
    581581        irq_spinlock_lock(&workq->lock, true);
    582582        assert(0 < workq->pending_op_cnt);
     
    597597        assert(!workq_corrupted(workq));
    598598        assert(irq_spinlock_locked(&workq->lock));
    599        
     599
    600600        /* Only signal workers if really necessary. */
    601601        signal_op_t signal_op = NULL;
     
    630630                        bool need_worker = (active < max_concurrent_workers)
    631631                                && (workq->cur_worker_cnt < max_worker_cnt);
    632                        
     632
    633633                        if (need_worker && can_block) {
    634634                                signal_op = add_worker_op;
     
    641641                                ++workq->cur_worker_cnt;
    642642                        }
    643                        
     643
    644644                        /*
    645645                         * We cannot create a new worker but we need one desperately
     
    648648                        if (need_worker && !can_block && 0 == active) {
    649649                                assert(0 == workq->idle_worker_cnt);
    650                                
     650
    651651                                irq_spinlock_lock(&nonblock_adder.lock, true);
    652652
     
    667667                signal_op = NULL;
    668668        }
    669        
     669
    670670        return signal_op;
    671671}
     
    682682                return;
    683683        }
    684        
     684
    685685        assert(arg != NULL);
    686        
     686
    687687        struct work_queue *workq = arg;
    688688        work_t *work_item;
    689        
     689
    690690        while (dequeue_work(workq, &work_item)) {
    691691                /* Copy the func field so func() can safely free work_item. */
     
    700700{
    701701        assert(!workq_corrupted(workq));
    702        
     702
    703703        irq_spinlock_lock(&workq->lock, true);
    704        
     704
    705705        /* Check if we should exit if load is low. */
    706706        if (!workq->stopping && worker_unnecessary(workq)) {
     
    710710                list_remove(&THREAD->workq_link);
    711711                irq_spinlock_unlock(&workq->lock, true);
    712                
     712
    713713                thread_detach(THREAD);
    714714                return false;
    715715        }
    716        
     716
    717717        bool stop = false;
    718        
     718
    719719        /* Wait for work to arrive. */
    720720        while (list_empty(&workq->queue) && !workq->stopping) {
    721721                cv_wait(workq);
    722                
     722
    723723                if (0 < workq->activate_pending)
    724724                        --workq->activate_pending;
     
    729729                link_t *work_link = list_first(&workq->queue);
    730730                *pwork_item = list_get_instance(work_link, work_t, queue_link);
    731                
     731
    732732#ifdef CONFIG_DEBUG
    733733                assert(!work_item_corrupted(*pwork_item));
     
    736736                list_remove(work_link);
    737737                --workq->item_cnt;
    738                
     738
    739739                stop = false;
    740740        } else {
     
    744744                stop = true;
    745745        }
    746        
     746
    747747        irq_spinlock_unlock(&workq->lock, true);
    748        
     748
    749749        return !stop;
    750750}
     
    754754{
    755755        assert(irq_spinlock_locked(&workq->lock));
    756        
     756
    757757        /* No work is pending. We don't need too many idle threads. */
    758758        if (list_empty(&workq->queue)) {
     
    775775        ++workq->idle_worker_cnt;
    776776        THREAD->workq_idling = true;
    777        
     777
    778778        /* Ignore lock ordering just here. */
    779779        assert(irq_spinlock_locked(&workq->lock));
    780        
     780
    781781        _condvar_wait_timeout_irq_spinlock(&workq->activate_worker,
    782782                &workq->lock, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
     
    784784        assert(!workq_corrupted(workq));
    785785        assert(irq_spinlock_locked(&workq->lock));
    786        
     786
    787787        THREAD->workq_idling = false;
    788788        --workq->idle_worker_cnt;
     
    803803                assert(THREAD != thread);
    804804                assert(!workq_corrupted(thread->workq));
    805                
     805
    806806                /* Protected by thread->lock */
    807807                thread->workq_blocked = false;
    808                
     808
    809809                irq_spinlock_lock(&thread->workq->lock, true);
    810810                --thread->workq->blocked_worker_cnt;
     
    823823                assert(!THREAD->workq_blocked);
    824824                assert(!workq_corrupted(THREAD->workq));
    825                
     825
    826826                THREAD->workq_blocked = true;
    827                
     827
    828828                irq_spinlock_lock(&THREAD->workq->lock, false);
    829829
    830830                ++THREAD->workq->blocked_worker_cnt;
    831                
     831
    832832                bool can_block = false;
    833833                signal_op_t op = signal_worker_logic(THREAD->workq, can_block);
    834                
     834
    835835                irq_spinlock_unlock(&THREAD->workq->lock, false);
    836                
     836
    837837                if (op) {
    838838                        assert(add_worker_noblock_op == op || signal_worker_op == op);
     
    856856        const char *load_str = worker_surplus ? "decreasing" :
    857857                (0 < workq->activate_pending) ? "increasing" : "stable";
    858        
     858
    859859        irq_spinlock_unlock(&workq->lock, true);
    860        
     860
    861861        printf(
    862862                "Configuration: max_worker_cnt=%zu, min_worker_cnt=%zu,\n"
     
    893893
    894894        irq_spinlock_lock(&info->lock, true);
    895        
     895
    896896        while (list_empty(&info->work_queues) && !stop) {
    897897                errno_t ret = _condvar_wait_timeout_irq_spinlock(&info->req_cv,
    898898                        &info->lock, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_INTERRUPTIBLE);
    899                
     899
    900900                stop = (ret == EINTR);
    901901        }
    902        
     902
    903903        if (!stop) {
    904904                *pworkq = list_get_instance(list_first(&info->work_queues),
     
    906906
    907907                assert(!workq_corrupted(*pworkq));
    908                
     908
    909909                list_remove(&(*pworkq)->nb_link);
    910910        }
    911        
     911
    912912        irq_spinlock_unlock(&info->lock, true);
    913        
     913
    914914        return !stop;
    915915}
     
    919919        nonblock_adder_t *info = arg;
    920920        struct work_queue *workq;
    921        
     921
    922922        while (dequeue_add_req(info, &workq)) {
    923923                add_worker(workq);
     
    931931        condvar_initialize(&nonblock_adder.req_cv);
    932932        list_initialize(&nonblock_adder.work_queues);
    933        
     933
    934934        nonblock_adder.thread = thread_create(thr_nonblock_add_worker,
    935935                &nonblock_adder, TASK, THREAD_FLAG_NONE, "kworkq-nb");
    936        
     936
    937937        if (nonblock_adder.thread) {
    938938                thread_ready(nonblock_adder.thread);
Note: See TracChangeset for help on using the changeset viewer.