Changeset 5663872 in mainline
- Timestamp:
- 2024-01-14T18:24:05Z (12 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)
- Location:
- kernel/generic
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/proc/thread.h
r4760793 r5663872 190 190 extern void thread_interrupt(thread_t *); 191 191 192 enum sleep_state { 193 SLEEP_INITIAL, 194 SLEEP_ASLEEP, 195 SLEEP_WOKE, 196 }; 197 192 198 typedef enum { 193 199 THREAD_OK, -
kernel/generic/src/proc/scheduler.c
r4760793 r5663872 443 443 after_thread_ran(); 444 444 445 int expected; 446 445 447 switch (THREAD->state) { 446 448 case Running: … … 462 464 463 465 case Sleeping: 464 /* 465 * Prefer the thread after it's woken up. 466 */ 467 THREAD->priority = -1; 468 irq_spinlock_unlock(&THREAD->lock, false); 466 expected = SLEEP_INITIAL; 467 468 /* Only set SLEEP_ASLEEP in sleep pad if it's still in initial state */ 469 if (atomic_compare_exchange_strong_explicit(&THREAD->sleep_state, 470 &expected, SLEEP_ASLEEP, 471 memory_order_acq_rel, memory_order_acquire)) { 472 473 /* Prefer the thread after it's woken up. */ 474 THREAD->priority = -1; 475 irq_spinlock_unlock(&THREAD->lock, false); 476 } else { 477 assert(expected == SLEEP_WOKE); 478 /* The thread has already been woken up, requeue immediately. */ 479 irq_spinlock_unlock(&THREAD->lock, false); 480 thread_ready(THREAD); 481 } 482 469 483 break; 470 484 -
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.