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
29namespace BPrivate {
30
31class superblock;
32
33class 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.
197STATIC_ASSERT(sizeof(block) % HAIKU_MEMORY_ALIGNMENT == 0);
198#endif
199
200
201superblock *
202block::getSuperblock(void)
203{
204#if HEAP_DEBUG
205	assert(isValid());
206#endif
207
208	return _mySuperblock;
209}
210
211
212void
213block::markFree(void)
214{
215#if HEAP_DEBUG
216	assert(_magic == ALLOCATED_BLOCK_MAGIC);
217	_magic = FREE_BLOCK_MAGIC;
218#endif
219}
220
221
222void
223block::markAllocated(void)
224{
225#if HEAP_DEBUG
226	assert(_magic == FREE_BLOCK_MAGIC);
227	_magic = ALLOCATED_BLOCK_MAGIC;
228#endif
229}
230
231
232const int
233block::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