model: add release sequence model_thread ASSERT()
[model-checker.git] / mymemory.cc
1 #include "mymemory.h"
2 #include "snapshot.h"
3 #include "snapshotimp.h"
4 #include <stdio.h>
5 #include <dlfcn.h>
6 #include <unistd.h>
7 #include <cstring>
8 #include "common.h"
9 #define REQUESTS_BEFORE_ALLOC 1024
10 size_t allocatedReqs[ REQUESTS_BEFORE_ALLOC ] = { 0 };
11 int nextRequest = 0;
12 int howManyFreed = 0;
13 #if !USE_MPROTECT_SNAPSHOT
14 static mspace sStaticSpace = NULL;
15 #endif
16
17 /** Non-snapshotting calloc for our use. */
18 void *model_calloc(size_t count, size_t size) {
19 #if USE_MPROTECT_SNAPSHOT
20         static void *(*callocp)(size_t count, size_t size)=NULL;
21         char *error;
22         void *ptr;
23
24         /* get address of libc malloc */
25         if (!callocp) {
26                 callocp = ( void * ( * )( size_t, size_t ) )dlsym(RTLD_NEXT, "calloc");
27                 if ((error = dlerror()) != NULL) {
28                         fputs(error, stderr);
29                         exit(EXIT_FAILURE);
30                 }
31         }
32         ptr = callocp(count, size);
33         return ptr;
34 #else
35         if( !snapshotrecord) {
36                 createSharedMemory();
37         }
38         if( NULL == sStaticSpace )
39                 sStaticSpace = create_mspace_with_base( ( void * )( snapshotrecord->mSharedMemoryBase ), SHARED_MEMORY_DEFAULT -sizeof( struct SnapShot ), 1 );
40         return mspace_calloc( sStaticSpace, count, size );
41 #endif
42 }
43
44 /** Non-snapshotting malloc for our use. */
45 void *model_malloc(size_t size) {
46 #if USE_MPROTECT_SNAPSHOT
47         static void *(*mallocp)(size_t size)=NULL;
48         char *error;
49         void *ptr;
50
51         /* get address of libc malloc */
52         if (!mallocp) {
53                 mallocp = ( void * ( * )( size_t ) )dlsym(RTLD_NEXT, "malloc");
54                 if ((error = dlerror()) != NULL) {
55                         fputs(error, stderr);
56                         exit(EXIT_FAILURE);
57                 }
58         }
59         ptr = mallocp(size);
60         return ptr;
61 #else
62         if( !snapshotrecord) {
63                 createSharedMemory();
64         }
65         if( NULL == sStaticSpace )
66                 sStaticSpace = create_mspace_with_base( ( void * )( snapshotrecord->mSharedMemoryBase ), SHARED_MEMORY_DEFAULT -sizeof( struct SnapShot ), 1 );
67         return mspace_malloc( sStaticSpace, size );
68 #endif
69 }
70
71 /** @brief Snapshotting malloc, for use by model-checker (not user progs) */
72 void * snapshot_malloc(size_t size)
73 {
74         return malloc(size);
75 }
76
77 /** @brief Snapshotting calloc, for use by model-checker (not user progs) */
78 void * snapshot_calloc(size_t count, size_t size)
79 {
80         return calloc(count, size);
81 }
82
83 /** @brief Snapshotting free, for use by model-checker (not user progs) */
84 void snapshot_free(void *ptr)
85 {
86         free(ptr);
87 }
88
89 void *system_malloc( size_t size ){
90         static void *(*mallocp)(size_t size);
91         char *error;
92         void *ptr;
93
94         /* get address of libc malloc */
95         if (!mallocp) {
96                 mallocp = ( void * ( * )( size_t ) )dlsym(RTLD_NEXT, "malloc");
97                 if ((error = dlerror()) != NULL) {
98                         fputs(error, stderr);
99                         exit(EXIT_FAILURE);
100                 }
101         }
102         ptr = mallocp(size);
103         return ptr;
104 }
105
106 void system_free( void * ptr ){
107         static void (*freep)(void *);
108         char *error;
109
110         /* get address of libc free */
111         if (!freep) {
112                 freep = ( void  ( * )( void * ) )dlsym(RTLD_NEXT, "free");
113                 if ((error = dlerror()) != NULL) {
114                         fputs(error, stderr);
115                         exit(EXIT_FAILURE);
116                 }
117         }
118         freep(ptr);
119 }
120
121 /** Non-snapshotting free for our use. */
122 void model_free(void *ptr) {
123 #if USE_MPROTECT_SNAPSHOT
124         static void (*freep)(void *);
125         char *error;
126
127         /* get address of libc free */
128         if (!freep) {
129                 freep = ( void  ( * )( void * ) )dlsym(RTLD_NEXT, "free");
130                 if ((error = dlerror()) != NULL) {
131                         fputs(error, stderr);
132                         exit(EXIT_FAILURE);
133                 }
134         }
135         freep(ptr);
136 #else
137         mspace_free( sStaticSpace, ptr );
138 #endif
139 }
140
141
142 /** @brief Global mspace reference for the snapshotting heap */
143 mspace mySpace = NULL;
144
145 /** @brief Global reference to the unaligned memory address that was malloc'd
146  * for the snapshotting heap */
147 void *basemySpace = NULL;
148
149 /** Bootstrap allocation.  Problem is that the dynamic linker calls
150  *  require calloc to work and calloc requires the dynamic linker to
151  *      work.  */
152
153 #define BOOTSTRAPBYTES 4096
154 char bootstrapmemory[BOOTSTRAPBYTES];
155 size_t offset=0;
156
157 void * HandleEarlyAllocationRequest( size_t sz ){
158         /*Align to 8 byte boundary*/
159         sz=(sz+7)&~7;
160
161         if (sz > (BOOTSTRAPBYTES-offset)) {
162                 printf("OUT OF BOOTSTRAP MEMORY\n");
163                 exit(EXIT_FAILURE);
164         }
165
166         void * pointer= (void *) & bootstrapmemory[offset];
167         offset+=sz;
168         return pointer;
169 }
170
171 /** Check whether this is bootstrapped memory that we should not
172                 free. */
173
174 bool DontFree( void * ptr ){
175         return (ptr>=(&bootstrapmemory[0])&&ptr<(&bootstrapmemory[BOOTSTRAPBYTES]));
176 }
177
178 /** @brief Snapshotting malloc implementation for user programs */
179 void *malloc( size_t size )
180 {
181         if (mySpace) {
182                 void *tmp=mspace_malloc( mySpace, size );
183                 ASSERT(tmp);
184                 return tmp;
185         } else
186                 return HandleEarlyAllocationRequest( size );
187 }
188
189 /** @brief Snapshotting free implementation for user programs */
190 void free( void * ptr ){
191         if (!DontFree(ptr))
192                 mspace_free(mySpace, ptr);
193 }
194
195 /** @brief Snapshotting realloc implementation for user programs */
196 void *realloc( void *ptr, size_t size )
197 {
198         void *tmp = mspace_realloc(mySpace, ptr, size);
199         ASSERT(tmp);
200         return tmp;
201 }
202
203 /** @brief Snapshotting calloc implementation for user programs */
204 void * calloc( size_t num, size_t size )
205 {
206         if (mySpace) {
207                 void *tmp = mspace_calloc(mySpace, num, size);
208                 ASSERT(tmp);
209                 return tmp;
210         } else {
211                 void *tmp=HandleEarlyAllocationRequest( size * num );
212                 std::memset( tmp, 0, size * num );
213                 return tmp;
214         }
215 }
216
217 /** @brief Snapshotting new operator for user programs */
218 void * operator new(size_t size) throw(std::bad_alloc)
219 {
220         return malloc(size);
221 }
222
223 /** @brief Snapshotting delete operator for user programs */
224 void operator delete(void *p) throw()
225 {
226         free(p);
227 }
228
229 /** @brief Snapshotting new[] operator for user programs */
230 void * operator new[](size_t size) throw(std::bad_alloc)
231 {
232         return malloc(size);
233 }
234
235 /** @brief Snapshotting delete[] operator for user programs */
236 void operator delete[](void *p, size_t size)
237 {
238         free(p);
239 }