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