subramanian lied when he said he fixed these...
[c11tester.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 #define REQUESTS_BEFORE_ALLOC 1024
9 size_t allocatedReqs[ REQUESTS_BEFORE_ALLOC ] = { 0 };
10 int nextRequest = 0;
11 int howManyFreed = 0;
12 #if !USE_MPROTECT_SNAPSHOT
13 static mspace sStaticSpace = NULL;
14 #endif
15
16 //SUBRAMANIAN!!! PLEASE FIX THE MALLOC/FREE/CALLOC/ETC FOR FORK-BASED APPROACH
17 //YOU HAVE NOT DONE THIS!!!!!!!!!!!
18
19 /** Non-snapshotting malloc for our use. */
20
21 void *MYMALLOC(size_t size) {
22 #if USE_MPROTECT_SNAPSHOT
23         static void *(*mallocp)(size_t size);
24         char *error;
25         void *ptr;
26   
27         /* get address of libc malloc */
28         if (!mallocp) {
29                 mallocp = ( void * ( * )( size_t ) )dlsym(RTLD_NEXT, "malloc");
30                 if ((error = dlerror()) != NULL) {
31                         fputs(error, stderr);
32                         exit(EXIT_FAILURE);
33                 }
34         }
35         ptr = mallocp(size);     
36         return ptr;
37 #else
38         if( !sTheRecord ){
39                 createSharedLibrary();
40         }
41         if( NULL == sStaticSpace )
42                 sStaticSpace = create_mspace_with_base( ( void * )( sTheRecord->mSharedMemoryBase ), SHARED_MEMORY_DEFAULT -sizeof( struct Snapshot ), 1 );
43         return mspace_malloc( sStaticSpace, size );
44 #endif
45 }
46
47 void *system_malloc( size_t size ){
48         static void *(*mallocp)(size_t size);
49         char *error;
50         void *ptr;
51
52         /* get address of libc malloc */
53         if (!mallocp) {
54                 mallocp = ( void * ( * )( size_t ) )dlsym(RTLD_NEXT, "malloc");
55                 if ((error = dlerror()) != NULL) {
56                         fputs(error, stderr);
57                         exit(EXIT_FAILURE);
58                 }
59         }
60         ptr = mallocp(size);
61         return ptr;
62 }
63
64 void system_free( void * ptr ){
65         static void (*freep)(void *);
66         char *error;
67
68         /* get address of libc free */
69         if (!freep) {
70                 freep = ( void  ( * )( void * ) )dlsym(RTLD_NEXT, "free");
71                 if ((error = dlerror()) != NULL) {
72                         fputs(error, stderr);
73                         exit(EXIT_FAILURE);
74                 }
75         }
76         freep(ptr);
77 }
78
79 /** Non-snapshotting free for our use. */
80 void MYFREE(void *ptr) {
81 #if USE_MPROTECT_SNAPSHOT
82         static void (*freep)(void *);
83         char *error;
84
85         /* get address of libc free */
86         if (!freep) {
87                 freep = ( void  ( * )( void * ) )dlsym(RTLD_NEXT, "free");
88                 if ((error = dlerror()) != NULL) {
89                         fputs(error, stderr);
90                         exit(EXIT_FAILURE);
91                 }
92         }
93         freep(ptr);
94 #else
95         mspace_free( sStaticSpace, ptr );
96 #endif
97 }
98
99
100 /** This global references the mspace for the snapshotting heap */
101 mspace mySpace = NULL;
102
103 /** This global references the unaligned memory address that was malloced for the snapshotting heap */
104 void * basemySpace = NULL;
105
106 /** Adding the fix for not able to allocate through a reimplemented calloc at the beginning before instantiating our allocator
107 A bit circumspect about adding an sbrk. linux docs say to avoid using it... */
108
109 void * HandleEarlyAllocationRequest( size_t sz ){
110         if( 0 == mySpace ){
111                 void * returnAddress = sbrk( sz );
112                 if( nextRequest >= REQUESTS_BEFORE_ALLOC ){
113                         exit( EXIT_FAILURE );
114                 }
115                 allocatedReqs[ nextRequest++ ] = ( size_t )returnAddress;
116                 return returnAddress;
117         }
118         return NULL;
119 }
120
121 /** The fact that I am not expecting more than a handful requests is implicit in my not using a binary search here*/
122
123 bool DontFree( void * ptr ){
124         if( howManyFreed == nextRequest ) return false; //a minor optimization to reduce the number of instructions executed on each free call....
125         if( NULL == ptr ) return true;
126         for( int i =  nextRequest - 1; i >= 0; --i ){
127                 if( allocatedReqs[ i ] ==  ( size_t )ptr ) {
128                         ++howManyFreed;
129                         return true;
130                 }
131         }
132         return false;
133 }
134
135 /** Snapshotting malloc implementation for user programs. */
136
137 void *malloc( size_t size ) {
138         void * earlyReq = HandleEarlyAllocationRequest( size );
139         if( earlyReq ) return earlyReq;
140         return mspace_malloc( mySpace, size );
141 }
142
143 /** Snapshotting free implementation for user programs. */
144
145 void free( void * ptr ){
146         if( DontFree( ptr ) ) return;
147         mspace_free( mySpace, ptr );
148 }
149
150 /** Snapshotting realloc implementation for user programs. */
151
152 void *realloc( void *ptr, size_t size ){
153         return mspace_realloc( mySpace, ptr, size );
154 }
155
156 /** Snapshotting calloc implementation for user programs. */
157
158 void * calloc( size_t num, size_t size ){
159         void * earlyReq = HandleEarlyAllocationRequest( size * num );
160         if( earlyReq ) {
161                 std::memset( earlyReq, 0, size * num );
162                 return earlyReq;
163         }
164         return mspace_calloc( mySpace, num, size );
165 }
166
167 /** Snapshotting new operator for user programs. */
168
169 void * operator new(size_t size) throw(std::bad_alloc) {
170         return malloc(size);
171 }
172
173 /** Snapshotting delete operator for user programs. */
174
175 void operator delete(void *p) throw() {
176         free(p);
177 }
178
179 /** Snapshotting new[] operator for user programs. */
180
181 void * operator new[](size_t size) throw(std::bad_alloc) {
182         return malloc(size);
183 }
184
185 /** Snapshotting delete[] operator for user programs. */
186
187 void operator delete[](void *p, size_t size) {
188         free(p);
189 }