source: proiecte/swift/trunk/lib/hoard-371/src/redirectfree.h @ 176

Last change on this file since 176 was 176, checked in by (none), 14 years ago
  • imported repo from "guagal"
File size: 2.7 KB
Line 
1// -*- C++ -*-
2
3/*
4
5  Heap Layers: An Extensible Memory Allocation Infrastructure
6 
7  Copyright (C) 2000-2003 by Emery Berger
8  http://www.cs.umass.edu/~emery
9  emery@cs.umass.edu
10 
11  This program is free software; you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation; either version 2 of the License, or
14  (at your option) any later version.
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25*/
26
27#ifndef _REDIRECTFREE_H_
28#define _REDIRECTFREE_H_
29
30#include "fred.h"
31#include "guard.h"
32
33namespace Hoard {
34
35/**
36 * @class RedirectFree
37 * @brief Routes free calls to the Superblock's owner heap.
38 * @note  We also lock the heap on calls to malloc.
39 */
40
41template <class Heap,
42          typename SuperblockType_>
43class RedirectFree {
44public:
45
46  enum { Alignment = (int) Heap::Alignment };
47
48  typedef SuperblockType_ SuperblockType;
49
50  inline void * malloc (size_t sz) {
51    return _theHeap.malloc (sz);
52  }
53
54  size_t getSize (void * ptr) {
55    return Heap::getSize (ptr);
56  }
57
58  SuperblockType * getSuperblock (void * ptr) {
59    return Heap::getSuperblock (ptr);
60  }
61
62  /// Free the given object, obeying the required locking protocol.
63  static inline void free (void * ptr) {
64    // Get the superblock header.
65    SuperblockType * s = reinterpret_cast<SuperblockType *>(Heap::getSuperblock (ptr));
66
67    assert (s->isValidSuperblock());
68
69    // Find out who the owner is.
70
71    typedef BaseHoardManager<SuperblockType> * baseHeapType;
72    baseHeapType owner;
73
74    s->lock();
75
76    // By acquiring the lock on the superblock (above),
77    // we prevent it from moving up to a higher heap.
78    // This eventually pins it down in one heap,
79    // so this loop is guaranteed to terminate.
80    // (It should generally take no more than two iterations.)
81
82    for (;;) {
83      owner = reinterpret_cast<baseHeapType>(s->getOwner());
84      assert (owner != NULL);
85      assert (owner->isValid());
86      // Lock the owner. If ownership changed between these two lines,
87      // we'll detect it and try again.
88      owner->lock();
89      if (owner == reinterpret_cast<baseHeapType>(s->getOwner())) {
90        owner->free (ptr);
91        owner->unlock();
92        s->unlock();
93        return;
94      }
95      owner->unlock();
96
97      // Sleep a little.
98      HL::Fred::yield();
99    }
100  }
101
102private:
103
104  Heap _theHeap;
105
106};
107
108}
109
110#endif
Note: See TracBrowser for help on using the repository browser.