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