コード例 #1
0
ファイル: thread.cpp プロジェクト: Aurorer/citra
/// Stops the current thread
void StopThread(Handle handle, const char* reason) {
    Thread* thread = g_object_pool.GetFast<Thread>(handle);
    _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!");
    
    ChangeReadyState(thread, false);
    thread->status = THREADSTATUS_DORMANT;
    for (size_t i = 0; i < thread->waiting_threads.size(); ++i) {
        const Handle waiting_thread = thread->waiting_threads[i];
        if (VerifyWait(waiting_thread, WAITTYPE_THREADEND, handle)) {
            ResumeThreadFromWait(waiting_thread);
        }
    }
    thread->waiting_threads.clear();

    // Stopped threads are never waiting.
    thread->wait_type = WAITTYPE_NONE;
    thread->wait_handle = 0;
}
コード例 #2
0
ファイル: thread.cpp プロジェクト: Aurorer/citra
/// Reschedules to the next available thread (call after current thread is suspended)
void Reschedule() {
    Thread* prev = GetCurrentThread();
    Thread* next = NextThread();
    HLE::g_reschedule = false;
    if (next > 0) {
        INFO_LOG(KERNEL, "context switch 0x%08X -> 0x%08X", prev->GetHandle(), next->GetHandle());
        
        SwitchContext(next);

        // Hack - There is no mechanism yet to waken the primary thread if it has been put to sleep
        // by a simulated VBLANK thread switch. So, we'll just immediately set it to "ready" again.
        // This results in the current thread yielding on a VBLANK once, and then it will be 
        // immediately placed back in the queue for execution.
        if (prev->wait_type == WAITTYPE_VBLANK) {
            ResumeThreadFromWait(prev->GetHandle());
        }
    }
}
コード例 #3
0
ファイル: event.cpp プロジェクト: eriknelson/citra
/**
 * Signals an event
 * @param handle Handle to event to signal
 * @return Result of operation, 0 on success, otherwise error code
 */
Result SignalEvent(const Handle handle) {
    Event* evt = g_object_pool.GetFast<Event>(handle);
    _assert_msg_(KERNEL, (evt != nullptr), "called, but event is nullptr!");

    // Resume threads waiting for event to signal
    bool event_caught = false;
    for (size_t i = 0; i < evt->waiting_threads.size(); ++i) {
        ResumeThreadFromWait( evt->waiting_threads[i]);

        // If any thread is signalled awake by this event, assume the event was "caught" and reset
        // the event. This will result in the next thread waiting on the event to block. Otherwise,
        // the event will not be reset, and the next thread to call WaitSynchronization on it will
        // not block. Not sure if this is correct behavior, but it seems to work.
        event_caught = true;
    }
    evt->waiting_threads.clear();

    if (!evt->permanent_locked) {
        evt->locked = event_caught;
    }
    return 0;
}