Changeset a35b458 in mainline for kernel/generic/src/synch


Ignore:
Timestamp:
2018-03-02T20:10:49Z (7 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f1380b7
Parents:
3061bc1
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
Message:

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

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

Legend:

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

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

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

    r3061bc1 ra35b458  
    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 ra35b458  
    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 ra35b458  
    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.