Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__SMALL_OBJECT_ALLOCATOR__
34 : #define __H__SMALL_OBJECT_ALLOCATOR__
35 :
36 : #include <cassert>
37 : #include <vector>
38 :
39 : /** Instances of this class can be used to allocate small objects of the same size
40 : * in a highly efficient way.
41 : */
42 : class FixedAllocator
43 : {
44 : public:
45 : FixedAllocator(std::size_t blockSize, unsigned char numBlocksPerChunk);
46 : void* allocate();
47 : void deallocate(void* p);
48 :
49 : private:
50 : /** The Chunk structure has to be used with great care.
51 : * A represents is a block of memory, in which it allocates
52 : * small objects. Be sure that the blockSize used in the calls
53 : * is the same for all calls to an instance.
54 : */
55 : struct Chunk
56 : {
57 : /// be careful. numBlocks has to be <= 255.
58 : void init(std::size_t blockSize, unsigned char numBlocks);
59 :
60 : /// call this method instead of a destructor
61 : void free();
62 :
63 : /// returns 0 if no more blocks are available.
64 : void* allocate(std::size_t blockSize);
65 : /// deallocates the given pointer.
66 : /** Make sure that p was allocated by the same instance on which you
67 : * call deallocate.*/
68 : void deallocate(void* p, std::size_t blockSize);
69 :
70 : unsigned char* m_pData;
71 : unsigned char m_firstAvailableBlock;
72 : unsigned char m_numAvailableBlocks;
73 : };
74 :
75 : private:
76 : inline bool pointer_is_in_chunk(void* p, Chunk* chunk)
77 : {
78 0 : return (p >= chunk->m_pData)
79 0 : && (p < chunk->m_pData + m_blockSize * m_numBlocksPerChunk);
80 : }
81 :
82 : private:
83 : typedef std::vector<Chunk> Chunks;
84 :
85 : private:
86 : std::size_t m_blockSize;
87 : unsigned char m_numBlocksPerChunk;
88 : Chunks m_chunks;
89 : Chunk* m_allocChunk;
90 : int m_emptyChunkIndex;
91 : int m_deallocChunkIndex;
92 : std::size_t m_numFreeBlocks;
93 : };
94 :
95 : /** A singleton that can be used to allocate small objects.*/
96 : template <std::size_t maxObjSize = 64, std::size_t maxChunkSize = 4096>
97 : class SmallObjectAllocator
98 : {
99 : public:
100 : /// returns an instance to this singleton
101 : static SmallObjectAllocator& inst();
102 :
103 : /// if numBytes > maxObjSize, allocate will directly call new.
104 : void* allocate(std::size_t numBytes);
105 :
106 : /// make sure that size exactly specifies the number of bytes of the object to which p points.
107 : void deallocate(void* p, std::size_t size);
108 :
109 : private:
110 : SmallObjectAllocator();
111 :
112 : private:
113 : std::vector<FixedAllocator> m_allocators;
114 : };
115 :
116 :
117 : /** This class implements the operators new and delete, so that they use the
118 : * SmallObjectAllocator.
119 : * By deriving from this class, your objects will be allocated through the
120 : * SmallObjectAllocator too.
121 : */
122 : template <std::size_t maxObjSize = 64, std::size_t maxChunkSize = 4096>
123 : class SmallObject
124 : {
125 : public:
126 : static void* operator new(std::size_t size);
127 : static void operator delete(void* p, std::size_t size);
128 : virtual ~SmallObject() {}
129 : };
130 :
131 : ////////////////////////////////
132 : // include implementation
133 : #include "small_object_allocator_impl.h"
134 :
135 : #endif
|