[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


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/