Ignore:
File:
1 edited

Legend:

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

    rc7326f21 rb169619  
    6262#include <arch/faddr.h>
    6363#include <atomic.h>
    64 #include <mem.h>
     64#include <memw.h>
    6565#include <stdio.h>
    6666#include <stdlib.h>
     
    231231        irq_spinlock_lock(&thread->lock, true);
    232232        thread->cpu = cpu;
    233         thread->wired = true;
     233        thread->nomigrate++;
    234234        irq_spinlock_unlock(&thread->lock, true);
    235235}
     
    259259            ++thread->priority : thread->priority;
    260260
    261         cpu_t *cpu;
    262         if (thread->wired || thread->nomigrate || thread->fpu_context_engaged) {
    263                 /* Cannot ready to another CPU */
    264                 assert(thread->cpu != NULL);
    265                 cpu = thread->cpu;
    266         } else if (thread->stolen) {
    267                 /* Ready to the stealing CPU */
    268                 cpu = CPU;
    269         } else if (thread->cpu) {
    270                 /* Prefer the CPU on which the thread ran last */
    271                 assert(thread->cpu != NULL);
    272                 cpu = thread->cpu;
    273         } else {
    274                 cpu = CPU;
    275         }
     261        /* Prefer the CPU on which the thread ran last */
     262        cpu_t *cpu = thread->cpu ? thread->cpu : CPU;
    276263
    277264        thread->state = Ready;
     
    348335        thread->priority = -1;          /* Start in rq[0] */
    349336        thread->cpu = NULL;
    350         thread->wired = false;
    351337        thread->stolen = false;
    352338        thread->uspace =
     
    369355
    370356        thread->fpu_context_exists = false;
    371         thread->fpu_context_engaged = false;
    372357
    373358        odlink_initialize(&thread->lthreads);
     
    426411
    427412        assert((thread->state == Exiting) || (thread->state == Lingering));
    428         assert(thread->cpu);
    429413
    430414        /* Clear cpu->fpu_owner if set to this thread. */
    431         irq_spinlock_lock(&thread->cpu->lock, false);
    432         if (thread->cpu->fpu_owner == thread)
    433                 thread->cpu->fpu_owner = NULL;
    434         irq_spinlock_unlock(&thread->cpu->lock, false);
     415#ifdef CONFIG_FPU_LAZY
     416        if (thread->cpu) {
     417                /*
     418                 * We need to lock for this because the old CPU can concurrently try
     419                 * to dump this thread's FPU state, in which case we need to wait for
     420                 * it to finish. An atomic compare-and-swap wouldn't be enough.
     421                 */
     422                irq_spinlock_lock(&thread->cpu->fpu_lock, false);
     423
     424                thread_t *owner = atomic_load_explicit(&thread->cpu->fpu_owner,
     425                    memory_order_relaxed);
     426
     427                if (owner == thread) {
     428                        atomic_store_explicit(&thread->cpu->fpu_owner, NULL,
     429                            memory_order_relaxed);
     430                }
     431
     432                irq_spinlock_unlock(&thread->cpu->fpu_lock, false);
     433        }
     434#endif
    435435
    436436        interrupts_restore(ipl);
Note: See TracChangeset for help on using the changeset viewer.