From b7c398574f88fa1befece926a07b45f5239fef88 Mon Sep 17 00:00:00 2001 From: donkopunchstania Date: Wed, 25 Feb 2009 07:06:02 +0000 Subject: [PATCH] Memory pools are set up in core timing to avoid frequent calls to new and delete. This reduces memory usage and gives a very minor speed boost in windows debug. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2430 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/Plugin.h | 2 +- Source/Core/Core/Src/CoreTiming.cpp | 79 +++++++++++++++++++++++++---- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/Source/Core/Common/Src/Plugin.h b/Source/Core/Common/Src/Plugin.h index 7018ee54ec..5175c53513 100644 --- a/Source/Core/Common/Src/Plugin.h +++ b/Source/Core/Common/Src/Plugin.h @@ -41,7 +41,7 @@ public: // This functions is only used when CPlugin is called directly, when a parent class like PluginVideo // is called its own IsValid() will be called. virtual bool IsValid() { return valid; }; - std::string GetFilename() const { return Filename; } + const std::string& GetFilename() const { return Filename; } bool GetInfo(PLUGIN_INFO& _pluginInfo); void SetGlobals(PLUGIN_GLOBALS* _PluginGlobals); void *LoadSymbol(const char *sym); diff --git a/Source/Core/Core/Src/CoreTiming.cpp b/Source/Core/Core/Src/CoreTiming.cpp index 5dcec626a9..7e53ac6b8b 100644 --- a/Source/Core/Core/Src/CoreTiming.cpp +++ b/Source/Core/Core/Src/CoreTiming.cpp @@ -22,8 +22,6 @@ #include "CoreTiming.h" #include "StringUtil.h" -// TODO(ector): Replace new/delete in this file with a simple memory pool -// Don't expect a massive speedup though. namespace CoreTiming { @@ -50,6 +48,11 @@ typedef LinkedListItem Event; Event *first; Event *tsFirst; +// event pools +Event *eventPool = 0; +Event *eventTsPool = 0; +int allocatedTsEvents = 0; + int downcount, slicelength; int maxSliceLength = 20000; @@ -60,6 +63,34 @@ Common::CriticalSection externalEventSection; void (*advanceCallback)(int cyclesExecuted); +Event* GetNewEvent() +{ + if(!eventPool) + return new Event; + + Event* ev = eventPool; + eventPool = ev->next; + return ev; +} + +Event* GetNewTsEvent() +{ + allocatedTsEvents++; + + if(!eventTsPool) + return new Event; + + Event* ev = eventTsPool; + eventTsPool = ev->next; + return ev; +} + +void FreeEvent(Event* ev) +{ + ev->next = eventPool; + eventPool = ev; +} + int RegisterEvent(const char *name, TimedCallback callback) { EventType type; @@ -88,6 +119,22 @@ void Shutdown() { ClearPendingEvents(); UnregisterAllEvents(); + + while(eventPool) + { + Event *ev = eventPool; + eventPool = ev->next; + delete ev; + } + + externalEventSection.Enter(); + while(eventTsPool) + { + Event *ev = eventTsPool; + eventTsPool = ev->next; + delete ev; + } + externalEventSection.Leave(); } void DoState(PointerWrap &p) @@ -111,7 +158,7 @@ void DoState(PointerWrap &p) p.Do(more_events); if (!more_events) break; - Event *ev = new Event; + Event *ev = GetNewEvent(); if (!prev) first = ev; else @@ -160,7 +207,7 @@ u64 GetIdleTicks() void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata) { externalEventSection.Enter(); - Event *ne = new Event; + Event *ne = GetNewTsEvent(); ne->time = globalTimer + cyclesIntoFuture; ne->type = event_type; ne->next = tsFirst; @@ -174,7 +221,7 @@ void ClearPendingEvents() while (first) { Event *e = first->next; - delete first; + FreeEvent(first); first = e; } } @@ -225,7 +272,7 @@ void AddEventToQueue(Event *ne) // than Advance void ScheduleEvent(int cyclesIntoFuture, int event_type, u64 userdata) { - Event *ne = new Event; + Event *ne = GetNewEvent(); ne->userdata = userdata; ne->type = event_type; ne->time = globalTimer + cyclesIntoFuture; @@ -258,7 +305,7 @@ void RemoveEvent(int event_type) if (first->type == event_type) { Event *next = first->next; - delete first; + FreeEvent(first); first = next; } if (!first) @@ -270,7 +317,7 @@ void RemoveEvent(int event_type) if (ptr->type == event_type) { prev->next = ptr->next; - delete ptr; + FreeEvent(ptr); ptr = prev->next; } else @@ -288,15 +335,25 @@ void SetMaximumSlice(int maximumSliceLength) void Advance() -{ - // Move events from async queue into main queue +{ externalEventSection.Enter(); + // Move events from async queue into main queue while (tsFirst) { Event *next = tsFirst->next; AddEventToQueue(tsFirst); tsFirst = next; } + + // Move free events to threadsafe pool + while(allocatedTsEvents > 0 && eventPool) + { + Event *ev = eventPool; + eventPool = ev->next; + ev->next = eventTsPool; + eventTsPool = ev; + allocatedTsEvents--; + } externalEventSection.Leave(); int cyclesExecuted = slicelength - downcount; @@ -311,7 +368,7 @@ void Advance() // first->name ? first->name : "?", (u64)globalTimer, (u64)first->time); event_types[first->type].callback(first->userdata, (int)(globalTimer - first->time)); Event *next = first->next; - delete first; + FreeEvent(first); first = next; } else