Skip to main content
gamedev.net
🔒 Locked

MemoryManager as plugin?

Started by bilsa Apr 30, 2004 at 6:33 AM 7 replies 550+ views
Original Post
bilsa
bilsa
Hey, how does a MemoryManager plugin sound? My entire engine is based on a PluginSystem that only loads plugins and exposes them as services to other modules. I have already made a LogManager, which I think sounded a good Idea in case you want to have remote logging etc... Now I'm thinking of a MemoryManager as a Plugin as well Something like this:
class Membase {
public:
	//something like this:

	void* operator new(size_t size) 
		the_memory_manager.new(size);
	}
	
	//and something like this:

	void operator delete(void* p) {
		the_memory_manager.delete(p);
	}

	static void setMemManager(IMemoryManager* mem_manager) {
		the_memory_manager = mem_manager;
	}
private:
	static IMemoryManager* the_memory_manager;
};
Now when my engine is loading this will be one of the first modules that will load by default. And then I just set the manager with the setMemManager() and all classes that want to be managed need to derive from this class... I would only use the memory manager during developement, so would the user of my library. Then during realease mode this would be disabled by a macro like: //if active #define MEM_MANAGED Membase //else class Empty_mem_class { }; #define MEM_MANAGED Empty_mem_class The memory manager could also be used to create objects instead of the ordinary new... but that would be terrible slow right? Since not only doesn't the new/delete containe the code directly and not only does it redirect the call to the memory manager but it also does this with a virtual function call... So how slow would this actually be? thank you! [edited by - bilsa on April 30, 2004 7:33:47 AM]
twanvl
twanvl
new/delete are already quite slow, i don''t think you need to worry about the virtual function call. But why do you want a memoryManager plugin in the first place? Do you really intend to provide different implementations?
bilsa
bilsa
Nope, I don''t intend to... but the engine is supposed to be ultra high pluggable

And the Idea is to let the user implement their own memory manager. Of course he could use the default one, but he might also want to implement a new one...

Let''s say my IMemoryManager doesn''t have a "CollectGarbage" function. And the user would really want that one implemented...
Then he can just derive from the IMemoryManager interface and add a new function "CollectGarbage". The engine will work as usual, because of the IMemoryManager interface but since he knows the exact IMemoryManagerV2 interface he can cast the MemoryManager to that and use the CollectGarbage function...

Now there might be other usefull stuff he might want to implement in that manager... Maybe do some logging in the end, have his own buffer and let new put the objects in this buffer... or whatever.

The point is that even if this feature won''t be used, the possibility still is there

well... thx for the post. Maybe you are right, the new/delete is slow... so maybe it doesn''t matter

Anyway, I can''t currently think of any other way of achieving this. Though I''ll prolly try to think something out with templates.

Any more suggestions/points about a pluggable memory manager?
antareus
antareus
quote:
Original post by Anonymous Poster
It may be worth checking out how Allocators are handled in the standard library, and perhaps follow the interface directly.


Seconded. Don''t push a compile-time decision (type of memory management) to a run-time one if you don''t get any benefit from it. I cannot fathom switching memory allocation strategies at runtime, but maybe I am thinking inside the box.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
Deebo
Deebo
For the type of extensibility you want with a memory manager, simply put an allocator, deallocator, and reallocator function in IMemoryManager and let this be the base class. Throw the plug-in idea away because the memory manager will be needed long before it will be loaded in your plug-in.

Anyone programming custom memory management will have a field day with because IMemoryManager because you only provide the "core" functions and let them add whatever they want to it (GC''s, pools, etc.) without being bound to you coding style or algorithm.

I use this a technique similar to this in my latest project and it works great. I simply do the basic mapping of new/delete to my allocator and deallocator, expose the allocating/reallocating/deallocating function for "custom" allocations, and then code my memory manager around those functions. Before I coded it, I spent about a good two months researching past and present allocating techniques and then came up with that framework so that I could "mix and match" memory managers and test them. If it worked for me, anyone should be able to use it.

Intro Engine
bilsa
bilsa
Hmm, well... actually the main idea I had with this was to let the user be able to switch a MemoryManager without having to recompile the Core/Project. Just as the rest of the engine.

Basically the user creates his own game.dll, and ultimately will never have to change anything in the engine. But still having the possibility to writ his own "low level" systems to override the standard ones comming with the engine.

The engine''s source code is not supposed to be public, but rather only a compiled version is available as download.

And the ModuleManager will be loaded "almost" as the first module.

like this:


int ENGINE_ENTRY_POINT(int arg, char** argv){
CSys sys_crucial_functions;

//The heart of the engine... handles modules and

//exposes them to other modules...

CSystems systems(&sys_crucial_functions);

const char* sMemoryManagerFile = //read the settings file...

//...

ISystem* memoryManagerSystem = systems.loadModule(sMemoryManagerFile);
//let the memoryManager Access other CONNECTED modules and CONNECT it

//to let other modules Access it...

memoryManagerSystem->Connect(&systems);
//set this moduleManager as the active one...

//this module is not to be changed at runtime... so finalize it...

systems.setActiveSystemFinal("IMemoryManager", memoryManagerSystem);
/* load the game.dll , or whatever the game module is called and run it */
}

void* operator new(size_t size) {
static IMemoryManager* memoryManagerSystem = (IMemoryManager*)CSystems::getActiveSystem("IMemoryManager");
return memoryManagerSystem->new(size);
};



Something like that... I actually think I rather override the global new operator, and then in my default MemoryManager module I could have the default new operator creating the objects...
Then
bilsa
bilsa
Hmm, well... actually the main idea I had with this was to let the user be able to switch a MemoryManager without having to recompile the Core/Project. Just as the rest of the engine.

Basically the user creates his own game.dll, and ultimately will never have to change anything in the engine. But still having the possibility to writ his own "low level" systems to override the standard ones comming with the engine.

The engine''s source code is not supposed to be public, but rather only a compiled version is available as download.

And the ModuleManager will be loaded "almost" as the first module.

like this:


int ENGINE_ENTRY_POINT(int arg, char** argv){
CSys sys_crucial_functions;

//The heart of the engine... handles modules and

//exposes them to other modules...

CSystems systems(&sys_crucial_functions);

const char* sMemoryManagerFile = //read the settings file...

//...

ISystem* memoryManagerSystem = systems.loadModule(sMemoryManagerFile);
//let the memoryManager Access other CONNECTED modules and CONNECT it

//to let other modules Access it...

memoryManagerSystem->Connect(&systems);
//set this moduleManager as the active one...

//this module is not to be changed at runtime... so finalize it...

systems.setActiveSystemFinal("IMemoryManager", memoryManagerSystem);
/* load the game.dll , or whatever the game module is called and run it */
}

void* operator new(size_t size) {
static IMemoryManager* memoryManagerSystem = (IMemoryManager*)CSystems::getActiveSystem("IMemoryManager");
return memoryManagerSystem->new(size);
};



Something like that... I actually think I rather override the global new operator, and then in my default MemoryManager module I could have the default new operator creating the objects...
Then
Deebo
Deebo
Simply put, you can''t have a memory manager that does that unless you do as I said earlier but make the 3 core functions function pointers equal, by default, some allocator that will work. Once your plugin is loaded into memory you can set the function pointers to the plugins core functions.

That is the only way I can think of that will work the way you want it to but it WILL result in undesired results because you are using more than one allocator/deallocator.

In my opinion, just drop the plug-in memory manager idea. The only way this will work is if it can be chosen and loaded while the program is being loaded into memory. The memory manager will be used long before your first lone of code in a typical program.

Intro Engine

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.