source: proiecte/swift/trunk/lib/hoard-371/src/heaplayers/experimental/chunk.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.3 KB
Line 
1/* -*- C++ -*- */
2
3#ifndef _CHUNK_H_
4#define _CHUNK_H_
5
6/*
7
8  Heap Layers: An Extensible Memory Allocation Infrastructure
9 
10  Copyright (C) 2000-2003 by Emery Berger
11  http://www.cs.umass.edu/~emery
12  emery@cs.umass.edu
13 
14  This program is free software; you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation; either version 2 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  GNU General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program; if not, write to the Free Software
26  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
28*/
29
30#include <assert.h>
31
32namespace HL {
33
34template <int chunkSize, int slotSize>
35class Chunk {
36public:
37
38  inline Chunk (void);
39
40  // Get and put slots.
41  // Get returns NULL if there are no slots available.
42  inline void * getSlot (void);
43  inline void putSlot (void *);
44
45  // How many slots are there in total?
46  inline static int getNumSlots (void);
47
48  // How many slots are available?
49  inline int getNumSlotsFree (void);
50
51  // How many slots are available?
52  inline int getNumSlotsInUse (void);
53
54  // Find a chunk given its slot.
55  inline static Chunk * getChunk (void *);
56
57  class ChunkBlock {
58  public:
59    void setChunk (Chunk * ch) { _myChunk = ch; }
60    Chunk * getChunk (void) { return _myChunk; }
61    void setNext (ChunkBlock * n) { _next = n; }
62    ChunkBlock * getNext (void) { return _next; }
63  private:
64    Chunk * _myChunk;   // If allocated, point to the chunk.
65    ChunkBlock * _next; // If not allocated, point to the next chunk block.
66  };
67
68  // Find a chunk block for a given pointer.
69  static inline ChunkBlock * getChunkBlock (void * ptr) {
70        assert (ptr != NULL);
71        return (ChunkBlock *) ptr - 1;
72  }
73
74private:
75
76  ChunkBlock * freeSlots;
77  int numSlotsAvailable;
78
79  static inline size_t align (size_t sz) {
80    return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
81  }
82
83};
84
85template <int chunkSize, int slotSize>
86Chunk<chunkSize, slotSize>::Chunk (void)
87  : freeSlots (NULL),
88    numSlotsAvailable (getNumSlots())
89{
90  //printf ("numSlots = %d\n", numSlots);
91  int numSlots = getNumSlots();
92  assert (numSlots > 0);
93  const int blksize = align(sizeof(ChunkBlock) + slotSize);
94  //printf ("blksize = %d\n", blksize);
95  // Carve up the chunk into a number of slots.
96  ChunkBlock * b = (ChunkBlock *) (this + 1);
97  for (int i = 0; i < numSlots; i++) {
98        assert ((unsigned long) b < ((unsigned long) (this + 1) + blksize * numSlots));
99    new (b) ChunkBlock;
100    b->setChunk (this);
101        assert (b->getChunk() == this);
102    b->setNext (freeSlots);
103    freeSlots = b;
104    b = (ChunkBlock *) ((char *) b + blksize);
105  }
106}
107
108
109template <int chunkSize, int slotSize>
110void * Chunk<chunkSize, slotSize>::getSlot (void)
111{
112  if (freeSlots == NULL) {
113    assert (numSlotsAvailable == 0);
114    return NULL;
115  }
116  assert (numSlotsAvailable > 0);
117  ChunkBlock * b = freeSlots;
118  freeSlots = freeSlots->getNext();
119  numSlotsAvailable--;
120  b->setChunk (this); // FIX ME -- this should be unnecessary.
121  b->setNext (NULL);
122  void * ptr = (void *) (b + 1);
123  Chunk<chunkSize, slotSize> * bch = getChunk(ptr);
124  assert (bch == this);
125  return (void *) (b + 1);
126}
127
128
129template <int chunkSize, int slotSize>
130void Chunk<chunkSize, slotSize>::putSlot (void * ptr)
131{
132  ChunkBlock * b = getChunkBlock (ptr);
133  assert (b->getChunk() == this);
134  b->setNext (freeSlots);
135  freeSlots = b;
136  numSlotsAvailable++;
137  assert (numSlotsAvailable <= getNumSlots());
138}
139
140
141template <int chunkSize, int slotSize>
142int Chunk<chunkSize, slotSize>::getNumSlots (void)
143{
144  return ((chunkSize - sizeof(Chunk)) / align (sizeof(ChunkBlock) + slotSize));
145}
146
147
148template <int chunkSize, int slotSize>
149int Chunk<chunkSize, slotSize>::getNumSlotsFree (void)
150{
151  return numSlotsAvailable;
152}
153
154
155template <int chunkSize, int slotSize>
156int Chunk<chunkSize, slotSize>::getNumSlotsInUse (void)
157{
158  return getNumSlots() - numSlotsAvailable;
159}
160
161
162template <int chunkSize, int slotSize>
163Chunk<chunkSize, slotSize> * Chunk<chunkSize, slotSize>::getChunk (void * ptr)
164{
165  ChunkBlock * ch = getChunkBlock (ptr);
166  return ch->getChunk();
167}
168
169};
170
171#endif
Note: See TracBrowser for help on using the repository browser.