xref: /haiku/src/system/libroot/posix/malloc/hoard2/threadheap.cpp (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
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.
12 //
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.
17 //
18 //////////////////////////////////////////////////////////////////////////////
19 
20 //#include <limits.h>
21 #include <string.h>
22 
23 #include "config.h"
24 
25 #include "heap.h"
26 #include "threadheap.h"
27 #include "processheap.h"
28 
29 using namespace BPrivate;
30 
31 
32 threadHeap::threadHeap(void)
33 	:_pHeap(0)
34 {
35 }
36 
37 
38 // malloc (sz):
39 //   inputs: the size of the object to be allocated.
40 //   returns: a pointer to an object of the appropriate size.
41 //   side effects: allocates a block from a superblock;
42 //                 may call sbrk() (via makeSuperblock).
43 
44 void *
45 threadHeap::malloc(const size_t size)
46 {
47 #if MAX_INTERNAL_FRAGMENTATION == 2
48 	if (size > 1063315264UL) {
49 		debug_printf("malloc() of %lu bytes asked\n", size);
50 		return NULL;
51 	}
52 #endif
53 
54 	const int sizeclass = sizeClass(size);
55 	block *b = NULL;
56 
57 	lock();
58 
59 	// Look for a free block.
60 	// We usually have memory locally so we first look for space in the
61 	// superblock list.
62 
63 	superblock *sb = findAvailableSuperblock(sizeclass, b, _pHeap);
64 	if (sb == NULL) {
65 		// We don't have memory locally.
66 		// Try to get more from the process heap.
67 
68 		assert(_pHeap);
69 		sb = _pHeap->acquire((int)sizeclass, this);
70 
71 		// If we didn't get any memory from the process heap,
72 		// we'll have to allocate our own superblock.
73 		if (sb == NULL) {
74 			sb = superblock::makeSuperblock(sizeclass, _pHeap);
75 			if (sb == NULL) {
76 				// We're out of memory!
77 				unlock();
78 				return NULL;
79 			}
80 #if HEAP_LOG
81 			// Record the memory allocation.
82 			MemoryRequest m;
83 			m.allocate((int)sb->getNumBlocks() *
84 				(int)sizeFromClass(sb->getBlockSizeClass()));
85 			_pHeap->getLog(getIndex()).append(m);
86 #endif
87 #if HEAP_FRAG_STATS
88 			_pHeap->setAllocated(0,
89 				sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass()));
90 #endif
91 		}
92 		// Get a block from the superblock.
93 		b = sb->getBlock();
94 		assert(b != NULL);
95 
96 		// Insert the superblock into our list.
97 		insertSuperblock(sizeclass, sb, _pHeap);
98 	}
99 
100 	assert(b != NULL);
101 	assert(b->isValid());
102 	assert(sb->isValid());
103 
104 	b->markAllocated();
105 
106 #if HEAP_LOG
107 	MemoryRequest m;
108 	m.malloc((void *)(b + 1), align(size));
109 	_pHeap->getLog(getIndex()).append(m);
110 #endif
111 #if HEAP_FRAG_STATS
112 	b->setRequestedSize(align(size));
113 	_pHeap->setAllocated(align(size), 0);
114 #endif
115 
116 	unlock();
117 
118 	// Skip past the block header and return the pointer.
119 	return (void *)(b + 1);
120 }
121