xref: /haiku/src/system/libroot/posix/malloc/hoard2/block.h (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
1 ///-*-C++-*-//////////////////////////////////////////////////////////////////
2 //
3 // Hoard: A Fast, Scalable, and Memory-Efficient Allocator
4 //        for Shared-Memory Multiprocessors
5 // Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery
6 //
7 // Copyright (c) 1998-2000, The University of Texas at Austin.
8 //
9 // This library is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU Library General Public License as
11 // published by the Free Software Foundation, http://www.fsf.org.
12 //
13 // This library is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // Library General Public License for more details.
17 //
18 //////////////////////////////////////////////////////////////////////////////
19 
20 #ifndef _BLOCK_H_
21 #define _BLOCK_H_
22 
23 #include "config.h"
24 
25 #include "os/support/Debug.h"
26 
27 //#include <assert.h>
28 
29 namespace BPrivate {
30 
31 class superblock;
32 
33 class block {
34 	public:
35 		block(superblock * sb)
36 			:
37 #if HEAP_DEBUG
38 			_magic(FREE_BLOCK_MAGIC),
39 #endif
40 			_next(NULL), _mySuperblock(sb)
41 		{
42 		}
43 
44 		block &
45 		operator=(const block & b)
46 		{
47 #if HEAP_DEBUG
48 			_magic = b._magic;
49 #endif
50 			_next = b._next;
51 			_mySuperblock = b._mySuperblock;
52 #if HEAP_FRAG_STATS
53 			_requestedSize = b._requestedSize;
54 #endif
55 			return *this;
56 		}
57 
58 		enum {
59 			ALLOCATED_BLOCK_MAGIC = 0xcafecafe,
60 			FREE_BLOCK_MAGIC = 0xbabebabe
61 		};
62 
63 		// Mark this block as free.
64 		inline void markFree(void);
65 
66 		// Mark this block as allocated.
67 		inline void markAllocated(void);
68 
69 		// Is this block valid? (i.e.,
70 		// does it have the right magic number?)
71 		inline const int isValid(void) const;
72 
73 		// Return the block's superblock pointer.
74 		inline superblock *getSuperblock(void);
75 
76 #if HEAP_FRAG_STATS
77 		void
78 		setRequestedSize(size_t s)
79 		{
80 			_requestedSize = s;
81 		}
82 
83 		size_t
84 		getRequestedSize(void)
85 		{
86 			return _requestedSize;
87 		}
88 #endif
89 
90 #if USE_PRIVATE_HEAPS
91 		void
92 		setActualSize(size_t s)
93 		{
94 			_actualSize = s;
95 		}
96 
97 		size_t
98 		getActualSize(void)
99 		{
100 			return _actualSize;
101 		}
102 #endif
103 		void
104 		setNext(block * b)
105 		{
106 			_next = b;
107 		}
108 
109 		block *
110 		getNext(void)
111 		{
112 			return _next;
113 		}
114 
115 #if HEAP_LEAK_CHECK
116 		void
117 		setCallStack(int index, void *address)
118 		{
119 			_callStack[index] = address;
120 		}
121 
122 		void *
123 		getCallStack(int index)
124 		{
125 			return _callStack[index];
126 		}
127 
128 		void
129 		setAllocatedSize(size_t size)
130 		{
131 			_allocatedSize = size;
132 		}
133 
134 		size_t
135 		getAllocatedSize()
136 		{
137 			return _allocatedSize;
138 		}
139 #endif
140 
141 	private:
142 #if USE_PRIVATE_HEAPS
143 #if HEAP_DEBUG
144 		union {
145 			unsigned long _magic;
146 			double _d1;				// For alignment.
147 		};
148 #endif
149 
150 		block *_next;				// The next block in a linked-list of blocks.
151 		size_t _actualSize;			// The actual size of the block.
152 
153 		union {
154 			double _d2;				// For alignment.
155 			superblock *_mySuperblock;	// A pointer to my superblock.
156 		};
157 #else // ! USE_PRIVATE_HEAPS
158 
159 #if HEAP_DEBUG
160 		union {
161 			unsigned long _magic;
162 			double _d3;				// For alignment.
163 		};
164 #endif
165 
166 		block *_next;				// The next block in a linked-list of blocks.
167 		superblock *_mySuperblock;	// A pointer to my superblock.
168 
169 #if defined(__i386__) && (__GNUC__ > 2)
170 		double _d5; // For alignment, make sure the whole structure is 16 byte
171 					// aligned
172 #endif
173 
174 #endif // USE_PRIVATE_HEAPS
175 
176 #if HEAP_LEAK_CHECK
177 		void *_callStack[HEAP_CALL_STACK_SIZE];
178 		size_t _allocatedSize;
179 #endif
180 
181 #if HEAP_FRAG_STATS
182 		union {
183 			double _d4;				// This is just for alignment purposes.
184 			size_t _requestedSize;	// The amount of space requested (vs. allocated).
185 		};
186 #endif
187 
188 		// Disable copying.
189 		block(const block &);
190 };
191 
192 // Make sure the block size does not mess up the alignment of allocations, it
193 // must be a multiple of ALIGNMENT
194 #if __GNUC__ > 2
195 // The macro we use for legacy gcc doesn't work in the global context, only
196 // inside functions since it is wrapped in a do/while.
197 STATIC_ASSERT(sizeof(block) % HAIKU_MEMORY_ALIGNMENT == 0);
198 #endif
199 
200 
201 superblock *
202 block::getSuperblock(void)
203 {
204 #if HEAP_DEBUG
205 	assert(isValid());
206 #endif
207 
208 	return _mySuperblock;
209 }
210 
211 
212 void
213 block::markFree(void)
214 {
215 #if HEAP_DEBUG
216 	assert(_magic == ALLOCATED_BLOCK_MAGIC);
217 	_magic = FREE_BLOCK_MAGIC;
218 #endif
219 }
220 
221 
222 void
223 block::markAllocated(void)
224 {
225 #if HEAP_DEBUG
226 	assert(_magic == FREE_BLOCK_MAGIC);
227 	_magic = ALLOCATED_BLOCK_MAGIC;
228 #endif
229 }
230 
231 
232 const int
233 block::isValid(void) const
234 {
235 #if HEAP_DEBUG
236 	return _magic == FREE_BLOCK_MAGIC
237 		|| _magic == ALLOCATED_BLOCK_MAGIC;
238 #else
239 	return 1;
240 #endif
241 }
242 
243 }	// namespace BPrivate
244 
245 #endif // _BLOCK_H_
246