aboutsummaryrefslogtreecommitdiff
path: root/backends/plugins/elf/elf-provider.cpp
diff options
context:
space:
mode:
authorYotam Barnoy2010-12-22 14:48:51 +0000
committerYotam Barnoy2010-12-22 14:48:51 +0000
commit6817d4b300f272f7ae51b8e3f5ab245f56d72780 (patch)
tree0d528759a3e9e22214e36250b514c08d6bca1d38 /backends/plugins/elf/elf-provider.cpp
parentc309bbde28a70a23a4d0199244f6db574d7c7189 (diff)
downloadscummvm-rg350-6817d4b300f272f7ae51b8e3f5ab245f56d72780.tar.gz
scummvm-rg350-6817d4b300f272f7ae51b8e3f5ab245f56d72780.tar.bz2
scummvm-rg350-6817d4b300f272f7ae51b8e3f5ab245f56d72780.zip
PLUGINS: add ELF memory manager to solve fragmentation
Following lordhoto's suggestion, I implemented a simple allocator that grabs the size of the biggest available plugin in memory. This is an elegant solution to the fragmentation problem, with the caveat that memory is wasted. As such, it's not suited for the DS, so I added a #define to disable it there. svn-id: r55009
Diffstat (limited to 'backends/plugins/elf/elf-provider.cpp')
-rw-r--r--backends/plugins/elf/elf-provider.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/backends/plugins/elf/elf-provider.cpp b/backends/plugins/elf/elf-provider.cpp
index b241379934..393010fd6f 100644
--- a/backends/plugins/elf/elf-provider.cpp
+++ b/backends/plugins/elf/elf-provider.cpp
@@ -33,6 +33,7 @@
#include "backends/plugins/elf/elf-provider.h"
#include "backends/plugins/dynamic-plugin.h"
+#include "backends/plugins/elf/memory-manager.h"
#include "common/debug.h"
#include "common/fs.h"
@@ -96,6 +97,17 @@ DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) {
return tmp;
}
+ /**
+ * Test the size of the plugin.
+ */
+void ELFPlugin::trackSize() {
+ // All we need to do is create our object, track its size, then delete it
+ DLObject *obj = makeDLObject();
+
+ obj->trackSize(_filename.c_str());
+ delete obj;
+}
+
bool ELFPlugin::loadPlugin() {
assert(!_dlHandle);
@@ -162,6 +174,30 @@ void ELFPlugin::unloadPlugin() {
}
}
+ /**
+ * We override this function in FilePluginProvider to allow the single
+ * plugin method to create a non-fragmenting memory allocation. We take
+ * the plugins found and tell the memory manager to allocate space for
+ * them.
+ */
+PluginList ELFPluginProvider::getPlugins() {
+ PluginList pl = FilePluginProvider::getPlugins();
+
+#if defined(ONE_PLUGIN_AT_A_TIME) && !defined(ELF_NO_MEM_MANAGER)
+ // This static downcast is safe because all of the plugins must
+ // be ELF plugins
+ for (PluginList::iterator p = pl.begin(); p != pl.end(); ++p) {
+ (static_cast<ELFPlugin *>(*p))->trackSize();
+ }
+
+ // The Memory Manager should now allocate space based on the information
+ // it collected
+ ELFMemMan.allocateHeap();
+#endif
+
+ return pl;
+}
+
bool ELFPluginProvider::isPluginFilename(const Common::FSNode &node) const {
// Check the plugin suffix
Common::String filename = node.getName();