Ignore:
File:
1 edited

Legend:

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

    r669f3d32 rcd3b380  
    4646#include <synch/spinlock.h>
    4747#include <synch/waitq.h>
    48 #include <synch/workqueue.h>
    49 #include <synch/rcu.h>
    5048#include <cpu.h>
    5149#include <str.h>
     
    194192        kmflags &= ~FRAME_HIGHMEM;
    195193       
    196         thread->kstack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | kmflags);
    197         if (!thread->kstack) {
     194        uintptr_t stack_phys =
     195            frame_alloc(STACK_FRAMES, kmflags, STACK_SIZE - 1);
     196        if (!stack_phys) {
    198197#ifdef CONFIG_FPU
    199198                if (thread->saved_fpu_context)
     
    203202        }
    204203       
     204        thread->kstack = (uint8_t *) PA2KA(stack_phys);
     205       
    205206#ifdef CONFIG_UDEBUG
    206207        mutex_initialize(&thread->udebug.lock, MUTEX_PASSIVE);
     
    218219        thr_destructor_arch(thread);
    219220       
    220         frame_free(KA2PA(thread->kstack));
     221        frame_free(KA2PA(thread->kstack), STACK_FRAMES);
    221222       
    222223#ifdef CONFIG_FPU
     
    262263}
    263264
    264 /** Invoked right before thread_ready() readies the thread. thread is locked. */
    265 static void before_thread_is_ready(thread_t *thread)
    266 {
    267         ASSERT(irq_spinlock_locked(&thread->lock));
    268         workq_before_thread_is_ready(thread);
    269 }
    270 
    271265/** Make thread ready
    272266 *
     
    281275       
    282276        ASSERT(thread->state != Ready);
    283 
    284         before_thread_is_ready(thread);
    285277       
    286278        int i = (thread->priority < RQ_COUNT - 1) ?
    287279            ++thread->priority : thread->priority;
    288 
    289         /* Check that thread->cpu is set whenever it needs to be. */
    290         ASSERT(thread->cpu != NULL ||
    291                 (!thread->wired && !thread->nomigrate && !thread->fpu_context_engaged));
    292 
    293         /*
    294          * Prefer to run on the same cpu as the last time. Used by wired
    295          * threads as well as threads with disabled migration.
    296          */
    297         cpu_t *cpu = thread->cpu;
    298         if (cpu == NULL)
     280       
     281        cpu_t *cpu;
     282        if (thread->wired || thread->nomigrate || thread->fpu_context_engaged) {
     283                ASSERT(thread->cpu != NULL);
     284                cpu = thread->cpu;
     285        } else
    299286                cpu = CPU;
    300287       
     
    390377        thread->task = task;
    391378       
    392         thread->workq = NULL;
    393        
    394379        thread->fpu_context_exists = false;
    395380        thread->fpu_context_engaged = false;
     
    406391        /* Might depend on previous initialization */
    407392        thread_create_arch(thread);
    408        
    409         rcu_thread_init(thread);
    410393       
    411394        if ((flags & THREAD_FLAG_NOATTACH) != THREAD_FLAG_NOATTACH)
     
    518501                         */
    519502                        ipc_cleanup();
    520                         futex_task_cleanup();
     503                        futex_cleanup();
    521504                        LOG("Cleanup of task %" PRIu64" completed.", TASK->taskid);
    522505                }
     
    538521        /* Not reached */
    539522        while (true);
    540 }
    541 
    542 /** Interrupts an existing thread so that it may exit as soon as possible.
    543  *
    544  * Threads that are blocked waiting for a synchronization primitive
    545  * are woken up with a return code of ESYNCH_INTERRUPTED if the
    546  * blocking call was interruptable. See waitq_sleep_timeout().
    547  *
    548  * The caller must guarantee the thread object is valid during the entire
    549  * function, eg by holding the threads_lock lock.
    550  *
    551  * Interrupted threads automatically exit when returning back to user space.
    552  *
    553  * @param thread A valid thread object. The caller must guarantee it
    554  *               will remain valid until thread_interrupt() exits.
    555  */
    556 void thread_interrupt(thread_t *thread)
    557 {
    558         ASSERT(thread != NULL);
    559        
    560         irq_spinlock_lock(&thread->lock, true);
    561        
    562         thread->interrupted = true;
    563         bool sleeping = (thread->state == Sleeping);
    564        
    565         irq_spinlock_unlock(&thread->lock, true);
    566        
    567         if (sleeping)
    568                 waitq_interrupt_sleep(thread);
    569 }
    570 
    571 /** Returns true if the thread was interrupted.
    572  *
    573  * @param thread A valid thread object. User must guarantee it will
    574  *               be alive during the entire call.
    575  * @return true if the thread was already interrupted via thread_interrupt().
    576  */
    577 bool thread_interrupted(thread_t *thread)
    578 {
    579         ASSERT(thread != NULL);
    580        
    581         bool interrupted;
    582        
    583         irq_spinlock_lock(&thread->lock, true);
    584         interrupted = thread->interrupted;
    585         irq_spinlock_unlock(&thread->lock, true);
    586        
    587         return interrupted;
    588523}
    589524
Note: See TracChangeset for help on using the changeset viewer.