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:
block(superblock * sb)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
setRequestedSize(size_t s)78 setRequestedSize(size_t s)
79 {
80 _requestedSize = s;
81 }
82
83 size_t
getRequestedSize(void)84 getRequestedSize(void)
85 {
86 return _requestedSize;
87 }
88 #endif
89
90 #if USE_PRIVATE_HEAPS
91 void
setActualSize(size_t s)92 setActualSize(size_t s)
93 {
94 _actualSize = s;
95 }
96
97 size_t
getActualSize(void)98 getActualSize(void)
99 {
100 return _actualSize;
101 }
102 #endif
103 void
setNext(block * b)104 setNext(block * b)
105 {
106 _next = b;
107 }
108
109 block *
getNext(void)110 getNext(void)
111 {
112 return _next;
113 }
114
115 #if HEAP_LEAK_CHECK
116 void
setCallStack(int index,void * address)117 setCallStack(int index, void *address)
118 {
119 _callStack[index] = address;
120 }
121
122 void *
getCallStack(int index)123 getCallStack(int index)
124 {
125 return _callStack[index];
126 }
127
128 void
setAllocatedSize(size_t size)129 setAllocatedSize(size_t size)
130 {
131 _allocatedSize = size;
132 }
133
134 size_t
getAllocatedSize()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 *
getSuperblock(void)202 block::getSuperblock(void)
203 {
204 #if HEAP_DEBUG
205 assert(isValid());
206 #endif
207
208 return _mySuperblock;
209 }
210
211
212 void
markFree(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
markAllocated(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
isValid(void)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