xref: /haiku/src/system/libroot/posix/malloc/hoard2/superblock.cpp (revision fc7456e9b1ec38c941134ed6d01c438cf289381e)
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.
11 //
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.
16 //
17 //////////////////////////////////////////////////////////////////////////////
18 
19 /*
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   ========================================================================
29 */
30 
31 #include <string.h>
32 
33 #include "arch-specific.h"
34 #include "config.h"
35 #include "heap.h"
36 #include "processheap.h"
37 #include "superblock.h"
38 
39 using namespace BPrivate;
40 
41 
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.
45 	:
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)
53 {
54 	assert(_numBlocks >= 1);
55 
56 	// Determine the size of each block.
57 	const int blksize = hoardHeap::align(sizeof(block)
58 		+ hoardHeap::sizeFromClass(_sizeClass));
59 
60 	// Make sure this size is in fact aligned.
61 	assert((blksize & hoardHeap::ALIGNMENT_MASK) == 0);
62 
63 	// Set the first block to just past this superblock header.
64 	block *b = (block *) hoardHeap::align((unsigned long)(this + 1));
65 
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);
76 	}
77 
78 	_numAvailable = _numBlocks;
79 	computeFullness();
80 	assert((unsigned long)b <= hoardHeap::align(sizeof(superblock) + blksize * _numBlocks)
81 		+ (unsigned long)this);
82 
83 	hoardLockInit(_upLock, "hoard superblock");
84 }
85 
86 
87 superblock *
88 superblock::makeSuperblock(int sizeclass, processHeap *pHeap)
89 {
90 	// We need to get more memory.
91 
92 	char *buf;
93 	int numBlocks = hoardHeap::numBlocks(sizeclass);
94 
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));
102 
103 		// Get some memory from the process heap.
104 		buf = (char *)pHeap->getSuperblockBuffer();
105 	} else {
106 		// One object.
107 		assert(numBlocks == 1);
108 
109 		size_t blksize = hoardHeap::align(sizeof(block)
110 			+ hoardHeap::sizeFromClass(sizeclass));
111 		moreMemory = hoardHeap::align(sizeof(superblock) + blksize);
112 
113 		// Get space from the system.
114 		buf = (char *)hoardSbrk(moreMemory);
115 	}
116 
117 	// Make sure that we actually got the memory.
118 	if (buf == NULL)
119 		return 0;
120 
121 	buf = (char *)hoardHeap::align((unsigned long)buf);
122 
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);
126 
127 	// Instantiate the new superblock in the buffer.
128 	return new(buf) superblock(numBlocks, sizeclass, NULL);
129 }
130