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
This commit is contained in:
donkopunchstania 2009-02-25 07:06:02 +00:00
parent caa34ef305
commit b7c398574f
2 changed files with 69 additions and 12 deletions

View File

@ -41,7 +41,7 @@ public:
// This functions is only used when CPlugin is called directly, when a parent class like PluginVideo // This functions is only used when CPlugin is called directly, when a parent class like PluginVideo
// is called its own IsValid() will be called. // is called its own IsValid() will be called.
virtual bool IsValid() { return valid; }; virtual bool IsValid() { return valid; };
std::string GetFilename() const { return Filename; } const std::string& GetFilename() const { return Filename; }
bool GetInfo(PLUGIN_INFO& _pluginInfo); bool GetInfo(PLUGIN_INFO& _pluginInfo);
void SetGlobals(PLUGIN_GLOBALS* _PluginGlobals); void SetGlobals(PLUGIN_GLOBALS* _PluginGlobals);
void *LoadSymbol(const char *sym); void *LoadSymbol(const char *sym);

View File

@ -22,8 +22,6 @@
#include "CoreTiming.h" #include "CoreTiming.h"
#include "StringUtil.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 namespace CoreTiming
{ {
@ -50,6 +48,11 @@ typedef LinkedListItem<BaseEvent> Event;
Event *first; Event *first;
Event *tsFirst; Event *tsFirst;
// event pools
Event *eventPool = 0;
Event *eventTsPool = 0;
int allocatedTsEvents = 0;
int downcount, slicelength; int downcount, slicelength;
int maxSliceLength = 20000; int maxSliceLength = 20000;
@ -60,6 +63,34 @@ Common::CriticalSection externalEventSection;
void (*advanceCallback)(int cyclesExecuted); 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) int RegisterEvent(const char *name, TimedCallback callback)
{ {
EventType type; EventType type;
@ -88,6 +119,22 @@ void Shutdown()
{ {
ClearPendingEvents(); ClearPendingEvents();
UnregisterAllEvents(); 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) void DoState(PointerWrap &p)
@ -111,7 +158,7 @@ void DoState(PointerWrap &p)
p.Do(more_events); p.Do(more_events);
if (!more_events) if (!more_events)
break; break;
Event *ev = new Event; Event *ev = GetNewEvent();
if (!prev) if (!prev)
first = ev; first = ev;
else else
@ -160,7 +207,7 @@ u64 GetIdleTicks()
void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata) void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata)
{ {
externalEventSection.Enter(); externalEventSection.Enter();
Event *ne = new Event; Event *ne = GetNewTsEvent();
ne->time = globalTimer + cyclesIntoFuture; ne->time = globalTimer + cyclesIntoFuture;
ne->type = event_type; ne->type = event_type;
ne->next = tsFirst; ne->next = tsFirst;
@ -174,7 +221,7 @@ void ClearPendingEvents()
while (first) while (first)
{ {
Event *e = first->next; Event *e = first->next;
delete first; FreeEvent(first);
first = e; first = e;
} }
} }
@ -225,7 +272,7 @@ void AddEventToQueue(Event *ne)
// than Advance // than Advance
void ScheduleEvent(int cyclesIntoFuture, int event_type, u64 userdata) void ScheduleEvent(int cyclesIntoFuture, int event_type, u64 userdata)
{ {
Event *ne = new Event; Event *ne = GetNewEvent();
ne->userdata = userdata; ne->userdata = userdata;
ne->type = event_type; ne->type = event_type;
ne->time = globalTimer + cyclesIntoFuture; ne->time = globalTimer + cyclesIntoFuture;
@ -258,7 +305,7 @@ void RemoveEvent(int event_type)
if (first->type == event_type) if (first->type == event_type)
{ {
Event *next = first->next; Event *next = first->next;
delete first; FreeEvent(first);
first = next; first = next;
} }
if (!first) if (!first)
@ -270,7 +317,7 @@ void RemoveEvent(int event_type)
if (ptr->type == event_type) if (ptr->type == event_type)
{ {
prev->next = ptr->next; prev->next = ptr->next;
delete ptr; FreeEvent(ptr);
ptr = prev->next; ptr = prev->next;
} }
else else
@ -288,15 +335,25 @@ void SetMaximumSlice(int maximumSliceLength)
void Advance() void Advance()
{ {
// Move events from async queue into main queue
externalEventSection.Enter(); externalEventSection.Enter();
// Move events from async queue into main queue
while (tsFirst) while (tsFirst)
{ {
Event *next = tsFirst->next; Event *next = tsFirst->next;
AddEventToQueue(tsFirst); AddEventToQueue(tsFirst);
tsFirst = next; 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(); externalEventSection.Leave();
int cyclesExecuted = slicelength - downcount; int cyclesExecuted = slicelength - downcount;
@ -311,7 +368,7 @@ void Advance()
// first->name ? first->name : "?", (u64)globalTimer, (u64)first->time); // first->name ? first->name : "?", (u64)globalTimer, (u64)first->time);
event_types[first->type].callback(first->userdata, (int)(globalTimer - first->time)); event_types[first->type].callback(first->userdata, (int)(globalTimer - first->time));
Event *next = first->next; Event *next = first->next;
delete first; FreeEvent(first);
first = next; first = next;
} }
else else