source: GTP/trunk/Lib/Vis/Preprocessing/src/havran/allocgo2.cpp @ 2582

Revision 2582, 6.6 KB checked in by bittner, 16 years ago (diff)

Havran Ray Caster compiles and links, but still does not work

Line 
1// ===================================================================
2// $Id: $
3//
4// allocgo2.cpp
5//
6// REPLACEMENT_STRING
7//
8// Copyright by Vlastimil Havran, 2006 - email to "vhavran AT seznam.cz"
9// Initial coding by Vlastimil Havran, 2003
10
11// standard headers
12#include <cassert>
13#include <iostream>
14
15// GOLEM headers
16#include "allocgo2.h"
17
18namespace GtpVisibilityPreprocessor {
19
20using namespace std;
21
22// ************* size-equal item allocator with alligning in the cache ****
23
24CAllocContinuous::CAllocContinuous(int sizeOfEntryV,
25                                   int numEntriesInBlockV,
26                                   int maxItemsForAllocation,
27                                   int allignEntrySizeV,
28                                   int allignBlockSizeV)
29{
30  if ((sizeOfEntryV < ((int)sizeof(void*))) || (numEntriesInBlockV < 2)) {
31    cerr << "Error: The Spc size-equal allocator initialization wrong.\n";
32    abort();
33  }
34  // input variables
35  sizeOfEntry = sizeOfEntryV;
36  granularity = numEntriesInBlockV;
37  maxItemsAtOnce = maxItemsForAllocation;
38  // Increase the allignment to be at least of entry size
39  int ta =  allignEntrySizeV;
40  while (sizeOfEntryV > allignEntrySizeV) {
41    allignEntrySizeV += ta;
42  } // while
43  // Increase the allignment of the block to be at least the size of one entry
44  ta = allignBlockSizeV;
45  while (allignEntrySizeV > allignBlockSizeV) {
46    allignBlockSizeV += ta;
47  } // while
48
49  // The allignment of entry
50  allignEntrySize = allignEntrySizeV;
51
52  // The allingment of block
53  allignBlockSize = allignBlockSizeV;
54
55  // Compute the memory needed for one block
56  memoryForOneBlock = (sizeOfEntry * (granularity + 2*maxItemsAtOnce))/allignEntrySize;
57  memoryForOneBlock = (memoryForOneBlock + 1) * allignEntrySize;
58  // Now we want to make sure for the big allignment
59  memoryForOneBlock /= allignBlockSize;
60  memoryForOneBlock = (memoryForOneBlock+2) * allignBlockSize;
61 
62  // status variables
63  initMemBlock = 0;
64  mstor = &initMemBlock;
65  // Release the memory and prepare the variables
66  ReleaseMemory();
67
68#if 0
69  cout << "CAllocContinuous: item size " << sz << " alligned to size " << size
70         <<" granularity " << gran << "\n";
71  cout << "     BigAlignment=" << bigAllignment << "\n";
72#endif
73}
74
75void
76CAllocContinuous::ReleaseMemory()
77{
78  // delete all allocated memory blocks
79  void *bk = mstor;
80  void *p;
81  while (bk != &initMemBlock) {
82    p = *(void**)bk;
83    //cout << "Release " << "  p = " << (void*)bk << endl;
84    delete [] (char*)bk;
85    bk = p;
86  } // while
87  remainItems = 0;
88  initMemBlock = 0;
89  mstor = &initMemBlock;
90  bytesAllocated = 0;
91  lastEntryInBlockAllocated = 0;
92  nextAllocp = 0;
93  lastValidAddress = 0;
94}
95
96void*
97CAllocContinuous::AllocNewBlock()
98{
99  int allocHere = 0;
100  allocHere++;
101 
102  nextAllocp = new char[memoryForOneBlock]; // append to chain
103  if (nextAllocp == NULL) {
104    cerr << "Memory exhausted in CAllocContinuous\n";
105    abort();
106  }
107 
108#ifdef _DEBUG
109  memset((void*)nextAllocp, 0xFF, memoryForOneBlock);
110#endif 
111  // Compute the last valid address to be used in the current block
112  lastValidAddress = (void*)
113    (nextAllocp + memoryForOneBlock - 1);
114 
115  //cout << "ALloc " << allocHere << "  p = " << (void*)nextAllocp << endl;
116 
117  // Link the block to the chain of block !
118  *((void**)nextAllocp) = (void*)mstor; // link the previous chain
119  mstor = (void**)nextAllocp; // link the currently allocated block
120
121  // set chain of blocks .. allign the starting address
122  nextAllocp = (char*)(allignBlockSize * (((unsigned long)nextAllocp +
123                     sizeof(void*) + allignBlockSize - 1) / allignBlockSize));
124#ifdef _DEBUG
125  if ((unsigned long)mstor > (unsigned long)nextAllocp) {
126    cerr << "Allignment of the block is wrong" << endl;
127    abort();
128  }
129#endif
130  // Compute Allignment
131  unsigned long allignmentTotal = 2 * maxItemsAtOnce * sizeOfEntry;
132     
133  char *maxAddressInBlock = ((char*)mstor + memoryForOneBlock);
134  // We have to put there the place for the last entry
135  maxAddressInBlock -= allignmentTotal;
136
137  // The maximum number of single items to be allocated, which then allows
138  // also to allocate a last entry by a special routine
139  remainItems = (unsigned long)( maxAddressInBlock - ((char*)nextAllocp) );
140  remainItems /= sizeOfEntry;
141  remainItems -= 2 * maxItemsAtOnce;
142
143#ifdef _DEBUG
144  if (remainItems<0) {
145    cerr << "CAllocContinuous::Alloc Error\n";
146    abort();
147  }
148#endif
149
150  // Update the statistics, the total number of bytes allocated
151  // by the instance of this allocator
152  bytesAllocated += memoryForOneBlock;
153  //cout << "The Alloc called\n" << flush;
154
155  // We will be left with the last entry to allocate
156  lastEntryInBlockAllocated = false;
157 
158  // Return the address to be allocated as the next one
159  return (void*)nextAllocp;
160}
161
162// alloc the memory of size "sizeItem*entriesCnt" alligned in the memory
163// started in the new block
164void*
165CAllocContinuous::NewEntryInNewBlock(int entriesCnt)
166{
167  // We require first to allocate a new block
168  AllocNewBlock();
169  return New(entriesCnt);
170}
171
172void*
173CAllocContinuous::New(int entriesCnt)
174{
175  // void *m;  // <JK> is unreferenced
176  assert(entriesCnt > 0);
177  assert(entriesCnt <= maxItemsAtOnce);
178
179  if (remainItems < entriesCnt) {
180    return (void*)0; // not enough space left
181  }
182
183  unsigned long tmp = (unsigned long)nextAllocp;
184  if ((tmp % allignEntrySize) == 0) {
185    remainItems -= entriesCnt;
186    nextAllocp = (char*)(tmp + entriesCnt * sizeOfEntry);
187    return (void*)tmp;
188  }
189  // We have to allign the address to the allignEntrySize
190  tmp /= allignEntrySize;
191  tmp = (tmp+1) * allignEntrySize;
192  remainItems -= (tmp - (unsigned long)nextAllocp) / entriesCnt;
193  nextAllocp = (char*)(tmp + entriesCnt * sizeOfEntry);
194  assert(nextAllocp < lastValidAddress);
195 
196  return (void*)tmp;
197}
198
199// alloc the memory of size "sizeItem*entriesCnt" alligned in the memory
200// it can be in the current block, which is definitely the last one in
201// the current block. This should be used only if function New() above
202// returns 0.
203void*
204CAllocContinuous::NewLastEntry(int entriesCnt)
205{
206  if (!lastEntryInBlockAllocated) {
207    // if the last entry in the current block was not yet allocated
208    void *tmp = nextAllocp;
209#ifdef _DEBUG
210    // check if we do not go behind the block
211    if ( (unsigned long)tmp + sizeOfEntry * entriesCnt >
212         (unsigned long)lastValidAddress) {
213      cerr << "Problem with the allocator, using the memory" << endl;
214      abort();
215    }   
216#endif // _DEBUG
217    lastEntryInBlockAllocated = true; // do not allocate again
218    return nextAllocp;
219  } // if the last entry
220
221  return (void*)0; // the entry was already allocated
222}
223
224void
225CAllocContinuous::Report()
226{
227  cout << "Unused entries in the current block = " << remainItems << "\n";
228  cout << "Total consumed memory = " << bytesAllocated << "\n";
229}
230
231
232}
233
Note: See TracBrowser for help on using the repository browser.