summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTycho <work.tycho+git@gmail.com>2014-05-23 18:18:11 +0200
committerTycho <work.tycho+git@gmail.com>2014-05-23 18:18:11 +0200
commit8be3a8f7dc10dbc49dfcdeca572677ef1e00f714 (patch)
tree204743272c8948237a8322027510f5240bfdb71e /src
parentUse placement new to initalise objects (diff)
downloadcuberite-8be3a8f7dc10dbc49dfcdeca572677ef1e00f714.tar
cuberite-8be3a8f7dc10dbc49dfcdeca572677ef1e00f714.tar.gz
cuberite-8be3a8f7dc10dbc49dfcdeca572677ef1e00f714.tar.bz2
cuberite-8be3a8f7dc10dbc49dfcdeca572677ef1e00f714.tar.lz
cuberite-8be3a8f7dc10dbc49dfcdeca572677ef1e00f714.tar.xz
cuberite-8be3a8f7dc10dbc49dfcdeca572677ef1e00f714.tar.zst
cuberite-8be3a8f7dc10dbc49dfcdeca572677ef1e00f714.zip
Diffstat (limited to '')
-rw-r--r--src/AllocationPool.h39
-rw-r--r--src/Chunk.cpp4
-rw-r--r--src/Chunk.h3
-rw-r--r--src/ChunkData.cpp6
-rw-r--r--src/ChunkData.h33
-rw-r--r--src/ChunkMap.cpp11
-rw-r--r--src/ChunkMap.h15
7 files changed, 79 insertions, 32 deletions
diff --git a/src/AllocationPool.h b/src/AllocationPool.h
index d14d56f7a..b3818e8b1 100644
--- a/src/AllocationPool.h
+++ b/src/AllocationPool.h
@@ -1,36 +1,52 @@
#pragma once
-template<class T, size_t BufferSize, class StarvationCallbacks>
-class AllocationPool {
+#include <memory>
+
+template<class T, size_t BufferSize>
+class cAllocationPool {
public:
+
+ class cStarvationCallbacks
+ {
+ public:
+ virtual ~cStarvationCallbacks() {}
+ virtual void OnStartingUsingBuffer() = 0;
+ virtual void OnStopUsingBuffer() = 0;
+ virtual void OnBufferEmpty() = 0;
+ };
+
+ cAllocationPool(std::auto_ptr<cStarvationCallbacks> a_Callbacks) :
+ m_Callbacks(a_Callbacks)
+ {
+ }
- ~AllocationPool()
+ ~cAllocationPool()
{
while (!m_FreeList.empty())
{
- delete m_FreeList.front();
+ free (m_FreeList.front());
m_FreeList.pop_front();
}
}
T* Allocate()
{
- if (m_FreeList.Size() <= BufferSize)
+ if (m_FreeList.size() <= BufferSize)
{
try
{
- return new T;
+ return new(malloc(sizeof(T))) T;
}
- catch (std::bad_alloc& ex)
+ catch (std::bad_alloc&)
{
if (m_FreeList.size() == BufferSize)
{
- StarvationCallbacks.OnStartingUsingBuffer();
+ m_Callbacks->OnStartingUsingBuffer();
}
else if (m_FreeList.empty())
{
- StarvationCallbacks.OnBufferEmpty();
+ m_Callbacks->OnBufferEmpty();
// Try again until the memory is avalable
return Allocate();
}
@@ -48,10 +64,11 @@ class AllocationPool {
m_FreeList.push_front(ptr);
if (m_FreeList.size() == BufferSize)
{
- StarvationCallbacks.OnStopUsingBuffer();
+ m_Callbacks->OnStopUsingBuffer();
}
}
private:
std::list<void *> m_FreeList;
-}
+ std::auto_ptr<cStarvationCallbacks> m_Callbacks;
+};
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index d85b44607..cdec0774f 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -64,7 +64,8 @@ sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_Bloc
cChunk::cChunk(
int a_ChunkX, int a_ChunkY, int a_ChunkZ,
cChunkMap * a_ChunkMap, cWorld * a_World,
- cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP
+ cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP,
+ cAllocationPool<cChunkData::sChunkSection,1600>& a_Pool
) :
m_IsValid(false),
m_IsLightValid(false),
@@ -77,6 +78,7 @@ cChunk::cChunk(
m_PosZ(a_ChunkZ),
m_World(a_World),
m_ChunkMap(a_ChunkMap),
+ m_ChunkData(a_Pool),
m_BlockTickX(0),
m_BlockTickY(0),
m_BlockTickZ(0),
diff --git a/src/Chunk.h b/src/Chunk.h
index 2de45919e..e5b55ed2a 100644
--- a/src/Chunk.h
+++ b/src/Chunk.h
@@ -65,7 +65,8 @@ public:
cChunk(
int a_ChunkX, int a_ChunkY, int a_ChunkZ, // Chunk coords
cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects
- cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP // Neighbor chunks
+ cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, // Neighbor chunks
+ cAllocationPool<cChunkData::sChunkSection,1600>& a_Pool
);
cChunk(cChunk& other);
~cChunk();
diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp
index 86b0c431c..31de364b9 100644
--- a/src/ChunkData.cpp
+++ b/src/ChunkData.cpp
@@ -4,7 +4,7 @@
cChunkData cChunkData::Copy() const
{
- cChunkData copy;
+ cChunkData copy(m_Pool);
for (int i = 0; i < CHUNK_SECTION_NUM; i++)
{
if (m_Sections[i] != NULL)
@@ -360,14 +360,14 @@ void cChunkData::SetSkyLight (const NIBBLETYPE * a_src)
cChunkData::sChunkSection * cChunkData::Allocate() const
{
// TODO: use a allocation pool
- return new cChunkData::sChunkSection;
+ return m_Pool.Allocate();
}
void cChunkData::Free(cChunkData::sChunkSection * ptr) const
{
- delete ptr;
+ m_Pool.Free(ptr);
}
diff --git a/src/ChunkData.h b/src/ChunkData.h
index 9c852ee24..527c5b2ae 100644
--- a/src/ChunkData.h
+++ b/src/ChunkData.h
@@ -7,6 +7,8 @@
#include "ChunkDef.h"
+#include "AllocationPool.h"
+
#define CHUNK_SECTION_HEIGHT 16
#define CHUNK_SECTION_NUM (256 / CHUNK_SECTION_HEIGHT)
@@ -21,11 +23,14 @@ class cChunkData
{
public:
- cChunkData()
+ struct sChunkSection;
+
+ cChunkData(cAllocationPool<cChunkData::sChunkSection, 1600>& a_Pool) :
#if __cplusplus < 201103L
// auto_ptr style interface for memory management
- : IsOwner(true)
+ IsOwner(true),
#endif
+ m_Pool(a_Pool)
{
memset(m_Sections, 0, sizeof(m_Sections));
}
@@ -44,7 +49,8 @@ public:
#if __cplusplus < 201103L
// auto_ptr style interface for memory management
cChunkData(const cChunkData& other) :
- IsOwner(true)
+ IsOwner(true),
+ m_Pool(other.m_Pool)
{
for (int i = 0; i < CHUNK_SECTION_NUM; i++)
{
@@ -70,13 +76,15 @@ public:
m_Sections[i] = other.m_Sections[i];
}
other.IsOwner = false;
+ ASSERT(&m_Pool == &other.m_Pool);
}
return *this;
}
#else
// unique_ptr style interface for memory management
- cChunkData(cChunkData&& other)
+ cChunkData(cChunkData&& other) :
+ m_Pool(other.m_Pool)
{
for (int i = 0; i < CHUNK_SECTION_NUM; i++)
{
@@ -95,6 +103,7 @@ public:
m_Sections[i] = other.m_Sections[i];
other.m_Sections[i] = 0;
}
+ ASSERT(&m_Pool == &other.m_Pool);
}
return *this;
}
@@ -252,13 +261,6 @@ public:
void SetLight (const NIBBLETYPE * a_src);
void SetSkyLight (const NIBBLETYPE * a_src);
-private:
-
- #if __cplusplus < 201103L
- // auto_ptr style interface for memory management
- mutable bool IsOwner;
- #endif
-
struct sChunkSection {
BLOCKTYPE m_BlockTypes [CHUNK_SECTION_HEIGHT * 16 * 16] ;
NIBBLETYPE m_BlockMeta [CHUNK_SECTION_HEIGHT * 16 * 16 / 2];
@@ -266,12 +268,21 @@ private:
NIBBLETYPE m_BlockSkyLight[CHUNK_SECTION_HEIGHT * 16 * 16 / 2];
};
+private:
+
+ #if __cplusplus < 201103L
+ // auto_ptr style interface for memory management
+ mutable bool IsOwner;
+ #endif
+
sChunkSection *m_Sections[CHUNK_SECTION_NUM];
sChunkSection * Allocate() const;
void Free(sChunkSection * ptr) const;
void ZeroSection(sChunkSection * ptr) const;
+
+ cAllocationPool<cChunkData::sChunkSection, 1600>& m_Pool;
};
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index d3f44bef8..bf2b09342 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -34,7 +34,8 @@
// cChunkMap:
cChunkMap::cChunkMap(cWorld * a_World )
- : m_World( a_World )
+ : m_World( a_World ),
+ m_Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks>(new cStarvationCallbacks()))
{
}
@@ -78,7 +79,7 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ)
}
// Not found, create new:
- cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this);
+ cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this, m_Pool);
if (Layer == NULL)
{
LOGERROR("cChunkMap: Cannot create new layer, server out of memory?");
@@ -2646,11 +2647,13 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
////////////////////////////////////////////////////////////////////////////////
// cChunkMap::cChunkLayer:
-cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent)
+cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent,
+ cAllocationPool<cChunkData::sChunkSection,1600>& a_Pool)
: m_LayerX( a_LayerX )
, m_LayerZ( a_LayerZ )
, m_Parent( a_Parent )
, m_NumChunksLoaded( 0 )
+ , m_Pool(a_Pool)
{
memset(m_Chunks, 0, sizeof(m_Chunks));
}
@@ -2692,7 +2695,7 @@ cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_Ch
cChunk * neixp = (LocalX < LAYER_SIZE - 1) ? m_Chunks[Index + 1] : m_Parent->FindChunk(a_ChunkX + 1, a_ChunkZ);
cChunk * neizm = (LocalZ > 0) ? m_Chunks[Index - LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ - 1);
cChunk * neizp = (LocalZ < LAYER_SIZE - 1) ? m_Chunks[Index + LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ + 1);
- m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp);
+ m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp, m_Pool);
}
return m_Chunks[Index];
}
diff --git a/src/ChunkMap.h b/src/ChunkMap.h
index c3deda088..1744c09d0 100644
--- a/src/ChunkMap.h
+++ b/src/ChunkMap.h
@@ -347,7 +347,8 @@ private:
class cChunkLayer
{
public:
- cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent);
+ cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent,
+ cAllocationPool<cChunkData::sChunkSection,1600>& a_Pool);
~cChunkLayer();
/** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */
@@ -391,6 +392,16 @@ private:
int m_LayerZ;
cChunkMap * m_Parent;
int m_NumChunksLoaded;
+
+ cAllocationPool<cChunkData::sChunkSection,1600> & m_Pool;
+ };
+
+ class cStarvationCallbacks
+ : public cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks
+ {
+ virtual void OnStartingUsingBuffer() {}
+ virtual void OnStopUsingBuffer() {}
+ virtual void OnBufferEmpty() {}
};
typedef std::list<cChunkLayer *> cChunkLayerList;
@@ -423,6 +434,8 @@ private:
/** The cChunkStay descendants that are currently enabled in this chunkmap */
cChunkStays m_ChunkStays;
+ cAllocationPool<cChunkData::sChunkSection,1600> m_Pool;
+
cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid
cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate
cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate