headers/bsd: Add sys/queue.h.
[haiku.git] / src / system / libroot / posix / malloc / superblock.cpp
blob5114ad826438738951fe0067ddd54a3e500467e3
1 ///-*-C++-*-//////////////////////////////////////////////////////////////////
2 //
3 // The Hoard Multiprocessor Memory Allocator
4 // Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery
5 //
6 // Copyright (c) 1998-2000, The University of Texas at Austin.
7 //
8 // This library is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU Library General Public License as
10 // published by the Free Software Foundation, http://www.fsf.org.
12 // This library is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // Library General Public License for more details.
17 //////////////////////////////////////////////////////////////////////////////
20 superblock.cpp
21 ------------------------------------------------------------------------
22 The superblock class controls a number of blocks (which are
23 allocatable units of memory).
24 ------------------------------------------------------------------------
25 Emery Berger | <http://www.cs.utexas.edu/users/emery>
26 Department of Computer Sciences | <http://www.cs.utexas.edu>
27 University of Texas at Austin | <http://www.utexas.edu>
28 ========================================================================
31 #include <string.h>
33 #include "arch-specific.h"
34 #include "config.h"
35 #include "heap.h"
36 #include "processheap.h"
37 #include "superblock.h"
39 using namespace BPrivate;
42 superblock::superblock(int numBlocks, // The number of blocks in the sb.
43 int szclass, // The size class of the blocks.
44 hoardHeap * o) // The heap that "owns" this sb.
46 #if HEAP_DEBUG
47 _magic(SUPERBLOCK_MAGIC),
48 #endif
49 _sizeClass(szclass),
50 _numBlocks(numBlocks),
51 _numAvailable(0),
52 _fullness(0), _freeList(NULL), _owner(o), _next(NULL), _prev(NULL)
54 assert(_numBlocks >= 1);
56 // Determine the size of each block.
57 const int blksize = hoardHeap::align(sizeof(block)
58 + hoardHeap::sizeFromClass(_sizeClass));
60 // Make sure this size is in fact aligned.
61 assert((blksize & hoardHeap::ALIGNMENT_MASK) == 0);
63 // Set the first block to just past this superblock header.
64 block *b = (block *) hoardHeap::align((unsigned long)(this + 1));
66 // Initialize all the blocks,
67 // and insert the block pointers into the linked list.
68 for (int i = 0; i < _numBlocks; i++) {
69 // Make sure the block is on a double-word boundary.
70 assert(((unsigned long)b & hoardHeap::ALIGNMENT_MASK) == 0);
71 new(b) block(this);
72 assert(b->getSuperblock() == this);
73 b->setNext(_freeList);
74 _freeList = b;
75 b = (block *)((char *)b + blksize);
78 _numAvailable = _numBlocks;
79 computeFullness();
80 assert((unsigned long)b <= hoardHeap::align(sizeof(superblock) + blksize * _numBlocks)
81 + (unsigned long)this);
83 hoardLockInit(_upLock, "hoard superblock");
87 superblock *
88 superblock::makeSuperblock(int sizeclass, processHeap *pHeap)
90 // We need to get more memory.
92 char *buf;
93 int numBlocks = hoardHeap::numBlocks(sizeclass);
95 // Compute how much memory we need.
96 unsigned long moreMemory;
97 if (numBlocks > 1) {
98 moreMemory = hoardHeap::SUPERBLOCK_SIZE;
99 assert(moreMemory >= hoardHeap::align(sizeof(superblock)
100 + (hoardHeap::align(sizeof(block)
101 + hoardHeap::sizeFromClass(sizeclass))) * numBlocks));
103 // Get some memory from the process heap.
104 buf = (char *)pHeap->getSuperblockBuffer();
105 } else {
106 // One object.
107 assert(numBlocks == 1);
109 size_t blksize = hoardHeap::align(sizeof(block)
110 + hoardHeap::sizeFromClass(sizeclass));
111 moreMemory = hoardHeap::align(sizeof(superblock) + blksize);
113 // Get space from the system.
114 buf = (char *)hoardSbrk(moreMemory);
117 // Make sure that we actually got the memory.
118 if (buf == NULL)
119 return 0;
121 buf = (char *)hoardHeap::align((unsigned long)buf);
123 // Make sure this buffer is double-word aligned.
124 assert(buf == (char *)hoardHeap::align((unsigned long)buf));
125 assert((((unsigned long)buf) & hoardHeap::ALIGNMENT_MASK) == 0);
127 // Instantiate the new superblock in the buffer.
128 return new(buf) superblock(numBlocks, sizeclass, NULL);