Ignore:
File:
1 edited

Legend:

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

    rf22dc820 r669f3d32  
    4646#include <synch/spinlock.h>
    4747#include <synch/waitq.h>
     48#include <synch/workqueue.h>
     49#include <synch/rcu.h>
    4850#include <cpu.h>
    4951#include <str.h>
     
    260262}
    261263
     264/** Invoked right before thread_ready() readies the thread. thread is locked. */
     265static 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
    262271/** Make thread ready
    263272 *
     
    272281       
    273282        ASSERT(thread->state != Ready);
     283
     284        before_thread_is_ready(thread);
    274285       
    275286        int i = (thread->priority < RQ_COUNT - 1) ?
    276287            ++thread->priority : thread->priority;
    277        
    278         cpu_t *cpu;
    279         if (thread->wired || thread->nomigrate || thread->fpu_context_engaged) {
    280                 ASSERT(thread->cpu != NULL);
    281                 cpu = thread->cpu;
    282         } else
     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)
    283299                cpu = CPU;
    284300       
     
    374390        thread->task = task;
    375391       
     392        thread->workq = NULL;
     393       
    376394        thread->fpu_context_exists = false;
    377395        thread->fpu_context_engaged = false;
     
    388406        /* Might depend on previous initialization */
    389407        thread_create_arch(thread);
     408       
     409        rcu_thread_init(thread);
    390410       
    391411        if ((flags & THREAD_FLAG_NOATTACH) != THREAD_FLAG_NOATTACH)
     
    498518                         */
    499519                        ipc_cleanup();
    500                         futex_cleanup();
     520                        futex_task_cleanup();
    501521                        LOG("Cleanup of task %" PRIu64" completed.", TASK->taskid);
    502522                }
     
    518538        /* Not reached */
    519539        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 */
     556void 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 */
     577bool 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;
    520588}
    521589
Note: See TracChangeset for help on using the changeset viewer.