BTRFS: Implement some space relevant helpers.
[haiku.git] / src / system / libroot / posix / malloc / threadheap.h
blob9c4083f1eded7bbb9eb4d7ebca559b3720002358
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 #ifndef _THREADHEAP_H_
21 #define _THREADHEAP_H_
23 #include "config.h"
25 #include <string.h>
27 #include "heap.h"
29 namespace BPrivate {
31 class processHeap; // forward declaration
34 // We use one threadHeap for each thread (processor).
37 class threadHeap : public hoardHeap {
38 public:
39 threadHeap(void);
41 // Memory allocation routines.
42 void *malloc(const size_t sz);
43 inline void *memalign(size_t alignment, size_t sz);
45 // Find out how large an allocated object is.
46 inline static size_t objectSize(void *ptr);
48 // Set our process heap.
49 inline void setpHeap(processHeap *p);
51 private:
52 // Prevent copying and assignment.
53 threadHeap(const threadHeap &);
54 const threadHeap &operator=(const threadHeap &);
56 // Our process heap.
57 processHeap *_pHeap;
59 // We insert a cache pad here to avoid false sharing (the
60 // processHeap holds an array of threadHeaps, and we don't want
61 // these to share any cache lines).
62 double _pad[CACHE_LINE / sizeof(double)];
66 void *
67 threadHeap::memalign(size_t alignment, size_t size)
69 // Calculate the amount of space we need
70 // to satisfy the alignment requirements.
72 size_t newSize;
74 // If the alignment is less than the required alignment,
75 // just call malloc.
76 if (alignment <= ALIGNMENT)
77 return this->malloc(size);
79 if (alignment < sizeof(block))
80 alignment = sizeof(block);
82 // Alignment must be a power of two!
83 assert((alignment & (alignment - 1)) == 0);
85 // Leave enough room to align the block within the malloced space.
86 newSize = size + sizeof(block) + alignment;
88 // Now malloc the space up with a little extra (we'll put the block
89 // pointer in right behind the allocated space).
91 void *ptr = this->malloc(newSize);
92 if ((((unsigned long) ptr) & -((long) alignment)) == 0) {
93 // ptr is already aligned, so return it.
94 assert(((unsigned long) ptr % alignment) == 0);
95 return ptr;
96 } else {
97 // Align ptr.
98 char *newptr = (char *)(((unsigned long)ptr + alignment - 1) & -((long)alignment));
100 // If there's not enough room for the block header, skip to the
101 // next aligned space within the block..
102 if ((unsigned long)newptr - (unsigned long)ptr < sizeof(block))
103 newptr += alignment;
105 assert(((unsigned long)newptr % alignment) == 0);
107 // Copy the block from the start of the allocated memory.
108 block *b = ((block *)ptr - 1);
110 assert(b->isValid());
111 assert(b->getSuperblock()->isValid());
113 // Make sure there's enough room for the block header.
114 assert(((unsigned long)newptr - (unsigned long)ptr) >=
115 sizeof(block));
117 block *p = ((block *)newptr - 1);
119 // Make sure there's enough room allocated for size bytes.
120 assert(((unsigned long)p - sizeof(block)) >= (unsigned long)b);
122 if (p != b) {
123 assert((unsigned long)newptr > (unsigned long)ptr);
124 // Copy the block header.
125 *p = *b;
126 assert(p->isValid());
127 assert(p->getSuperblock()->isValid());
129 // Set the next pointer to point to b with the 1 bit set.
130 // When this block is freed, it will be treated specially.
131 p->setNext((block *)((unsigned long)b | 1));
132 } else
133 assert(ptr != newptr);
135 assert(((unsigned long)ptr + newSize) >=
136 ((unsigned long)newptr + size));
137 return newptr;
142 size_t
143 threadHeap::objectSize(void *ptr)
145 // Find the superblock pointer.
146 block *b = ((block *)ptr - 1);
147 assert(b->isValid());
148 superblock *sb = b->getSuperblock();
149 assert(sb);
151 // Return the size.
152 return sizeFromClass(sb->getBlockSizeClass());
156 void threadHeap::setpHeap(processHeap *p)
158 _pHeap = p;
161 } // namespace BPrivate
163 #endif // _THREADHEAP_H_