Changeset c7ceacf in mainline for kernel/generic/src/proc/thread.c


Ignore:
Timestamp:
2024-01-15T14:54:17Z (12 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master
Children:
5861b60
Parents:
4760793 (diff), 151c050 (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.
Message:

Merge part of scheduler refactoring changes

A series of changes meant to remove unnecessary spinlock uses and
to improve understandability of the code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/proc/thread.c

    r4760793 rc7ceacf  
    8282};
    8383
    84 enum sleep_state {
    85         SLEEP_INITIAL,
    86         SLEEP_ASLEEP,
    87         SLEEP_WOKE,
    88 };
    89 
    9084/** Lock protecting the @c threads ordered dictionary .
    9185 *
     
    127121        void (*f)(void *) = THREAD->thread_code;
    128122        void *arg = THREAD->thread_arg;
    129         THREAD->last_cycle = get_cycle();
    130123
    131124        /* This is where each thread wakes up after its creation */
     
    320313
    321314        current_initialize((current_t *) thread->kstack);
    322 
    323         ipl_t ipl = interrupts_disable();
    324         thread->saved_ipl = interrupts_read();
    325         interrupts_restore(ipl);
    326315
    327316        str_cpy(thread->name, THREAD_NAME_BUFLEN, name);
     
    525514        }
    526515
    527         irq_spinlock_lock(&THREAD->lock, true);
    528         THREAD->state = Exiting;
    529         irq_spinlock_unlock(&THREAD->lock, true);
    530 
    531         scheduler();
    532 
    533         panic("should never be reached");
     516        scheduler_enter(Exiting);
     517        unreachable();
    534518}
    535519
     
    579563}
    580564
    581 static void thread_wait_internal(void)
    582 {
    583         assert(THREAD != NULL);
    584 
    585         ipl_t ipl = interrupts_disable();
    586 
    587         if (atomic_load(&haltstate))
    588                 halt();
    589 
    590         /*
    591          * Lock here to prevent a race between entering the scheduler and another
    592          * thread rescheduling this thread.
    593          */
    594         irq_spinlock_lock(&THREAD->lock, false);
    595 
    596         int expected = SLEEP_INITIAL;
    597 
    598         /* Only set SLEEP_ASLEEP in sleep pad if it's still in initial state */
    599         if (atomic_compare_exchange_strong_explicit(&THREAD->sleep_state, &expected,
    600             SLEEP_ASLEEP, memory_order_acq_rel, memory_order_acquire)) {
    601                 THREAD->state = Sleeping;
    602                 scheduler_locked(ipl);
    603         } else {
    604                 assert(expected == SLEEP_WOKE);
    605                 /* Return immediately. */
    606                 irq_spinlock_unlock(&THREAD->lock, false);
    607                 interrupts_restore(ipl);
    608         }
    609 }
    610 
    611565static void thread_wait_timeout_callback(void *arg)
    612566{
     
    649603        timeout_t timeout;
    650604
     605        /* Extra check to avoid going to scheduler if we don't need to. */
     606        if (atomic_load_explicit(&THREAD->sleep_state, memory_order_acquire) !=
     607            SLEEP_INITIAL)
     608                return THREAD_WAIT_SUCCESS;
     609
    651610        if (deadline != DEADLINE_NEVER) {
    652                 /* Extra check to avoid setting up a deadline if we don't need to. */
    653                 if (atomic_load_explicit(&THREAD->sleep_state, memory_order_acquire) !=
    654                     SLEEP_INITIAL)
    655                         return THREAD_WAIT_SUCCESS;
    656 
    657611                timeout_initialize(&timeout);
    658612                timeout_register_deadline(&timeout, deadline,
     
    660614        }
    661615
    662         thread_wait_internal();
     616        scheduler_enter(Sleeping);
    663617
    664618        if (deadline != DEADLINE_NEVER && !timeout_unregister(&timeout)) {
     
    674628
    675629        int state = atomic_exchange_explicit(&thread->sleep_state, SLEEP_WOKE,
    676             memory_order_release);
     630            memory_order_acq_rel);
    677631
    678632        if (state == SLEEP_ASLEEP) {
     
    770724
    771725        (void) waitq_sleep_timeout(&wq, usec);
     726}
     727
     728/** Allow other threads to run. */
     729void thread_yield(void)
     730{
     731        assert(THREAD != NULL);
     732        scheduler_enter(Running);
    772733}
    773734
Note: See TracChangeset for help on using the changeset viewer.