source: proiecte/swift/trunk/lib/hoard-371/src/hoardsuperblockheader.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.6 KB
Line 
1// -*- C++ -*-
2
3#ifndef _HOARDSUPERBLOCKHEADER_H_
4#define _HOARDSUPERBLOCKHEADER_H_
5
6#include <stdlib.h>
7
8namespace Hoard {
9
10template <class LockType,
11          int SuperblockSize,
12          typename HeapType>
13class HoardSuperblock;
14
15template <class LockType,
16          int SuperblockSize,
17          typename HeapType>
18class HoardSuperblockHeader {
19public:
20
21  HoardSuperblockHeader (size_t sz, size_t bufferSize)
22    : magicNumber (MAGIC_NUMBER),
23      objectSize (sz),
24      objectSizeIsPowerOfTwo (!(sz & (sz - 1)) && sz),
25      totalObjects (bufferSize / sz),
26      owner (NULL),
27      prev (NULL),
28      next (NULL),
29      reapableObjects (bufferSize / sz),
30      objectsFree (bufferSize / sz),
31      start ((char *) (this + 1)),
32      position (start)
33  {
34  }
35 
36  inline void * malloc (void) {
37    assert (isValid());
38    void * ptr = reapAlloc();
39    if (!ptr) {
40      ptr = freeListAlloc();
41    }
42    assert ((size_t) ptr % sizeof(double) == 0);
43    return ptr;
44  }
45
46  inline void free (void * ptr) {
47    assert (isValid());
48    freeList.insert (reinterpret_cast<FreeSLList::Entry *>(ptr));
49    objectsFree++;
50    if (objectsFree == totalObjects) {
51      clear();
52    }
53  }
54
55  void clear (void) {
56    assert (isValid());
57    // Clear out the freelist.
58    freeList.clear();
59    // All the objects are now free.
60    objectsFree = totalObjects;
61    reapableObjects = totalObjects;
62    position = start;
63  }
64
65  /// @brief Returns the actual start of the object.
66  INLINE void * normalize (void * ptr) const {
67    assert (isValid());
68    size_t offset = (size_t) ptr - (size_t) start;
69    void * p;
70
71    // Optimization note: the modulo operation (%) is *really* slow on
72    // some architectures (notably x86-64). To reduce its overhead, we
73    // optimize for the case when the size request is a power of two,
74    // which is often enough to make a difference.
75
76    if (objectSizeIsPowerOfTwo) {
77      p = (void *) ((size_t) ptr - (offset & (objectSize - 1)));
78    } else {
79      p = (void *) ((size_t) ptr - (offset % objectSize));
80    }
81    return p;
82  }
83
84
85  size_t getSize (void * ptr) const {
86    assert (isValid());
87    size_t offset = (size_t) ptr - (size_t) start;
88    size_t newSize;
89    if (objectSizeIsPowerOfTwo) {
90      newSize = objectSize - (offset & (objectSize - 1));
91    } else {
92      newSize = objectSize - (offset % objectSize);
93    }
94    return newSize;
95  }
96
97  size_t getObjectSize (void) const {
98    return objectSize;
99  }
100
101  int getTotalObjects (void) const {
102    return totalObjects;
103  }
104
105  int getObjectsFree (void) const {
106    return objectsFree;
107  }
108
109  HeapType * getOwner (void) const {
110    return owner;
111  }
112
113  void setOwner (HeapType * o) {
114    owner = o;
115  }
116
117  bool isValid (void) const {
118    return (magicNumber == MAGIC_NUMBER);
119  }
120
121  HoardSuperblock<LockType, SuperblockSize, HeapType> * getNext (void) const {
122    return next;
123  }
124
125  HoardSuperblock<LockType, SuperblockSize, HeapType> * getPrev (void) const {
126    return prev;
127  }
128
129  void setNext (HoardSuperblock<LockType, SuperblockSize, HeapType> * n) {
130    next = n;
131  }
132
133  void setPrev (HoardSuperblock<LockType, SuperblockSize, HeapType> * p) {
134    prev = p;
135  }
136
137  void lock (void) {
138    theLock.lock();
139  }
140
141  void unlock (void) {
142    theLock.unlock();
143  }
144
145private:
146
147  MALLOC_FUNCTION INLINE void * reapAlloc (void) {
148    assert (isValid());
149    assert (position);
150    // Reap mode.
151    if (reapableObjects > 0) {
152      char * ptr = position;
153      position = ptr + objectSize;
154      reapableObjects--;
155      objectsFree--;
156      return ptr;
157    } else {
158      return NULL;
159    }
160  }
161
162  MALLOC_FUNCTION INLINE void * freeListAlloc (void) {
163    assert (isValid());
164    // Freelist mode.
165    char * ptr = reinterpret_cast<char *>(freeList.get());
166    if (ptr) {
167      assert (objectsFree >= 1);
168      objectsFree--;
169    }
170    return ptr;
171  }
172
173  enum { MAGIC_NUMBER = 0xcafed00d };
174
175  const size_t magicNumber;
176
177  /// The object size.
178  const size_t objectSize;
179
180  const bool objectSizeIsPowerOfTwo;
181
182  /// Total objects in the superblock.
183  const int totalObjects;
184
185  /// The lock.
186  LockType theLock;
187
188  /// The owner of this superblock.
189  HeapType * owner;
190
191  /// The preceding superblock in a linked list.
192  HoardSuperblock<LockType, SuperblockSize, HeapType> * prev;
193
194  /// The succeeding superblock in a linked list.
195  HoardSuperblock<LockType, SuperblockSize, HeapType> * next;
196   
197  /// The number of objects available to be 'reap'ed.
198  int reapableObjects;
199
200  /// The number of objects available for (re)use.
201  int objectsFree;
202
203  /// The start of reap allocation.
204  char * start;
205
206  /// The list of freed objects.
207  FreeSLList freeList;
208
209  /// The cursor into the buffer following the header.
210  char * position;
211
212private:
213
214  double _dummy; // for alignment
215};
216
217};
218
219#endif
Note: See TracBrowser for help on using the repository browser.