vfs: check userland buffers before reading them.
[haiku.git] / src / system / libroot / posix / malloc / processheap.h
blob2c94af90eba117ee900eeaf4f92b8b8c3a1e4e23
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.
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_
25 #include "config.h"
27 #include <stdio.h>
28 #include <stdlib.h>
30 #include "arch-specific.h"
31 #include "heap.h"
32 #if USE_PRIVATE_HEAPS
33 # include "privateheap.h"
34 # define HEAPTYPE privateHeap
35 #else
36 # define HEAPTYPE threadHeap
37 # include "threadheap.h"
38 #endif
40 #if HEAP_LOG
41 # include "memstat.h"
42 # include "log.h"
43 #endif
46 namespace BPrivate {
48 class processHeap : public hoardHeap {
49 public:
50 // Always grab at least this many superblocks' worth of memory which
51 // we parcel out.
52 enum { REFILL_NUMBER_OF_SUPERBLOCKS = 16 };
54 processHeap();
55 ~processHeap(void)
57 #if HEAP_STATS
58 stats();
59 #endif
61 // Memory deallocation routines.
62 void free(void *ptr);
64 // Print out statistics information.
65 void stats(void);
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);
85 #if HEAP_LOG
86 // Get the log for index i.
87 inline Log < MemoryRequest > &getLog(int i);
88 #endif
90 #if HEAP_FRAG_STATS
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;
118 #endif
120 private:
121 // Hide the lock & unlock methods.
122 void
123 lock(void)
125 hoardHeap::lock();
128 void
129 unlock(void)
131 hoardHeap::unlock();
134 // Prevent copying and assignment.
135 processHeap(const processHeap &);
136 const processHeap & operator=(const processHeap &);
138 // The per-thread heaps.
139 HEAPTYPE* theap;
141 #if HEAP_FRAG_STATS
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;
148 int _maxAllocated;
149 int _maxRequested;
150 int _inUseAtMaxAllocated;
151 int _fragmentation;
153 // A lock to protect these statistics.
154 hoardLockType _statsLock;
155 #endif
157 #if HEAP_LOG
158 Log < MemoryRequest >* _log;
159 #endif
161 // A lock for the superblock buffer.
162 hoardLockType _bufferLock;
164 char *_buffer;
165 int _bufferCount;
169 HEAPTYPE &
170 processHeap::getHeap(int i)
172 assert(theap != NULL);
173 assert(i >= 0);
174 assert(i < fMaxThreadHeaps);
175 return theap[i];
179 #if HEAP_LOG
180 Log<MemoryRequest > &
181 processHeap::getLog(int i)
183 assert(_log != NULL);
184 assert(i >= 0);
185 assert(i < fMaxThreadHeaps + 1);
186 return _log[i];
188 #endif
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,
198 // times two.
199 int tid = find_thread(NULL) & _numProcessorsMask;
200 assert(tid < fMaxThreadHeaps);
201 return tid;
205 // Return the maximum number of heaps.
208 processHeap::getMaxThreadHeaps(void)
210 return fMaxThreadHeaps;
214 superblock *
215 processHeap::acquire(const int sizeclass, hoardHeap * dest)
217 lock();
219 // Remove the superblock with the most free space.
220 superblock *maxSb = removeMaxSuperblock(sizeclass);
221 if (maxSb)
222 maxSb->setOwner(dest);
224 unlock();
226 return maxSb;
230 inline char *
231 processHeap::getSuperblockBuffer(void)
233 char *buf;
234 hoardLock(_bufferLock);
235 if (_bufferCount == 0) {
236 _buffer = (char *)hoardSbrk(SUPERBLOCK_SIZE
237 * REFILL_NUMBER_OF_SUPERBLOCKS);
238 _bufferCount = REFILL_NUMBER_OF_SUPERBLOCKS;
241 buf = _buffer;
242 _buffer += SUPERBLOCK_SIZE;
243 _bufferCount--;
244 hoardUnlock(_bufferLock);
246 return buf;
250 // Put a superblock back into our list of superblocks.
252 void
253 processHeap::release(superblock *sb)
255 assert(EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
257 lock();
259 // Insert the superblock.
260 insertSuperblock(sb->getBlockSizeClass(), sb, this);
262 unlock();
265 } // namespace BPrivate
267 #endif // _PROCESSHEAP_H_