source: proiecte/swift/trunk/lib/hoard-371/src/heaplayers/experimental/bigchunk.h @ 176

Last change on this file since 176 was 176, checked in by (none), 14 years ago
  • imported repo from "guagal"
File size: 4.8 KB
Line 
1/* -*- C++ -*- */
2
3#ifndef _BIGCHUNK_H_
4#define _BIGCHUNK_H_
5
6#include <assert.h>
7
8template <int chunkSize, int slotSize, class Super>
9class BigChunk {
10public:
11
12  inline BigChunk (void);
13
14  // Get and put slots.
15  // Get returns NULL if there are no slots available.
16  inline void * getSlot (void);
17  inline void putSlot (void *);
18
19  // How many slots are there in total?
20  inline static int getNumSlots (void);
21
22  // How many slots are available?
23  inline int getNumSlotsFree (void);
24
25  // How many slots are available?
26  inline int getNumSlotsInUse (void);
27
28  // Find a chunk given its slot.
29  inline static BigChunk * getChunk (void *);
30
31  class ChunkBlock {
32  public:
33    void setChunk (BigChunk * ch) { _myChunk = ch; }
34    BigChunk * getChunk (void) { return _myChunk; }
35    void setNext (ChunkBlock * n) { _next = n; }
36    ChunkBlock * getNext (void) { return _next; }
37  private:
38    BigChunk * _myChunk;   // If allocated, point to the chunk.
39    ChunkBlock * _next; // If not allocated, point to the next chunk block.
40  };
41
42  // Find a chunk block for a given pointer.
43  static inline ChunkBlock * getChunkBlock (void * ptr) {
44        assert (ptr != NULL);
45        return (ChunkBlock *) ptr - 1;
46  }
47
48  void setHeap (Super * h) {
49        heap = h;
50  }
51
52  inline Super * getHeap (void) {
53        return heap;
54  }
55
56  // Add doubly linked-list operations.
57  inline BigChunk * getNext (void);
58  inline BigChunk * getPrev (void);
59  inline void setNext (BigChunk *);
60  inline void setPrev (BigChunk *);
61
62private:
63
64  static inline size_t align (size_t sz) {
65    return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
66  }
67
68  ChunkBlock * freeSlots;
69  int numSlotsAvailable;
70  Super * heap;
71  BigChunk * prev;
72  BigChunk * next;
73};
74
75
76template <int chunkSize, int slotSize, class Super>
77BigChunk<chunkSize, slotSize, Super> * BigChunk<chunkSize, slotSize, Super>::getNext (void)
78{
79  return next;
80}
81
82
83template <int chunkSize, int slotSize, class Super>
84BigChunk<chunkSize, slotSize, Super> * BigChunk<chunkSize, slotSize, Super>::getPrev (void)
85{
86  return prev;
87}
88
89
90template <int chunkSize, int slotSize, class Super>
91void BigChunk<chunkSize, slotSize, Super>::setNext (BigChunk<chunkSize, slotSize, Super> * ptr)
92{
93  next = ptr;
94}
95
96
97template <int chunkSize, int slotSize, class Super>
98void BigChunk<chunkSize, slotSize, Super>::setPrev (BigChunk<chunkSize, slotSize, Super> * ptr)
99{
100  prev = ptr;
101}
102
103
104template <int chunkSize, int slotSize, class Super>
105BigChunk<chunkSize, slotSize, Super>::BigChunk (void)
106  : freeSlots (NULL),
107    numSlotsAvailable (getNumSlots()),
108        prev (NULL),
109        next (NULL)
110{
111  //printf ("numSlots = %d\n", numSlots);
112  int numSlots = getNumSlots();
113  assert (numSlots > 0);
114  const int blksize = align(sizeof(ChunkBlock) + slotSize);
115  //printf ("blksize = %d\n", blksize);
116  // Carve up the chunk into a number of slots.
117  ChunkBlock * b = (ChunkBlock *) (this + 1);
118  for (int i = 0; i < numSlots; i++) {
119        assert ((unsigned long) b < ((unsigned long) (this + 1) + blksize * numSlots));
120    new (b) ChunkBlock;
121    b->setChunk (this);
122        assert (b->getChunk() == this);
123    b->setNext (freeSlots);
124    freeSlots = b;
125    b = (ChunkBlock *) ((char *) b + blksize);
126  }
127}
128
129
130template <int chunkSize, int slotSize, class Super>
131void * BigChunk<chunkSize, slotSize, Super>::getSlot (void)
132{
133  if (freeSlots == NULL) {
134    assert (numSlotsAvailable == 0);
135    return NULL;
136  }
137  assert (numSlotsAvailable > 0);
138  assert (numSlotsAvailable <= getNumSlots());
139  ChunkBlock * b = freeSlots;
140  freeSlots = freeSlots->getNext();
141  numSlotsAvailable--;
142  b->setChunk (this); // FIX ME -- this should be unnecessary.
143  b->setNext (NULL);
144  void * ptr = (void *) (b + 1);
145  BigChunk<chunkSize, slotSize, Super> * bch = getChunk(ptr);
146  assert (bch == this);
147  return (void *) (b + 1);
148}
149
150
151template <int chunkSize, int slotSize, class Super>
152void BigChunk<chunkSize, slotSize, Super>::putSlot (void * ptr)
153{
154  assert (numSlotsAvailable >= 0);
155  assert (numSlotsAvailable <= getNumSlots());
156  ChunkBlock * b = getChunkBlock (ptr);
157  assert (b->getChunk() == this);
158  b->setNext (freeSlots);
159  freeSlots = b;
160  numSlotsAvailable++;
161  assert (numSlotsAvailable > 0);
162  assert (numSlotsAvailable <= getNumSlots());
163}
164
165
166template <int chunkSize, int slotSize, class Super>
167int BigChunk<chunkSize, slotSize, Super>::getNumSlots (void)
168{
169  return ((chunkSize - sizeof(BigChunk)) / align (sizeof(ChunkBlock) + slotSize));
170}
171
172
173template <int chunkSize, int slotSize, class Super>
174int BigChunk<chunkSize, slotSize, Super>::getNumSlotsFree (void)
175{
176  return numSlotsAvailable;
177}
178
179
180template <int chunkSize, int slotSize, class Super>
181int BigChunk<chunkSize, slotSize, Super>::getNumSlotsInUse (void)
182{
183  return getNumSlots() - numSlotsAvailable;
184}
185
186
187template <int chunkSize, int slotSize, class Super>
188BigChunk<chunkSize, slotSize, Super> * BigChunk<chunkSize, slotSize, Super>::getChunk (void * ptr)
189{
190  ChunkBlock * ch = getChunkBlock (ptr);
191  return ch->getChunk();
192}
193
194#endif
Note: See TracBrowser for help on using the repository browser.