1 /****************************************************************************
2 * Copyright (C) 2006-2008 by Jason Ansel *
3 * jansel@csail.mit.edu *
4 * *
5 * This file is part of the JALIB module of DMTCP (DMTCP:dmtcp/jalib). *
6 * *
7 * DMTCP:dmtcp/jalib is free software: you can redistribute it and/or *
8 * modify it under the terms of the GNU Lesser General Public License as *
9 * published by the Free Software Foundation, either version 3 of the *
10 * License, or (at your option) any later version. *
11 * *
12 * DMTCP:dmtcp/src is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU Lesser General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with DMTCP:dmtcp/src. If not, see *
19 * <http://www.gnu.org/licenses/>. *
20 ****************************************************************************/
21
22 #include "jalloc.h"
23 #include <pthread.h>
24 #include <stdio.h>
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 static pthread_mutex_t allocateLock = PTHREAD_MUTEX_INITIALIZER;
31
32 void jalib::JAllocDispatcher::reset_on_fork()
33 {
34 pthread_mutex_t tmpLock = PTHREAD_MUTEX_INITIALIZER;
35 allocateLock = tmpLock;
36 }
37
38 void jalib::JAllocDispatcher::lock()
39 {
40 if(pthread_mutex_lock(&allocateLock) != 0)
41 perror("JGlobalAlloc::ckptThreadAcquireLock");
42 }
43
44 void jalib::JAllocDispatcher::unlock()
45 {
46 if(pthread_mutex_unlock(&allocateLock) != 0)
47 perror("JGlobalAlloc::ckptThreadReleaseLock");
48 }
49
50
51 #ifdef JALIB_ALLOCATOR
52
53 #include <sys/mman.h>
54 #include <unistd.h>
55 #include <stdlib.h>
56 #include <sys/user.h>
57
58
59 namespace jalib
60 {
61
62 inline void* _alloc_raw(size_t n) {
63 #ifdef JALIB_USE_MALLOC
64 return malloc(n);
65 #else
66
67 //#define USE_DMTCP_ALLOC_ARENA
68 # ifdef USE_DMTCP_ALLOC_ARENA
69 #ifndef __x86_64__
70 #error "USE_DMTCP_ALLOC_ARENA can't be used with 32-bit binaries"
71 #endif
72 static void *mmapHintAddr = (void*) 0x1f000000000;
73 if (n % PAGE_SIZE != 0) {
74 n = (n + PAGE_SIZE) - (n % PAGE_SIZE);
75 }
76 void* p = mmap(mmapHintAddr, n, PROT_READ | PROT_WRITE,
77 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
78 if (p!= MAP_FAILED)
79 mmapHintAddr = p + n;
80 # else
81 void* p = mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
82 # endif
83
84 if(p==MAP_FAILED)
85 perror("_alloc_raw: ");
86 return p;
87 #endif
88 }
89
90 inline void _dealloc_raw(void* ptr, size_t n) {
91 #ifdef JALIB_USE_MALLOC
92 free(ptr);
93 #else
94 if(ptr==0 || n==0) return;
95 int rv = munmap(ptr, n);
96 if(rv!=0)
97 perror("_dealloc_raw: ");
98 #endif
99 }
100
101 template < size_t _N, size_t BLOCKSIZE>
102 class JFixedAllocStack {
103 public:
104 enum { N=_N };
|
Event uninit_member: |
Non-static class member padding is not initialized in this constructor nor in any functions that it calls. |
| Also see events: |
[member_decl] |
105 JFixedAllocStack() : _root(NULL) {}
106
107 //allocate a chunk of size N
108 void* allocate() {
109 if(_root == NULL) expand();
110 FreeItem* item = _root;
111 _root = item->next;
112 item->next = NULL;
113 return item;
114 }
115
116 //deallocate a chunk of size N
117 void deallocate(void* ptr) {
118 FreeItem* item = static_cast<FreeItem*>(ptr);
119 item->next = _root;
120 _root = item;
121 }
122 protected:
123 //allocate more raw memory when stack is empty
124 void expand() {
125 FreeItem* bufs = static_cast<FreeItem*>(_alloc_raw(BLOCKSIZE));
126 int count=BLOCKSIZE / sizeof(FreeItem);
127 for(int i=0; i<count-1; ++i){
128 bufs[i].next=bufs+i+1;
129 }
130 bufs[count-1].next = _root;
131 _root=bufs;
132 }
133 protected:
134 struct FreeItem {
135 union {
136 FreeItem* next;
137 char buf[N];
138 };
139 };
140 private:
141 FreeItem* _root;
|
Event member_decl: |
Class member declaration for padding. |
| Also see events: |
[uninit_member] |
142 char padding[128];
143 };
144
145 // FIXME: Do we really need this class now? --Kapil
146 template < typename Alloc >
147 class JGlobalAlloc {
148 public:
149 enum { N = Alloc::N };
150
151 static void* allocate(){
152 #if 0
153 if(pthread_mutex_lock(theMutex()) != 0)
154 perror("JGlobalAlloc::allocate");
155 #endif
156
157 void* ptr = theAlloc().allocate();
158
159 #if 0
160 if(pthread_mutex_unlock(theMutex()) != 0)
161 perror("JGlobalAlloc::allocate");
162 #endif
163
164 return ptr;
165 }
166
167 //deallocate a chunk of size N
168 static void deallocate(void* ptr){
169 #if 0
170 if(pthread_mutex_lock(theMutex()) != 0)
171 perror("JGlobalAlloc::allocate");
172 #endif
173
174 theAlloc().deallocate(ptr);
175
176 #if 0
177 if(pthread_mutex_unlock(theMutex()) != 0)
178 perror("JGlobalAlloc::allocate");
179 #endif
180 }
181
182 private:
183 static pthread_mutex_t* theMutex() {
184 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
185 return &m;
186 }
187 static Alloc& theAlloc() {
188 static Alloc a;
189 return a;
190 }
191 };
192
193 typedef JGlobalAlloc< JFixedAllocStack<64 , 1024*16 > > lvl1;
194 typedef JGlobalAlloc< JFixedAllocStack<256, 1024*16 > > lvl2;
195 typedef JGlobalAlloc< JFixedAllocStack<1024, 1024*16 > > lvl3;
196
197 void* JAllocDispatcher::allocate(size_t n) {
198 lock();
199 void *retVal;
200 if(n <= lvl1::N) retVal = lvl1::allocate(); else
201 if(n <= lvl2::N) retVal = lvl2::allocate(); else
202 if(n <= lvl3::N) retVal = lvl3::allocate(); else
203 retVal = _alloc_raw(n);
204 unlock();
205 return retVal;
206 }
207 void JAllocDispatcher::deallocate(void* ptr, size_t n){
208 lock();
209 if(n <= lvl1::N) lvl1::deallocate(ptr); else
210 if(n <= lvl2::N) lvl2::deallocate(ptr); else
211 if(n <= lvl3::N) lvl3::deallocate(ptr); else
212 _dealloc_raw(ptr, n);
213 unlock();
214 }
215
216 } // namespace jalib
217
218 #else
219
220 #include <stdlib.h>
221
222 void* jalib::JAllocDispatcher::allocate(size_t n) {
223 lock();
224 void* p = malloc(n);
225 unlock();
226 return p;
227 }
228 void jalib::JAllocDispatcher::deallocate(void* ptr, size_t){
229 lock();
230 free(ptr);
231 unlock();
232 }
233
234 #endif
235
236 #ifdef OVERRIDE_GLOBAL_ALLOCATOR
237 # ifndef JALIB_ALLOCATOR
238 # error "JALIB_ALLOCATOR must be #defined in dmtcp/jalib/jalloc.h for --enable-allocator to work"
239 # endif
240 void* operator new(size_t nbytes){
241 size_t* p = (size_t*) jalib::JAllocDispatcher::allocate(nbytes+sizeof(size_t));
242 *p = nbytes;
243 p+=1;
244 return p;
245 }
246
247 void operator delete(void* _p){
248 size_t* p = (size_t*) _p;
249 p-=1;
250 jalib::JAllocDispatcher::deallocate(p, *p+sizeof(size_t));
251 }
252 #endif