10 #ifndef ROOT_Minuit2_StackAllocator
11 #define ROOT_Minuit2_StackAllocator
20 #ifdef MN_USE_STACK_ALLOC
21 #define _MN_NO_THREAD_SAVE_
41 class StackOverflow {};
52 class StackAllocator {
57 enum {default_size = 524288};
59 StackAllocator() : fStack(0) {
60 #ifdef _MN_NO_THREAD_SAVE_
62 fStack =
new unsigned char[default_size];
69 #ifdef _MN_NO_THREAD_SAVE_
71 if(fStack)
delete [] fStack;
75 void* Allocate(
size_t nBytes) {
76 #ifdef _MN_NO_THREAD_SAVE_
77 if(fStack == 0) fStack =
new unsigned char[default_size];
78 int nAlloc = AlignedSize(nBytes);
79 CheckOverflow(nAlloc);
84 WriteInt( fStackOffset, fStackOffset+nAlloc);
86 WriteInt( fStackOffset + nAlloc -
sizeof(
int), fStackOffset);
88 void* result = fStack + fStackOffset +
sizeof(int);
89 fStackOffset += nAlloc;
92 #ifdef DEBUG_ALLOCATOR
97 void* result = malloc(nBytes);
98 if (!result)
throw std::bad_alloc();
104 void Deallocate(
void* p) {
105 #ifdef _MN_NO_THREAD_SAVE_
107 int delBlock = ToInt(p);
108 int nextBlock = ReadInt( delBlock);
109 int previousBlock = ReadInt( nextBlock -
sizeof(
int));
110 if ( nextBlock == fStackOffset) {
112 fStackOffset = previousBlock;
116 int nextNextBlock = ReadInt(nextBlock);
117 WriteInt( nextNextBlock -
sizeof(
int), previousBlock);
119 WriteInt( previousBlock, nextNextBlock);
123 #ifdef DEBUG_ALLOCATOR
133 int ReadInt(
int offset) {
134 int* ip = (
int*)(fStack+offset);
141 void WriteInt(
int offset,
int Value) {
145 int* ip =
reinterpret_cast<int*
>(fStack+offset);
149 int ToInt(
void* p) {
150 unsigned char* pc =
static_cast<unsigned char*
>(p);
154 int userBlock = pc - fStack;
155 return userBlock -
sizeof(int);
158 int AlignedSize(
int nBytes) {
159 const int fAlignment = 4;
160 int needed = nBytes % fAlignment == 0 ? nBytes : (nBytes/fAlignment+1)*fAlignment;
161 return needed + 2*
sizeof(int);
164 void CheckOverflow(
int n) {
165 if (fStackOffset + n >= default_size) {
167 throw StackOverflow();
171 bool CheckConsistency() {
177 int end = fStackOffset;
179 while (beg < fStackOffset) {
185 int beg2 = ReadInt( end -
sizeof(
int));
193 if (end != fStackOffset) {
197 if (nblocks != fBlockCount) {
207 unsigned char* fStack;
216 class StackAllocatorHolder {
224 static StackAllocator & Get() {
225 static StackAllocator gStackAllocator;
226 return gStackAllocator;