mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-16 06:41:30 +00:00
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:
parent
caa34ef305
commit
b7c398574f
@ -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);
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user