1 ///-*-C++-*-//////////////////////////////////////////////////////////////////
3 // The Hoard Multiprocessor Memory Allocator
4 // Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery
6 // Copyright (c) 1998-2000, The University of Texas at Austin.
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 //////////////////////////////////////////////////////////////////////////////
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 ========================================================================
33 #include "arch-specific.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.
47 _magic(SUPERBLOCK_MAGIC
),
50 _numBlocks(numBlocks
),
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);
72 assert(b
->getSuperblock() == this);
73 b
->setNext(_freeList
);
75 b
= (block
*)((char *)b
+ blksize
);
78 _numAvailable
= _numBlocks
;
80 assert((unsigned long)b
<= hoardHeap::align(sizeof(superblock
) + blksize
* _numBlocks
)
81 + (unsigned long)this);
83 hoardLockInit(_upLock
, "hoard superblock");
88 superblock::makeSuperblock(int sizeclass
, processHeap
*pHeap
)
90 // We need to get more memory.
93 int numBlocks
= hoardHeap::numBlocks(sizeclass
);
95 // Compute how much memory we need.
96 unsigned long moreMemory
;
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();
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.
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
);