1 ///-*-C++-*-//////////////////////////////////////////////////////////////////
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
7 // Copyright (c) 1998-2000, The University of Texas at Austin.
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.
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.
18 //////////////////////////////////////////////////////////////////////////////
20 /* We use one processHeap for the whole program. */
22 #ifndef _PROCESSHEAP_H_
23 #define _PROCESSHEAP_H_
30 #include "arch-specific.h"
33 # include "privateheap.h"
34 # define HEAPTYPE privateHeap
36 # define HEAPTYPE threadHeap
37 # include "threadheap.h"
48 class processHeap
: public hoardHeap
{
50 // Always grab at least this many superblocks' worth of memory which
52 enum { REFILL_NUMBER_OF_SUPERBLOCKS
= 16 };
61 // Memory deallocation routines.
64 // Print out statistics information.
67 // Get a thread heap index.
68 inline int getHeapIndex(void);
70 // Get thread heap max.
71 inline int getMaxThreadHeaps(void);
73 // Get the thread heap with index i.
74 inline HEAPTYPE
& getHeap(int i
);
76 // Extract a superblock.
77 inline superblock
*acquire(const int c
, hoardHeap
* dest
);
79 // Get space for a superblock.
80 inline char *getSuperblockBuffer(void);
82 // Insert a superblock.
83 inline void release(superblock
* sb
);
86 // Get the log for index i.
87 inline Log
< MemoryRequest
> &getLog(int i
);
91 // Declare that we have allocated an object.
92 void setAllocated(int requestedSize
, int actualSize
);
94 // Declare that we have deallocated an object.
95 void setDeallocated(int requestedSize
, int actualSize
);
97 // Return the number of wasted bytes at the high-water mark
98 // (maxAllocated - maxRequested)
99 inline int getFragmentation(void);
102 getMaxAllocated(void)
104 return _maxAllocated
;
108 getInUseAtMaxAllocated(void)
110 return _inUseAtMaxAllocated
;
114 getMaxRequested(void)
116 return _maxRequested
;
121 // Hide the lock & unlock methods.
134 // Prevent copying and assignment.
135 processHeap(const processHeap
&);
136 const processHeap
& operator=(const processHeap
&);
138 // The per-thread heaps.
142 // Statistics required to compute fragmentation. We cannot
143 // unintrusively keep track of these on a multiprocessor, because
144 // this would become a bottleneck.
146 int _currentAllocated
;
147 int _currentRequested
;
150 int _inUseAtMaxAllocated
;
153 // A lock to protect these statistics.
154 hoardLockType _statsLock
;
158 Log
< MemoryRequest
>* _log
;
161 // A lock for the superblock buffer.
162 hoardLockType _bufferLock
;
170 processHeap::getHeap(int i
)
172 assert(theap
!= NULL
);
174 assert(i
< fMaxThreadHeaps
);
180 Log
<MemoryRequest
> &
181 processHeap::getLog(int i
)
183 assert(_log
!= NULL
);
185 assert(i
< fMaxThreadHeaps
+ 1);
191 // Hash out the thread id to a heap and return an index to that heap.
194 processHeap::getHeapIndex(void)
196 // Here we use the number of processors as the maximum number of heaps.
197 // In fact, for efficiency, we just round up to the highest power of two,
199 int tid
= find_thread(NULL
) & _numProcessorsMask
;
200 assert(tid
< fMaxThreadHeaps
);
205 // Return the maximum number of heaps.
208 processHeap::getMaxThreadHeaps(void)
210 return fMaxThreadHeaps
;
215 processHeap::acquire(const int sizeclass
, hoardHeap
* dest
)
219 // Remove the superblock with the most free space.
220 superblock
*maxSb
= removeMaxSuperblock(sizeclass
);
222 maxSb
->setOwner(dest
);
231 processHeap::getSuperblockBuffer(void)
234 hoardLock(_bufferLock
);
235 if (_bufferCount
== 0) {
236 _buffer
= (char *)hoardSbrk(SUPERBLOCK_SIZE
237 * REFILL_NUMBER_OF_SUPERBLOCKS
);
238 _bufferCount
= REFILL_NUMBER_OF_SUPERBLOCKS
;
242 _buffer
+= SUPERBLOCK_SIZE
;
244 hoardUnlock(_bufferLock
);
250 // Put a superblock back into our list of superblocks.
253 processHeap::release(superblock
*sb
)
255 assert(EMPTY_FRACTION
* sb
->getNumAvailable() > sb
->getNumBlocks());
259 // Insert the superblock.
260 insertSuperblock(sb
->getBlockSizeClass(), sb
, this);
265 } // namespace BPrivate
267 #endif // _PROCESSHEAP_H_