Changeset 5663872 in mainline for kernel/generic/src/proc/thread.c
- Timestamp:
- 2024-01-14T18:24:05Z (16 months ago)
- Branches:
- master
- Children:
- 23f36a3
- Parents:
- 4760793
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2023-02-18 13:37:30)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2024-01-14 18:24:05)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/proc/thread.c
r4760793 r5663872 82 82 }; 83 83 84 enum sleep_state {85 SLEEP_INITIAL,86 SLEEP_ASLEEP,87 SLEEP_WOKE,88 };89 90 84 /** Lock protecting the @c threads ordered dictionary . 91 85 * … … 579 573 } 580 574 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 another592 * 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 611 575 static void thread_wait_timeout_callback(void *arg) 612 576 { … … 649 613 timeout_t timeout; 650 614 615 /* Extra check to avoid going to scheduler if we don't need to. */ 616 if (atomic_load_explicit(&THREAD->sleep_state, memory_order_acquire) != 617 SLEEP_INITIAL) 618 return THREAD_WAIT_SUCCESS; 619 651 620 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 657 621 timeout_initialize(&timeout); 658 622 timeout_register_deadline(&timeout, deadline, … … 660 624 } 661 625 662 thread_wait_internal(); 626 ipl_t ipl = interrupts_disable(); 627 irq_spinlock_lock(&THREAD->lock, false); 628 THREAD->state = Sleeping; 629 scheduler_locked(ipl); 663 630 664 631 if (deadline != DEADLINE_NEVER && !timeout_unregister(&timeout)) { … … 674 641 675 642 int state = atomic_exchange_explicit(&thread->sleep_state, SLEEP_WOKE, 676 memory_order_ release);643 memory_order_acq_rel); 677 644 678 645 if (state == SLEEP_ASLEEP) {
Note:
See TracChangeset
for help on using the changeset viewer.