diff --git a/src/core/src/core_timing.cpp b/src/core/src/core_timing.cpp index 73dd9b549..78bbaafe2 100644 --- a/src/core/src/core_timing.cpp +++ b/src/core/src/core_timing.cpp @@ -1,20 +1,6 @@ -// Copyright (c) 2012- PPSSPP Project / Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. #include #include @@ -26,8 +12,6 @@ #include "core.h" #include "chunk_file.h" -//#include "HLE/sceKernelThread.h" - int g_clock_rate_arm11 = 268123480; // is this really necessary? @@ -39,23 +23,23 @@ namespace CoreTiming struct EventType { - EventType() {} + EventType() {} - EventType(TimedCallback cb, const char *n) - : callback(cb), name(n) {} + EventType(TimedCallback cb, const char *n) + : callback(cb), name(n) {} - TimedCallback callback; - const char *name; + TimedCallback callback; + const char *name; }; std::vector event_types; struct BaseEvent { - s64 time; - u64 userdata; - int type; -// Event *next; + s64 time; + u64 userdata; + int type; + // Event *next; }; typedef LinkedListItem Event; @@ -81,123 +65,123 @@ s64 idledCycles; static std::recursive_mutex externalEventSection; // Warning: not included in save state. -void (*advanceCallback)(int cyclesExecuted) = NULL; +void(*advanceCallback)(int cyclesExecuted) = NULL; void SetClockFrequencyMHz(int cpuMhz) { - g_clock_rate_arm11 = cpuMhz * 1000000; - // TODO: Rescale times of scheduled events? + g_clock_rate_arm11 = cpuMhz * 1000000; + // TODO: Rescale times of scheduled events? } int GetClockFrequencyMHz() { - return g_clock_rate_arm11 / 1000000; + return g_clock_rate_arm11 / 1000000; } Event* GetNewEvent() { - if(!eventPool) - return new Event; + if (!eventPool) + return new Event; - Event* ev = eventPool; - eventPool = ev->next; - return ev; + Event* ev = eventPool; + eventPool = ev->next; + return ev; } Event* GetNewTsEvent() { - allocatedTsEvents++; + allocatedTsEvents++; - if(!eventTsPool) - return new Event; + if (!eventTsPool) + return new Event; - Event* ev = eventTsPool; - eventTsPool = ev->next; - return ev; + Event* ev = eventTsPool; + eventTsPool = ev->next; + return ev; } void FreeEvent(Event* ev) { - ev->next = eventPool; - eventPool = ev; + ev->next = eventPool; + eventPool = ev; } void FreeTsEvent(Event* ev) { - ev->next = eventTsPool; - eventTsPool = ev; - allocatedTsEvents--; + ev->next = eventTsPool; + eventTsPool = ev; + allocatedTsEvents--; } int RegisterEvent(const char *name, TimedCallback callback) { - event_types.push_back(EventType(callback, name)); - return (int)event_types.size() - 1; + event_types.push_back(EventType(callback, name)); + return (int)event_types.size() - 1; } void AntiCrashCallback(u64 userdata, int cyclesLate) { - ERROR_LOG(TIME, "Savestate broken: an unregistered event was called."); - Core::Halt("invalid timing events"); + ERROR_LOG(TIME, "Savestate broken: an unregistered event was called."); + Core::Halt("invalid timing events"); } void RestoreRegisterEvent(int event_type, const char *name, TimedCallback callback) { - if (event_type >= (int) event_types.size()) - event_types.resize(event_type + 1, EventType(AntiCrashCallback, "INVALID EVENT")); + if (event_type >= (int)event_types.size()) + event_types.resize(event_type + 1, EventType(AntiCrashCallback, "INVALID EVENT")); - event_types[event_type] = EventType(callback, name); + event_types[event_type] = EventType(callback, name); } void UnregisterAllEvents() { - if (first) - PanicAlert("Cannot unregister events with events pending"); - event_types.clear(); + if (first) + PanicAlert("Cannot unregister events with events pending"); + event_types.clear(); } void Init() { - //currentMIPS->downcount = INITIAL_SLICE_LENGTH; - //slicelength = INITIAL_SLICE_LENGTH; - globalTimer = 0; - idledCycles = 0; - hasTsEvents = 0; + //currentMIPS->downcount = INITIAL_SLICE_LENGTH; + //slicelength = INITIAL_SLICE_LENGTH; + globalTimer = 0; + idledCycles = 0; + hasTsEvents = 0; } void Shutdown() { - MoveEvents(); - ClearPendingEvents(); - UnregisterAllEvents(); + MoveEvents(); + ClearPendingEvents(); + UnregisterAllEvents(); - while(eventPool) - { - Event *ev = eventPool; - eventPool = ev->next; - delete ev; - } + while (eventPool) + { + Event *ev = eventPool; + eventPool = ev->next; + delete ev; + } - std::lock_guard lk(externalEventSection); - while(eventTsPool) - { - Event *ev = eventTsPool; - eventTsPool = ev->next; - delete ev; - } + std::lock_guard lk(externalEventSection); + while (eventTsPool) + { + Event *ev = eventTsPool; + eventTsPool = ev->next; + delete ev; + } } u64 GetTicks() { - ERROR_LOG(TIME, "Unimplemented function!"); - return 0; - //return (u64)globalTimer + slicelength - currentMIPS->downcount; + ERROR_LOG(TIME, "Unimplemented function!"); + return 0; + //return (u64)globalTimer + slicelength - currentMIPS->downcount; } u64 GetIdleTicks() { - return (u64)idledCycles; + return (u64)idledCycles; } @@ -205,60 +189,60 @@ u64 GetIdleTicks() // schedule things to be executed on the main thread. void ScheduleEvent_Threadsafe(s64 cyclesIntoFuture, int event_type, u64 userdata) { - std::lock_guard lk(externalEventSection); - Event *ne = GetNewTsEvent(); - ne->time = GetTicks() + cyclesIntoFuture; - ne->type = event_type; - ne->next = 0; - ne->userdata = userdata; - if(!tsFirst) - tsFirst = ne; - if(tsLast) - tsLast->next = ne; - tsLast = ne; + std::lock_guard lk(externalEventSection); + Event *ne = GetNewTsEvent(); + ne->time = GetTicks() + cyclesIntoFuture; + ne->type = event_type; + ne->next = 0; + ne->userdata = userdata; + if (!tsFirst) + tsFirst = ne; + if (tsLast) + tsLast->next = ne; + tsLast = ne; - Common::AtomicStoreRelease(hasTsEvents, 1); + Common::AtomicStoreRelease(hasTsEvents, 1); } // Same as ScheduleEvent_Threadsafe(0, ...) EXCEPT if we are already on the CPU thread // in which case the event will get handled immediately, before returning. void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata) { - if(false) //Core::IsCPUThread()) - { - std::lock_guard lk(externalEventSection); - event_types[event_type].callback(userdata, 0); - } - else - ScheduleEvent_Threadsafe(0, event_type, userdata); + if (false) //Core::IsCPUThread()) + { + std::lock_guard lk(externalEventSection); + event_types[event_type].callback(userdata, 0); + } + else + ScheduleEvent_Threadsafe(0, event_type, userdata); } void ClearPendingEvents() { - while (first) - { - Event *e = first->next; - FreeEvent(first); - first = e; - } + while (first) + { + Event *e = first->next; + FreeEvent(first); + first = e; + } } void AddEventToQueue(Event* ne) { - Event* prev = NULL; - Event** pNext = &first; - for(;;) - { - Event*& next = *pNext; - if(!next || ne->time < next->time) - { - ne->next = next; - next = ne; - break; - } - prev = next; - pNext = &prev->next; - } + Event* prev = NULL; + Event** pNext = &first; + for (;;) + { + Event*& next = *pNext; + if (!next || ne->time < next->time) + { + ne->next = next; + next = ne; + break; + } + prev = next; + pNext = &prev->next; + } } // This must be run ONLY from within the cpu thread @@ -266,374 +250,374 @@ void AddEventToQueue(Event* ne) // than Advance void ScheduleEvent(s64 cyclesIntoFuture, int event_type, u64 userdata) { - Event *ne = GetNewEvent(); - ne->userdata = userdata; - ne->type = event_type; - ne->time = GetTicks() + cyclesIntoFuture; - AddEventToQueue(ne); + Event *ne = GetNewEvent(); + ne->userdata = userdata; + ne->type = event_type; + ne->time = GetTicks() + cyclesIntoFuture; + AddEventToQueue(ne); } // Returns cycles left in timer. s64 UnscheduleEvent(int event_type, u64 userdata) { - s64 result = 0; - if (!first) - return result; - while(first) - { - if (first->type == event_type && first->userdata == userdata) - { - result = first->time - globalTimer; + s64 result = 0; + if (!first) + return result; + while (first) + { + if (first->type == event_type && first->userdata == userdata) + { + result = first->time - globalTimer; - Event *next = first->next; - FreeEvent(first); - first = next; - } - else - { - break; - } - } - if (!first) - return result; - Event *prev = first; - Event *ptr = prev->next; - while (ptr) - { - if (ptr->type == event_type && ptr->userdata == userdata) - { - result = ptr->time - globalTimer; + Event *next = first->next; + FreeEvent(first); + first = next; + } + else + { + break; + } + } + if (!first) + return result; + Event *prev = first; + Event *ptr = prev->next; + while (ptr) + { + if (ptr->type == event_type && ptr->userdata == userdata) + { + result = ptr->time - globalTimer; - prev->next = ptr->next; - FreeEvent(ptr); - ptr = prev->next; - } - else - { - prev = ptr; - ptr = ptr->next; - } - } + prev->next = ptr->next; + FreeEvent(ptr); + ptr = prev->next; + } + else + { + prev = ptr; + ptr = ptr->next; + } + } - return result; + return result; } s64 UnscheduleThreadsafeEvent(int event_type, u64 userdata) { - s64 result = 0; - std::lock_guard lk(externalEventSection); - if (!tsFirst) - return result; - while(tsFirst) - { - if (tsFirst->type == event_type && tsFirst->userdata == userdata) - { - result = tsFirst->time - globalTimer; + s64 result = 0; + std::lock_guard lk(externalEventSection); + if (!tsFirst) + return result; + while (tsFirst) + { + if (tsFirst->type == event_type && tsFirst->userdata == userdata) + { + result = tsFirst->time - globalTimer; - Event *next = tsFirst->next; - FreeTsEvent(tsFirst); - tsFirst = next; - } - else - { - break; - } - } - if (!tsFirst) - { - tsLast = NULL; - return result; - } + Event *next = tsFirst->next; + FreeTsEvent(tsFirst); + tsFirst = next; + } + else + { + break; + } + } + if (!tsFirst) + { + tsLast = NULL; + return result; + } - Event *prev = tsFirst; - Event *ptr = prev->next; - while (ptr) - { - if (ptr->type == event_type && ptr->userdata == userdata) - { - result = ptr->time - globalTimer; + Event *prev = tsFirst; + Event *ptr = prev->next; + while (ptr) + { + if (ptr->type == event_type && ptr->userdata == userdata) + { + result = ptr->time - globalTimer; - prev->next = ptr->next; - if (ptr == tsLast) - tsLast = prev; - FreeTsEvent(ptr); - ptr = prev->next; - } - else - { - prev = ptr; - ptr = ptr->next; - } - } + prev->next = ptr->next; + if (ptr == tsLast) + tsLast = prev; + FreeTsEvent(ptr); + ptr = prev->next; + } + else + { + prev = ptr; + ptr = ptr->next; + } + } - return result; + return result; } // Warning: not included in save state. -void RegisterAdvanceCallback(void (*callback)(int cyclesExecuted)) +void RegisterAdvanceCallback(void(*callback)(int cyclesExecuted)) { - advanceCallback = callback; + advanceCallback = callback; } -bool IsScheduled(int event_type) +bool IsScheduled(int event_type) { - if (!first) - return false; - Event *e = first; - while (e) { - if (e->type == event_type) - return true; - e = e->next; - } - return false; + if (!first) + return false; + Event *e = first; + while (e) { + if (e->type == event_type) + return true; + e = e->next; + } + return false; } void RemoveEvent(int event_type) { - if (!first) - return; - while(first) - { - if (first->type == event_type) - { - Event *next = first->next; - FreeEvent(first); - first = next; - } - else - { - break; - } - } - if (!first) - return; - Event *prev = first; - Event *ptr = prev->next; - while (ptr) - { - if (ptr->type == event_type) - { - prev->next = ptr->next; - FreeEvent(ptr); - ptr = prev->next; - } - else - { - prev = ptr; - ptr = ptr->next; - } - } + if (!first) + return; + while (first) + { + if (first->type == event_type) + { + Event *next = first->next; + FreeEvent(first); + first = next; + } + else + { + break; + } + } + if (!first) + return; + Event *prev = first; + Event *ptr = prev->next; + while (ptr) + { + if (ptr->type == event_type) + { + prev->next = ptr->next; + FreeEvent(ptr); + ptr = prev->next; + } + else + { + prev = ptr; + ptr = ptr->next; + } + } } void RemoveThreadsafeEvent(int event_type) { - std::lock_guard lk(externalEventSection); - if (!tsFirst) - { - return; - } - while(tsFirst) - { - if (tsFirst->type == event_type) - { - Event *next = tsFirst->next; - FreeTsEvent(tsFirst); - tsFirst = next; - } - else - { - break; - } - } - if (!tsFirst) - { - tsLast = NULL; - return; - } - Event *prev = tsFirst; - Event *ptr = prev->next; - while (ptr) - { - if (ptr->type == event_type) - { - prev->next = ptr->next; - if (ptr == tsLast) - tsLast = prev; - FreeTsEvent(ptr); - ptr = prev->next; - } - else - { - prev = ptr; - ptr = ptr->next; - } - } + std::lock_guard lk(externalEventSection); + if (!tsFirst) + { + return; + } + while (tsFirst) + { + if (tsFirst->type == event_type) + { + Event *next = tsFirst->next; + FreeTsEvent(tsFirst); + tsFirst = next; + } + else + { + break; + } + } + if (!tsFirst) + { + tsLast = NULL; + return; + } + Event *prev = tsFirst; + Event *ptr = prev->next; + while (ptr) + { + if (ptr->type == event_type) + { + prev->next = ptr->next; + if (ptr == tsLast) + tsLast = prev; + FreeTsEvent(ptr); + ptr = prev->next; + } + else + { + prev = ptr; + ptr = ptr->next; + } + } } void RemoveAllEvents(int event_type) { - RemoveThreadsafeEvent(event_type); - RemoveEvent(event_type); + RemoveThreadsafeEvent(event_type); + RemoveEvent(event_type); } //This raise only the events required while the fifo is processing data void ProcessFifoWaitEvents() { - while (first) - { - if (first->time <= globalTimer) - { -// LOG(TIMER, "[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; - } - } + while (first) + { + if (first->time <= globalTimer) + { + // LOG(TIMER, "[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; + } + } } void MoveEvents() { - Common::AtomicStoreRelease(hasTsEvents, 0); + Common::AtomicStoreRelease(hasTsEvents, 0); - std::lock_guard lk(externalEventSection); - // Move events from async queue into main queue - while (tsFirst) - { - Event *next = tsFirst->next; - AddEventToQueue(tsFirst); - tsFirst = next; - } - tsLast = NULL; + std::lock_guard lk(externalEventSection); + // Move events from async queue into main queue + while (tsFirst) + { + Event *next = tsFirst->next; + AddEventToQueue(tsFirst); + tsFirst = next; + } + tsLast = NULL; - // Move free events to threadsafe pool - while(allocatedTsEvents > 0 && eventPool) - { - Event *ev = eventPool; - eventPool = ev->next; - ev->next = eventTsPool; - eventTsPool = ev; - allocatedTsEvents--; - } + // Move free events to threadsafe pool + while (allocatedTsEvents > 0 && eventPool) + { + Event *ev = eventPool; + eventPool = ev->next; + ev->next = eventTsPool; + eventTsPool = ev; + allocatedTsEvents--; + } } void Advance() { - ERROR_LOG(TIME, "Unimplemented function!"); - //int cyclesExecuted = slicelength - currentMIPS->downcount; - //globalTimer += cyclesExecuted; - //currentMIPS->downcount = slicelength; + ERROR_LOG(TIME, "Unimplemented function!"); + //int cyclesExecuted = slicelength - currentMIPS->downcount; + //globalTimer += cyclesExecuted; + //currentMIPS->downcount = slicelength; - //if (Common::AtomicLoadAcquire(hasTsEvents)) - // MoveEvents(); - //ProcessFifoWaitEvents(); + //if (Common::AtomicLoadAcquire(hasTsEvents)) + // MoveEvents(); + //ProcessFifoWaitEvents(); - //if (!first) - //{ - // // WARN_LOG(TIMER, "WARNING - no events in queue. Setting currentMIPS->downcount to 10000"); - // currentMIPS->downcount += 10000; - //} - //else - //{ - // slicelength = (int)(first->time - globalTimer); - // if (slicelength > MAX_SLICE_LENGTH) - // slicelength = MAX_SLICE_LENGTH; - // currentMIPS->downcount = slicelength; - //} - //if (advanceCallback) - // advanceCallback(cyclesExecuted); + //if (!first) + //{ + // // WARN_LOG(TIMER, "WARNING - no events in queue. Setting currentMIPS->downcount to 10000"); + // currentMIPS->downcount += 10000; + //} + //else + //{ + // slicelength = (int)(first->time - globalTimer); + // if (slicelength > MAX_SLICE_LENGTH) + // slicelength = MAX_SLICE_LENGTH; + // currentMIPS->downcount = slicelength; + //} + //if (advanceCallback) + // advanceCallback(cyclesExecuted); } void LogPendingEvents() { - Event *ptr = first; - while (ptr) - { - //INFO_LOG(TIMER, "PENDING: Now: %lld Pending: %lld Type: %d", globalTimer, ptr->time, ptr->type); - ptr = ptr->next; - } + Event *ptr = first; + while (ptr) + { + //INFO_LOG(TIMER, "PENDING: Now: %lld Pending: %lld Type: %d", globalTimer, ptr->time, ptr->type); + ptr = ptr->next; + } } void Idle(int maxIdle) { - ERROR_LOG(TIME, "Unimplemented function!"); - //int cyclesDown = currentMIPS->downcount; - //if (maxIdle != 0 && cyclesDown > maxIdle) - // cyclesDown = maxIdle; + ERROR_LOG(TIME, "Unimplemented function!"); + //int cyclesDown = currentMIPS->downcount; + //if (maxIdle != 0 && cyclesDown > maxIdle) + // cyclesDown = maxIdle; - //if (first && cyclesDown > 0) - //{ - // int cyclesExecuted = slicelength - currentMIPS->downcount; - // int cyclesNextEvent = (int) (first->time - globalTimer); + //if (first && cyclesDown > 0) + //{ + // int cyclesExecuted = slicelength - currentMIPS->downcount; + // int cyclesNextEvent = (int) (first->time - globalTimer); - // if (cyclesNextEvent < cyclesExecuted + cyclesDown) - // { - // cyclesDown = cyclesNextEvent - cyclesExecuted; - // // Now, now... no time machines, please. - // if (cyclesDown < 0) - // cyclesDown = 0; - // } - //} + // if (cyclesNextEvent < cyclesExecuted + cyclesDown) + // { + // cyclesDown = cyclesNextEvent - cyclesExecuted; + // // Now, now... no time machines, please. + // if (cyclesDown < 0) + // cyclesDown = 0; + // } + //} - //INFO_LOG(TIME, "Idle for %i cycles! (%f ms)", cyclesDown, cyclesDown / (float)(g_clock_rate_arm11 * 0.001f)); + //INFO_LOG(TIME, "Idle for %i cycles! (%f ms)", cyclesDown, cyclesDown / (float)(g_clock_rate_arm11 * 0.001f)); - //idledCycles += cyclesDown; - //currentMIPS->downcount -= cyclesDown; - //if (currentMIPS->downcount == 0) - // currentMIPS->downcount = -1; + //idledCycles += cyclesDown; + //currentMIPS->downcount -= cyclesDown; + //if (currentMIPS->downcount == 0) + // currentMIPS->downcount = -1; } std::string GetScheduledEventsSummary() { - Event *ptr = first; - std::string text = "Scheduled events\n"; - text.reserve(1000); - while (ptr) - { - unsigned int t = ptr->type; - if (t >= event_types.size()) - PanicAlert("Invalid event type"); // %i", t); - const char *name = event_types[ptr->type].name; - if (!name) - name = "[unknown]"; - char temp[512]; - sprintf(temp, "%s : %i %08x%08x\n", name, (int)ptr->time, (u32)(ptr->userdata >> 32), (u32)(ptr->userdata)); - text += temp; - ptr = ptr->next; - } - return text; + Event *ptr = first; + std::string text = "Scheduled events\n"; + text.reserve(1000); + while (ptr) + { + unsigned int t = ptr->type; + if (t >= event_types.size()) + PanicAlert("Invalid event type"); // %i", t); + const char *name = event_types[ptr->type].name; + if (!name) + name = "[unknown]"; + char temp[512]; + sprintf(temp, "%s : %i %08x%08x\n", name, (int)ptr->time, (u32)(ptr->userdata >> 32), (u32)(ptr->userdata)); + text += temp; + ptr = ptr->next; + } + return text; } void Event_DoState(PointerWrap &p, BaseEvent *ev) { - p.Do(*ev); + p.Do(*ev); } void DoState(PointerWrap &p) { - std::lock_guard lk(externalEventSection); + std::lock_guard lk(externalEventSection); - auto s = p.Section("CoreTiming", 1); - if (!s) - return; + auto s = p.Section("CoreTiming", 1); + if (!s) + return; - int n = (int) event_types.size(); - p.Do(n); - // These (should) be filled in later by the modules. - event_types.resize(n, EventType(AntiCrashCallback, "INVALID EVENT")); + int n = (int)event_types.size(); + p.Do(n); + // These (should) be filled in later by the modules. + event_types.resize(n, EventType(AntiCrashCallback, "INVALID EVENT")); - p.DoLinkedList(first, (Event **) NULL); - p.DoLinkedList(tsFirst, &tsLast); + p.DoLinkedList(first, (Event **)NULL); + p.DoLinkedList(tsFirst, &tsLast); - p.Do(g_clock_rate_arm11); - p.Do(slicelength); - p.Do(globalTimer); - p.Do(idledCycles); + p.Do(g_clock_rate_arm11); + p.Do(slicelength); + p.Do(globalTimer); + p.Do(idledCycles); } } // namespace diff --git a/src/core/src/core_timing.h b/src/core/src/core_timing.h index 1ef17f6f8..b62acea6c 100644 --- a/src/core/src/core_timing.h +++ b/src/core/src/core_timing.h @@ -1,22 +1,8 @@ -// Copyright (c) 2012- PPSSPP Project / Dolphin Project. +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#ifndef CORE_CORE_TIMING_H_ -#define CORE_CORE_TIMING_H_ +#pragma once // This is a system to schedule events into the emulated machine's future. Time is measured // in main CPU clock cycles. @@ -38,88 +24,86 @@ class PointerWrap; extern int g_clock_rate_arm11; inline s64 msToCycles(int ms) { - return g_clock_rate_arm11 / 1000 * ms; + return g_clock_rate_arm11 / 1000 * ms; } inline s64 msToCycles(float ms) { - return (s64)(g_clock_rate_arm11 * ms * (0.001f)); + return (s64)(g_clock_rate_arm11 * ms * (0.001f)); } inline s64 msToCycles(double ms) { - return (s64)(g_clock_rate_arm11 * ms * (0.001)); + return (s64)(g_clock_rate_arm11 * ms * (0.001)); } inline s64 usToCycles(float us) { - return (s64)(g_clock_rate_arm11 * us * (0.000001f)); + return (s64)(g_clock_rate_arm11 * us * (0.000001f)); } inline s64 usToCycles(int us) { - return (g_clock_rate_arm11 / 1000000 * (s64)us); + return (g_clock_rate_arm11 / 1000000 * (s64)us); } inline s64 usToCycles(s64 us) { - return (g_clock_rate_arm11 / 1000000 * us); + return (g_clock_rate_arm11 / 1000000 * us); } inline s64 usToCycles(u64 us) { - return (s64)(g_clock_rate_arm11 / 1000000 * us); + return (s64)(g_clock_rate_arm11 / 1000000 * us); } inline s64 cyclesToUs(s64 cycles) { - return cycles / (g_clock_rate_arm11 / 1000000); + return cycles / (g_clock_rate_arm11 / 1000000); } -namespace CoreTiming -{ - void Init(); - void Shutdown(); +namespace CoreTiming { - typedef void (*TimedCallback)(u64 userdata, int cyclesLate); +void Init(); +void Shutdown(); - u64 GetTicks(); - u64 GetIdleTicks(); +typedef void(*TimedCallback)(u64 userdata, int cyclesLate); - // Returns the event_type identifier. - int RegisterEvent(const char *name, TimedCallback callback); - // For save states. - void RestoreRegisterEvent(int event_type, const char *name, TimedCallback callback); - void UnregisterAllEvents(); +u64 GetTicks(); +u64 GetIdleTicks(); - // userdata MAY NOT CONTAIN POINTERS. userdata might get written and reloaded from disk, - // when we implement state saves. - void ScheduleEvent(s64 cyclesIntoFuture, int event_type, u64 userdata=0); - void ScheduleEvent_Threadsafe(s64 cyclesIntoFuture, int event_type, u64 userdata=0); - void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata=0); - s64 UnscheduleEvent(int event_type, u64 userdata); - s64 UnscheduleThreadsafeEvent(int event_type, u64 userdata); +// Returns the event_type identifier. +int RegisterEvent(const char *name, TimedCallback callback); +// For save states. +void RestoreRegisterEvent(int event_type, const char *name, TimedCallback callback); +void UnregisterAllEvents(); - void RemoveEvent(int event_type); - void RemoveThreadsafeEvent(int event_type); - void RemoveAllEvents(int event_type); - bool IsScheduled(int event_type); - void Advance(); - void MoveEvents(); - void ProcessFifoWaitEvents(); +// userdata MAY NOT CONTAIN POINTERS. userdata might get written and reloaded from disk, +// when we implement state saves. +void ScheduleEvent(s64 cyclesIntoFuture, int event_type, u64 userdata = 0); +void ScheduleEvent_Threadsafe(s64 cyclesIntoFuture, int event_type, u64 userdata = 0); +void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata = 0); +s64 UnscheduleEvent(int event_type, u64 userdata); +s64 UnscheduleThreadsafeEvent(int event_type, u64 userdata); - // Pretend that the main CPU has executed enough cycles to reach the next event. - void Idle(int maxIdle = 0); +void RemoveEvent(int event_type); +void RemoveThreadsafeEvent(int event_type); +void RemoveAllEvents(int event_type); +bool IsScheduled(int event_type); +void Advance(); +void MoveEvents(); +void ProcessFifoWaitEvents(); - // Clear all pending events. This should ONLY be done on exit or state load. - void ClearPendingEvents(); +// Pretend that the main CPU has executed enough cycles to reach the next event. +void Idle(int maxIdle = 0); - void LogPendingEvents(); +// Clear all pending events. This should ONLY be done on exit or state load. +void ClearPendingEvents(); - // Warning: not included in save states. - void RegisterAdvanceCallback(void (*callback)(int cyclesExecuted)); +void LogPendingEvents(); - std::string GetScheduledEventsSummary(); +// Warning: not included in save states. +void RegisterAdvanceCallback(void(*callback)(int cyclesExecuted)); - void DoState(PointerWrap &p); +std::string GetScheduledEventsSummary(); - void SetClockFrequencyMHz(int cpuMhz); - int GetClockFrequencyMHz(); - extern int slicelength; +void DoState(PointerWrap &p); + +void SetClockFrequencyMHz(int cpuMhz); +int GetClockFrequencyMHz(); +extern int slicelength; }; // namespace - -#endif // CORE_CORE_TIMING_H_