Exemple #1
0
void remove_thread(unsigned int thread_id)
#endif
{
    struct thread_entry *current = cores[CURRENT_CORE].running;
    struct thread_entry *thread = thread_id_entry(thread_id);

    SDL_Thread *t;
    SDL_sem *s;

    if (thread_id != THREAD_ID_CURRENT && thread->id != thread_id)
        return;

    int oldlevel = disable_irq_save();

    t = thread->context.t;
    s = thread->context.s;
    thread->context.t = NULL;

    if (thread != current)
    {
        switch (thread->state)
        {
        case STATE_BLOCKED:
        case STATE_BLOCKED_W_TMO:
            /* Remove thread from object it's waiting on */
            remove_from_list_l(thread->bqp, thread);

#ifdef HAVE_WAKEUP_EXT_CB
            if (thread->wakeup_ext_cb != NULL)
                thread->wakeup_ext_cb(thread);
#endif
            break;
        }

        SDL_SemPost(s);
    }

    THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n",
        thread - threads, THREAD_SDL_GET_NAME(thread));

    new_thread_id(thread->id, thread);
    thread->state = STATE_KILLED;
    thread_queue_wake(&thread->queue);

    SDL_DestroySemaphore(s);

    if (thread == current)
    {
        /* Do a graceful exit - perform the longjmp back into the thread
           function to return */
        restore_irq(oldlevel);
        longjmp(thread_jmpbufs[current - threads], 1);
    }

    SDL_KillThread(t);
    restore_irq(oldlevel);
}
  VM* SharedState::new_vm(const char* name) {
    utilities::thread::SpinLock::LockGuard guard(vm_lock_);

    // TODO calculate the thread id by finding holes in the
    // field of ids, so we reuse ids.
    uint32_t id = new_thread_id();

    VM* vm = new VM(id, *this, name);
    threads_.push_back(vm);

    // If there is no root vm, then the first one created becomes it.
    if(!root_vm_) root_vm_ = vm;

    return vm;
  }
Exemple #3
0
  VM* SharedState::new_vm() {
    uint32_t id = new_thread_id();

    SYNC_TL;

    // TODO calculate the thread id by finding holes in the
    // field of ids, so we reuse ids.

    VM* vm = new VM(id, *this);
    threads_.push_back(vm);

    this->ref();

    // If there is no root vm, then the first one created becomes it.
    if(!root_vm_) root_vm_ = vm;
    return vm;
  }
Exemple #4
0
void remove_thread(unsigned int thread_id)
#endif
{
    struct thread_entry *current = cores[CURRENT_CORE].running;
    struct thread_entry *thread = thread_id_entry(thread_id);

    SDL_Thread *t;
    SDL_sem *s;

    if (thread_id != THREAD_ID_CURRENT && thread->id != thread_id)
        return;

    int oldlevel = disable_irq_save();

    t = thread->context.t;
    s = thread->context.s;

    /* Wait the last thread here and keep this one or SDL will leak it since
     * it doesn't free its own library allocations unless a wait is performed.
     * Such behavior guards against the memory being invalid by the time
     * SDL_WaitThread is reached and also against two different threads having
     * the same pointer. It also makes SDL_WaitThread a non-concurrent function.
     *
     * However, see more below about SDL_KillThread.
     */
    SDL_WaitThread(thread->context.told, NULL);

    thread->context.t = NULL;
    thread->context.s = NULL;
    thread->context.told = t;

    if (thread != current)
    {
        switch (thread->state)
        {
        case STATE_BLOCKED:
        case STATE_BLOCKED_W_TMO:
            /* Remove thread from object it's waiting on */
            remove_from_list_l(thread->bqp, thread);

#ifdef HAVE_WAKEUP_EXT_CB
            if (thread->wakeup_ext_cb != NULL)
                thread->wakeup_ext_cb(thread);
#endif
            break;
        }

        SDL_SemPost(s);
    }

    THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n",
                      thread - threads, THREAD_SDL_GET_NAME(thread));

    new_thread_id(thread->id, thread);
    thread->state = STATE_KILLED;
    thread_queue_wake(&thread->queue);

    SDL_DestroySemaphore(s);

    if (thread == current)
    {
        /* Do a graceful exit - perform the longjmp back into the thread
           function to return */
        restore_irq(oldlevel);
        longjmp(thread_jmpbufs[current - threads], 1);
    }

    /* SDL_KillThread frees the old pointer too because it uses SDL_WaitThread
     * to wait for the host to remove it. */
    thread->context.told = NULL;
    SDL_KillThread(t);
    restore_irq(oldlevel);
}