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

Last change on this file since 176 was 176, checked in by (none), 14 years ago
  • imported repo from "guagal"
File size: 3.9 KB
Line 
1// -*- C++ -*-
2
3/**
4 * @file alignedmmap.h
5 * @author Emery Berger <http://www.cs.umass.edu/~emery>
6 */
7
8
9#ifndef _ALIGNEDMMAP_H_
10#define _ALIGNEDMMAP_H_
11
12#include "sassert.h"
13#include "myhashmap.h"
14#include "freelistheap.h"
15#include "mmapwrapper.h"
16#include "bumpalloc.h"
17#include "exactlyone.h"
18#include "mmapalloc.h"
19
20using namespace std;
21using namespace HL;
22
23namespace Hoard {
24
25/**
26 * @class AlignedMmapInstance
27 * @brief Memory allocated from here is aligned with respect to Alignment.
28 * @author Emery Berger <http://www.cs.umass.edu/~emery>
29 */
30
31
32template <size_t Alignment_>
33class AlignedMmapInstance {
34public:
35
36  enum { Alignment = Alignment_ };
37
38  inline void * malloc (size_t sz) {
39
40    // Round up sz to the nearest page.
41    sz = (sz + HL::MmapWrapper::Size - 1) & ~(HL::MmapWrapper::Size - 1);
42
43    // If the memory is already suitably aligned, just track size requests.
44    if ((size_t) HL::MmapWrapper::Alignment % (size_t) Alignment == 0) {
45      void * ptr = HL::MmapWrapper::map (sz);
46      MyMap.set (ptr, sz);
47      return ptr;
48    }
49
50    // Try a map call and hope that it's suitably aligned. If we get lucky,
51    // we're done.
52
53    char * ptr = reinterpret_cast<char *>(HL::MmapWrapper::map (sz));
54
55    if (ptr == align(ptr)) {
56      // We're done.
57      MyMap.set (ptr, sz);
58      return ptr;
59    } else {
60      // Try again.
61      HL::MmapWrapper::unmap ((void *) ptr, sz);
62    }
63
64    // We have to align it ourselves. We get memory from
65    // mmap, align a pointer in the space, and free the space before
66    // and after the aligned segment.
67
68    ptr = reinterpret_cast<char *>(HL::MmapWrapper::map (sz + Alignment_));
69
70    if (ptr == NULL) {
71      return NULL;
72    }
73
74    char * newptr = align (ptr);
75
76    // Unmap the part before (prolog) and after.
77
78    size_t prolog = (size_t) newptr - (size_t) ptr;
79
80    if (prolog > 0) {
81      // Get rid of the prolog.
82      HL::MmapWrapper::unmap (ptr, prolog);
83    }
84
85    size_t epilog = Alignment_ - prolog;
86    HL::MmapWrapper::unmap ((char *) newptr + sz, epilog);
87
88    // Now record the size associated with this pointer.
89
90    MyMap.set (newptr, sz);
91    return newptr;
92  }
93
94  inline void free (void * ptr) {
95
96    // Find the object. If we don't find it, we didn't allocate it.
97    // For now, just ignore such an invalid free...
98
99    size_t requestedSize = MyMap.get (ptr);
100
101    if (requestedSize == 0) {
102      return;
103    }
104
105    HL::MmapWrapper::unmap (ptr, requestedSize);
106
107    // Finally, undo the mapping.
108    MyMap.erase (ptr);
109
110    assert (MyMap.get (ptr) == 0);
111  }
112 
113  inline size_t getSize (void * ptr) {
114    return MyMap.get (ptr);
115  }
116
117
118private:
119
120  /// Round a pointer up to the next Alignment-rounded chunk.
121  inline static char * align (char * buf) {
122    return (char *)(((size_t) buf + (Alignment_-1)) & ~(Alignment_-1));
123  }
124
125  // Manage information in a map that uses a custom heap for
126  // allocation.
127
128  /// The key is an mmapped pointer.
129  typedef void * keyType;
130
131  /// The value is the requested size.
132  typedef size_t valType;
133
134  // The heap from which memory comes for the Map's purposes.
135  // Objects come from chunks via mmap, and we manage these with a free list.
136  class SourceHeap : public HL::FreelistHeap<BumpAlloc<65536, MmapAlloc> > { };
137
138  /// The map type, with all the pieces in place.
139  typedef MyHashMap<keyType, valType, SourceHeap> mapType;
140
141  /// The map that maintains the size of each mmapped chunk.
142  mapType MyMap;
143
144};
145
146
147/**
148 * @class AlignedMmap
149 * @brief Route requests to the one aligned mmap instance.
150 * @author Emery Berger <http://www.cs.umass.edu/~emery>
151 */
152
153template <size_t Alignment_>
154class AlignedMmap : public ExactlyOne<AlignedMmapInstance<Alignment_> > {
155public:
156
157  enum { Alignment = Alignment_ };
158
159  inline void * malloc (size_t sz) {
160    return (*this)().malloc (sz);
161  }
162  inline void free (void * ptr) {
163    return (*this)().free (ptr);
164  }
165  inline size_t getSize (void * ptr) const {
166    return (*this)().getSize (ptr);
167  }
168 
169};
170
171};
172
173#endif
Note: See TracBrowser for help on using the repository browser.