[opengtl-commits] [558] add a MemoryManager to OpenGTL |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/opengtl-commits Archives
]
Revision: 558
Author: cyrille
Date: 2009-02-22 21:00:49 +0100 (Sun, 22 Feb 2009)
Log Message:
-----------
add a MemoryManager to OpenGTL
Modified Paths:
--------------
trunk/OpenGTL/OpenGTL/GTLCore/CMakeLists.txt
trunk/OpenGTL/OpenGTL/GTLCore/tests/TestGTLCore.cpp
Added Paths:
-----------
trunk/OpenGTL/OpenGTL/GTLCore/MemoryManager_p.cpp
trunk/OpenGTL/OpenGTL/GTLCore/MemoryManager_p.h
trunk/OpenGTL/OpenGTL/GTLCore/tests/TestMemoryManager.h
Modified: trunk/OpenGTL/OpenGTL/GTLCore/CMakeLists.txt
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/CMakeLists.txt 2009-02-22 20:00:19 UTC (rev 557)
+++ trunk/OpenGTL/OpenGTL/GTLCore/CMakeLists.txt 2009-02-22 20:00:49 UTC (rev 558)
@@ -50,6 +50,7 @@
FloatHalfConverter_p.cpp
GenerationContext_p.cpp
LexerBase_p.cpp
+ MemoryManager_p.cpp
ModuleData_p.cpp
Optimiser_p.cpp
ParserBase_p.cpp
Added: trunk/OpenGTL/OpenGTL/GTLCore/MemoryManager_p.cpp
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/MemoryManager_p.cpp (rev 0)
+++ trunk/OpenGTL/OpenGTL/GTLCore/MemoryManager_p.cpp 2009-02-22 20:00:49 UTC (rev 558)
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2009 Cyrille Berger <cberger@xxxxxxxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "MemoryManager_p.h"
+
+#include <stdint.h>
+#include <list>
+
+#include "Debug.h"
+#include "Macros_p.h"
+
+using namespace GTLCore;
+
+#define DEFAULT_SEGMENT_SIZE 1000
+
+struct MemoryManager::Header {
+ enum Status {
+ USED, ///< Indicate the memory is still used
+ FREED ///< Indicate the memory has been freed
+ };
+ Status status;
+ int size;
+ Header* previous;
+ Header* next;
+ uint8_t* data;
+};
+
+struct MemoryManager::Segment {
+ inline Segment( int size )
+ {
+ size += sizeof(Header);
+ start = new uint8_t[size];
+ end = start + size * sizeof(uint8_t);
+ nextFree = start;
+ previous = 0;
+ }
+ ~Segment() {
+ delete[] start;
+ }
+ inline bool contains( void* ptr ) const
+ {
+ return (ptr >= start and ptr < end)
+ or ( ptr == end and (
+ reinterpret_cast<Header*>(reinterpret_cast<uint8_t*>(ptr)-sizeof(Header))->size == 0 ) );
+ }
+ inline bool canContains(int size) const {
+ return uint(end - nextFree) >= uint(size + sizeof(Header));
+ }
+ inline void* allocate(int size)
+ {
+ GTL_ASSERT( canContains(size) );
+ int sizeTotal = size + sizeof(Header);
+ Header* nextFreeH = reinterpret_cast<Header*>(nextFree);
+ nextFreeH->status = Header::USED;
+ nextFreeH->size = size;
+ nextFreeH->previous = previous;
+ nextFreeH->next = 0;
+ nextFreeH->data = nextFree + sizeof(Header);
+ if(previous)
+ {
+ previous->next = nextFreeH;
+ }
+ previous = nextFreeH;
+ nextFree += sizeTotal;
+ return nextFreeH->data;
+ }
+ inline void desallocate(void* ptr)
+ {
+ GTL_ASSERT(contains(ptr));
+ uint8_t* ptr8 = reinterpret_cast<uint8_t*>(ptr);
+ Header* currentHeader = reinterpret_cast<Header*>(ptr8-sizeof(Header));
+ GTL_ASSERT(currentHeader->status == Header::USED);
+ currentHeader->status = Header::FREED;
+ while(currentHeader->next == 0)
+ {
+ if(currentHeader->previous == 0)
+ {
+ nextFree = reinterpret_cast<uint8_t*>(currentHeader);
+ previous = 0;
+ return;
+ }
+ Header* previousCurrentHeader = currentHeader->previous;
+ if( previousCurrentHeader->status == Header::FREED )
+ {
+ currentHeader = previousCurrentHeader;
+ } else {
+ previous = previousCurrentHeader;
+ previous->next = 0;
+ nextFree = reinterpret_cast<uint8_t*>(currentHeader);
+ return;
+ }
+ }
+ }
+ uint8_t* nextFree;
+ Header* previous;
+ uint8_t* start;
+ uint8_t* end;
+};
+
+struct MemoryManager::Private {
+ std::list<Segment*> segments;
+ static Private* s_instance;
+};
+
+MemoryManager::Private* MemoryManager::Private::s_instance = new MemoryManager::Private;
+
+void* MemoryManager::allocate(int size)
+{
+ foreach(Segment* segment, Private::s_instance->segments)
+ {
+ if( segment->canContains(size) )
+ {
+ void* ptr = segment->allocate(size);
+ GTL_ASSERT(segment->contains(ptr));
+ return ptr;
+ }
+ }
+// GTL_DEBUG("Create new segment");
+ int newSegSize = size > DEFAULT_SEGMENT_SIZE ? size : DEFAULT_SEGMENT_SIZE;
+ Segment* segment = new Segment(newSegSize);
+ Private::s_instance->segments.push_back(segment);
+ void* ptr = segment->allocate(size);
+ GTL_ASSERT(segment->contains(ptr));
+ return ptr;
+}
+
+void MemoryManager::desallocate(void* ptr)
+{
+ foreach(Segment* segment, Private::s_instance->segments)
+ {
+ if( segment->contains(ptr) )
+ {
+ segment->desallocate(ptr);
+ return;
+ }
+ }
+ GTL_ABORT("Not allocated pointer.");
+}
Property changes on: trunk/OpenGTL/OpenGTL/GTLCore/MemoryManager_p.cpp
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: trunk/OpenGTL/OpenGTL/GTLCore/MemoryManager_p.h
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/MemoryManager_p.h (rev 0)
+++ trunk/OpenGTL/OpenGTL/GTLCore/MemoryManager_p.h 2009-02-22 20:00:49 UTC (rev 558)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2009 Cyrille Berger <cberger@xxxxxxxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _MEMORY_MANAGER_P_H_
+#define _MEMORY_MANAGER_P_H_
+
+namespace GTLCore {
+ /**
+ * @internal
+ * @ingroup GTLCore
+ * This class allow to allocate memory
+ */
+ class MemoryManager {
+ struct Header;
+ struct Segment;
+ struct Private;
+ public:
+ static void* allocate(int size);
+ static void desallocate(void* ptr);
+ };
+}
+
+#endif
Property changes on: trunk/OpenGTL/OpenGTL/GTLCore/MemoryManager_p.h
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: trunk/OpenGTL/OpenGTL/GTLCore/tests/TestGTLCore.cpp
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/tests/TestGTLCore.cpp 2009-02-22 20:00:19 UTC (rev 557)
+++ trunk/OpenGTL/OpenGTL/GTLCore/tests/TestGTLCore.cpp 2009-02-22 20:00:49 UTC (rev 558)
@@ -38,6 +38,7 @@
#include "TestScopedName.h"
#include "TestConvertCenter.h"
#include "TestMetadata.h"
+#include "TestMemoryManager.h"
class TestArray : public GTLTest::Case {
public:
@@ -70,4 +71,5 @@
GTLTEST_MAIN_ADD_CASE(TestScopedName)
GTLTEST_MAIN_ADD_CASE(TestConvertCenter)
GTLTEST_MAIN_ADD_CASE(TestMetadata)
+GTLTEST_MAIN_ADD_CASE(TestMemoryManager)
GTLTEST_MAIN_END()
Added: trunk/OpenGTL/OpenGTL/GTLCore/tests/TestMemoryManager.h
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/tests/TestMemoryManager.h (rev 0)
+++ trunk/OpenGTL/OpenGTL/GTLCore/tests/TestMemoryManager.h 2009-02-22 20:00:49 UTC (rev 558)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009 Cyrille Berger <cberger@xxxxxxxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "../MemoryManager_p.h"
+
+#include <cstring>
+
+#define COUMPONENT_NAME "GTLCore test"
+
+class TestMemoryManager : public GTLTest::Case {
+ public:
+ TestMemoryManager() : GTLTest::Case("MemoryManager")
+ {
+ }
+ virtual void runTest()
+ {
+ int countAlloc = 10000;
+ std::vector<void*> allocated;
+ std::vector<int> sizes;
+ for(int i = 0; i < countAlloc; ++i)
+ {
+ int size = rand() / 1000000;
+ void* m = GTLCore::MemoryManager::allocate(size);
+ GTLTEST_CHECK_REQUIRED(m);
+ char counter = i;
+ memset(m, counter, size);
+ allocated.push_back(m);
+ sizes.push_back(size);
+ }
+ GTLTEST_CHECK_REQUIRED( allocated.size() == sizes.size() );
+ int error = 0;
+ for(int i = 0; i < countAlloc; ++i)
+ {
+ void* ptr = allocated[i];
+ int size = sizes[i];
+ error += checkArray(ptr, i, size);
+ }
+ GTLTEST_CHECK_EQUAL(error, 0);
+ for(int i = 0; i < countAlloc; ++i)
+ {
+ void* ptr = allocated[i];
+ GTLCore::MemoryManager::desallocate(ptr);
+ }
+ }
+ private:
+ int checkArray( void* ptr, char v, int size)
+ {
+ char* ptr8 = reinterpret_cast<char*>(ptr);
+ int error = 0;
+ for(int j = 0; j < size; ++j)
+ {
+ if( ptr8[j] != v )
+ {
+ GTL_DEBUG( (int)ptr8[j] << " " << (int)v );
+ ++error;
+ }
+ }
+ return error;
+ }
+};
Property changes on: trunk/OpenGTL/OpenGTL/GTLCore/tests/TestMemoryManager.h
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native