Example #1
0
void Shutdown()
{
    std::lock_guard<std::mutex> lk(s_ts_write_lock);
    MoveEvents();
    ClearPendingEvents();
    UnregisterAllEvents();
}
Example #2
0
void Advance()
{
	MoveEvents();

	int cyclesExecuted = slicelength - DowncountToCycles(PowerPC::ppcState.downcount);
	globalTimer += cyclesExecuted;
	lastOCFactor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
	PowerPC::ppcState.downcount = CyclesToDowncount(slicelength);

	while (first && first->time <= globalTimer)
	{
		//LOG(POWERPC, "[Scheduler] %s     (%lld, %lld) ",
		//             event_types[first->type].name ? event_types[first->type].name : "?", (u64)globalTimer, (u64)first->time);
		Event* evt = first;
		first = first->next;
		event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
		FreeEvent(evt);
	}

	if (!first)
	{
		WARN_LOG(POWERPC, "WARNING - no events in queue. Setting downcount to 10000");
		PowerPC::ppcState.downcount += CyclesToDowncount(10000);
	}
	else
	{
		slicelength = (int)(first->time - globalTimer);
		if (slicelength > maxSliceLength)
			slicelength = maxSliceLength;
		PowerPC::ppcState.downcount = CyclesToDowncount(slicelength);
	}
}
Example #3
0
//This raise only the events required while the fifo is processing data
void ProcessFifoWaitEvents()
{
	if (Common::AtomicLoadAcquire(hasTsEvents))
		MoveEvents();

	if (!first)
		return;

	while (first)
	{
		if (first->time <= globalTimer)
		{
//			LOG(CPU, "[Scheduler] %s		 (%lld, %lld) ", 
//				first->name ? first->name : "?", (u64)globalTimer, (u64)first->time);
			Event* evt = first;
			first = first->next;
			event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
			FreeEvent(evt);
		}
		else
		{
			break;
		}
	}
}
Example #4
0
void Advance() {
    s64 cycles_executed = g_slice_length - Core::g_app_core->down_count;
    global_timer += cycles_executed;
    Core::g_app_core->down_count = g_slice_length;

    if (has_ts_events)
        MoveEvents();
    ProcessFifoWaitEvents();

    if (!first) {
        if (g_slice_length < 10000) {
            g_slice_length += 10000;
            Core::g_app_core->down_count += g_slice_length;
        }
    } else {
        // Note that events can eat cycles as well.
        int target = (int)(first->time - global_timer);
        if (target > MAX_SLICE_LENGTH)
            target = MAX_SLICE_LENGTH;

        const int diff = target - g_slice_length;
        g_slice_length += diff;
        Core::g_app_core->down_count += diff;
    }
    if (advance_callback)
        advance_callback(static_cast<int>(cycles_executed));
}
Example #5
0
void Advance()
{
	int cyclesExecuted = slicelength - currentMIPS->downcount;
	globalTimer += cyclesExecuted;
	currentMIPS->downcount = slicelength;

	if (Common::AtomicLoadAcquire(hasTsEvents))
		MoveEvents();
	ProcessFifoWaitEvents();

	if (!first)
	{
		// WARN_LOG(TIMER, "WARNING - no events in queue. Setting currentMIPS->downcount to 10000");
		currentMIPS->downcount += 10000;
		slicelength = 10000;
	}
	else
	{
		slicelength = (int)(first->time - globalTimer);
		if (slicelength > MAX_SLICE_LENGTH)
			slicelength = MAX_SLICE_LENGTH;
		currentMIPS->downcount = slicelength;
	}
	if (advanceCallback)
		advanceCallback(cyclesExecuted);
}
Example #6
0
void Advance()
{
	int cyclesExecuted = slicelength - currentMIPS->downcount;
	globalTimer += cyclesExecuted;
	currentMIPS->downcount = slicelength;

	if (Common::AtomicLoadAcquire(hasTsEvents))
		MoveEvents();
	ProcessFifoWaitEvents();

	if (!first)
	{
		// This should never happen in PPSSPP.
		// WARN_LOG_REPORT(TIME, "WARNING - no events in queue. Setting currentMIPS->downcount to 10000");
		if (slicelength < 10000) {
			slicelength += 10000;
			currentMIPS->downcount += slicelength;
		}
	}
	else
	{
		// Note that events can eat cycles as well.
		int target = (int)(first->time - globalTimer);
		if (target > MAX_SLICE_LENGTH)
			target = MAX_SLICE_LENGTH;

		const int diff = target - slicelength;
		slicelength += diff;
		currentMIPS->downcount += diff;
	}
	if (advanceCallback)
		advanceCallback(cyclesExecuted);
}
Example #7
0
void Advance() {
    MoveEvents();

    int cycles_executed = slice_length - downcount;
    global_timer += cycles_executed;
    slice_length = MAX_SLICE_LENGTH;

    is_global_timer_sane = true;

    while (!event_queue.empty() && event_queue.front().time <= global_timer) {
        Event evt = std::move(event_queue.front());
        std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<Event>());
        event_queue.pop_back();
        evt.type->callback(evt.userdata, global_timer - evt.time);
    }

    is_global_timer_sane = false;

    // Still events left (scheduled in the future)
    if (!event_queue.empty()) {
        slice_length = static_cast<int>(
            std::min<s64>(event_queue.front().time - global_timer, MAX_SLICE_LENGTH));
    }

    downcount = slice_length;
}
Example #8
0
void DoState(PointerWrap& p)
{
    std::lock_guard<std::mutex> lk(s_ts_write_lock);
    p.Do(g_slice_length);
    p.Do(g_global_timer);
    p.Do(s_idled_cycles);
    p.Do(s_fake_dec_start_value);
    p.Do(s_fake_dec_start_ticks);
    p.Do(g_fake_TB_start_value);
    p.Do(g_fake_TB_start_ticks);
    p.Do(s_last_OC_factor);
    g_last_OC_factor_inverted = 1.0f / s_last_OC_factor;
    p.Do(s_event_fifo_id);

    p.DoMarker("CoreTimingData");

    MoveEvents();
    p.DoEachElement(s_event_queue, [](PointerWrap& pw, Event& ev) {
        pw.Do(ev.time);
        pw.Do(ev.fifo_order);

        // this is why we can't have (nice things) pointers as userdata
        pw.Do(ev.userdata);

        // we can't savestate ev.type directly because events might not get registered in the same
        // order (or at all) every time.
        // so, we savestate the event's type's name, and derive ev.type from that when loading.
        std::string name;
        if (pw.GetMode() != PointerWrap::MODE_READ)
            name = *ev.type->name;

        pw.Do(name);
        if (pw.GetMode() == PointerWrap::MODE_READ)
        {
            auto itr = s_event_types.find(name);
            if (itr != s_event_types.end())
            {
                ev.type = &itr->second;
            }
            else
            {
                WARN_LOG(POWERPC,
                         "Lost event from savestate because its type, \"%s\", has not been registered.",
                         name.c_str());
                ev.type = s_ev_lost;
            }
        }
    });
    p.DoMarker("CoreTimingEvents");

    // When loading from a save state, we must assume the Event order is random and meaningless.
    // The exact layout of the heap in memory is implementation defined, therefore it is platform
    // and library version specific.
    if (p.GetMode() == PointerWrap::MODE_READ)
        std::make_heap(s_event_queue.begin(), s_event_queue.end(), std::greater<Event>());
}
Example #9
0
void Shutdown()
{
	std::lock_guard<std::mutex> lk(tsWriteLock);
	MoveEvents();
	ClearPendingEvents();
	UnregisterAllEvents();

	while (eventPool)
	{
		Event *ev = eventPool;
		eventPool = ev->next;
		delete ev;
	}
}
Example #10
0
void DoState(PointerWrap &p)
{
	std::lock_guard<std::mutex> lk(tsWriteLock);
	p.Do(slicelength);
	p.Do(globalTimer);
	p.Do(idledCycles);
	p.Do(fakeDecStartValue);
	p.Do(fakeDecStartTicks);
	p.Do(fakeTBStartValue);
	p.Do(fakeTBStartTicks);
	p.DoMarker("CoreTimingData");

	MoveEvents();

	p.DoLinkedList<BaseEvent, GetNewEvent, FreeEvent, EventDoState>(first);
	p.DoMarker("CoreTimingEvents");
}
Example #11
0
void Shutdown() {
    MoveEvents();
    ClearPendingEvents();
    UnregisterAllEvents();

    while (event_pool) {
        Event* event = event_pool;
        event_pool = event->next;
        delete event;
    }

    std::lock_guard<std::recursive_mutex> lock(external_event_section);
    while (event_ts_pool) {
        Event* event = event_ts_pool;
        event_ts_pool = event->next;
        delete event;
    }
}
Example #12
0
void Advance()
{
	MoveEvents();

	int cyclesExecuted = g_slicelength - DowncountToCycles(PowerPC::ppcState.downcount);
	g_globalTimer += cyclesExecuted;
	s_lastOCFactor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
	g_lastOCFactor_inverted = 1.0f / s_lastOCFactor;
	PowerPC::ppcState.downcount = CyclesToDowncount(g_slicelength);

	globalTimerIsSane = true;

	while (first && first->time <= g_globalTimer)
	{
		//LOG(POWERPC, "[Scheduler] %s     (%lld, %lld) ",
		//             event_types[first->type].name ? event_types[first->type].name : "?", (u64)g_globalTimer, (u64)first->time);
		Event* evt = first;
		first = first->next;
		event_types[evt->type].callback(evt->userdata, (int)(g_globalTimer - evt->time));
		FreeEvent(evt);
	}

	globalTimerIsSane = false;

	if (!first)
	{
		WARN_LOG(POWERPC, "WARNING - no events in queue. Setting downcount to 10000");
		PowerPC::ppcState.downcount += CyclesToDowncount(10000);
	}
	else
	{
		g_slicelength = (int)(first->time - g_globalTimer);
		if (g_slicelength > maxslicelength)
			g_slicelength = maxslicelength;
		PowerPC::ppcState.downcount = CyclesToDowncount(g_slicelength);
	}

	// Check for any external exceptions.
	// It's important to do this after processing events otherwise any exceptions will be delayed until the next slice:
	//        Pokemon Box refuses to boot if the first exception from the audio DMA is received late
	PowerPC::CheckExternalExceptions();
}
Example #13
0
void Advance()
{
	MoveEvents();

	int cyclesExecuted = slicelength - PowerPC::ppcState.downcount;
	globalTimer += cyclesExecuted;
	PowerPC::ppcState.downcount = slicelength;

	while (first)
	{
		if (first->time <= globalTimer)
		{
			//LOG(POWERPC, "[Scheduler] %s     (%lld, %lld) ",
			//             event_types[first->type].name ? event_types[first->type].name : "?", (u64)globalTimer, (u64)first->time);
			Event* evt = first;
			first = first->next;
			event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
			FreeEvent(evt);
		}
		else
		{
			break;
		}
	}

	if (!first)
	{
		WARN_LOG(POWERPC, "WARNING - no events in queue. Setting downcount to 10000");
		PowerPC::ppcState.downcount += 10000;
	}
	else
	{
		slicelength = (int)(first->time - globalTimer);
		if (slicelength > maxSliceLength)
			slicelength = maxSliceLength;
		PowerPC::ppcState.downcount = slicelength;
	}

	if (advanceCallback)
		advanceCallback(cyclesExecuted);
}
Example #14
0
void DoState(PointerWrap &p)
{
	std::lock_guard<std::mutex> lk(tsWriteLock);
	p.Do(g_slicelength);
	p.Do(g_globalTimer);
	p.Do(idledCycles);
	p.Do(fakeDecStartValue);
	p.Do(fakeDecStartTicks);
	p.Do(g_fakeTBStartValue);
	p.Do(g_fakeTBStartTicks);
	p.Do(s_lastOCFactor);
	if (p.GetMode() == PointerWrap::MODE_READ)
		g_lastOCFactor_inverted = 1.0f / s_lastOCFactor;

	p.DoMarker("CoreTimingData");

	MoveEvents();

	p.DoLinkedList<BaseEvent, GetNewEvent, FreeEvent, EventDoState>(first);
	p.DoMarker("CoreTimingEvents");
}
Example #15
0
void Shutdown()
{
	MoveEvents();
	ClearPendingEvents();
	UnregisterAllEvents();

	while(eventPool)
	{
		Event *ev = eventPool;
		eventPool = ev->next;
		delete ev;
	}

	std::lock_guard<std::recursive_mutex> lk(externalEventSection);
	while(eventTsPool)
	{
		Event *ev = eventTsPool;
		eventTsPool = ev->next;
		delete ev;
	}
}
Example #16
0
void Advance()
{
    MoveEvents();

    int cyclesExecuted = g_slice_length - DowncountToCycles(PowerPC::ppcState.downcount);
    g_global_timer += cyclesExecuted;
    s_last_OC_factor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
    g_last_OC_factor_inverted = 1.0f / s_last_OC_factor;
    g_slice_length = MAX_SLICE_LENGTH;

    s_is_global_timer_sane = true;

    while (!s_event_queue.empty() && s_event_queue.front().time <= g_global_timer)
    {
        Event evt = std::move(s_event_queue.front());
        std::pop_heap(s_event_queue.begin(), s_event_queue.end(), std::greater<Event>());
        s_event_queue.pop_back();
        // NOTICE_LOG(POWERPC, "[Scheduler] %-20s (%lld, %lld)", evt.type->name->c_str(),
        //            g_global_timer, evt.time);
        evt.type->callback(evt.userdata, g_global_timer - evt.time);
    }

    s_is_global_timer_sane = false;

    // Still events left (scheduled in the future)
    if (!s_event_queue.empty())
    {
        g_slice_length = static_cast<int>(
                             std::min<s64>(s_event_queue.front().time - g_global_timer, MAX_SLICE_LENGTH));
    }

    PowerPC::ppcState.downcount = CyclesToDowncount(g_slice_length);

    // Check for any external exceptions.
    // It's important to do this after processing events otherwise any exceptions will be delayed
    // until the next slice:
    //        Pokemon Box refuses to boot if the first exception from the audio DMA is received late
    PowerPC::CheckExternalExceptions();
}
Example #17
0
void Advance()
{
	MoveEvents();		

	int cyclesExecuted = slicelength - downcount;
	globalTimer += cyclesExecuted;
	downcount = slicelength;

	while (first)
	{
		if (first->time <= globalTimer)
		{
//			LOG(CPU, "[Scheduler] %s		 (%lld, %lld) ", 
//				first->name ? first->name : "?", (u64)globalTimer, (u64)first->time);
			Event* evt = first;
			first = first->next;
			event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
			FreeEvent(evt);
		}
		else
		{
			break;
		}
	}
	if (!first) 
	{
		// WARN_LOG(CPU, "WARNING - no events in queue. Setting downcount to 10000");
		downcount += 10000;
	}
	else
	{
		slicelength = (int)(first->time - globalTimer);
		if (slicelength > MAX_SLICE_LENGTH)
			slicelength = MAX_SLICE_LENGTH;
		downcount = slicelength;
	}
	if (advanceCallback)
		advanceCallback(cyclesExecuted);
}
Example #18
0
//This raise only the events required while the fifo is processing data
void ProcessFifoWaitEvents()
{
	MoveEvents();

	if (!first)
		return;

	while (first)
	{
		if (first->time <= globalTimer)
		{
			Event* evt = first;
			first = first->next;
			event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
			FreeEvent(evt);
		}
		else
		{
			break;
		}
	}	
}
Example #19
0
void RemoveAllEvents(int event_type)
{
	MoveEvents();
	RemoveEvent(event_type);
}
Example #20
0
void RemoveAllEvents(EventType* event_type)
{
    MoveEvents();
    RemoveEvent(event_type);
}
Example #21
0
void Shutdown() {
    MoveEvents();
    ClearPendingEvents();
    UnregisterAllEvents();
}
Example #22
0
void RemoveNormalAndThreadsafeEvent(const EventType* event_type) {
    MoveEvents();
    RemoveEvent(event_type);
}