00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <sys/mm.h>
00027
00028 #ifdef CONF_MM
00029
00030 #include <stdlib.h>
00031 #include <sys/tm.h>
00032 #include <sys/critsec.h>
00033 #include <string.h>
00034
00036
00037
00038
00040
00041 size_t *mm_first_free;
00042
00043 #ifndef CONF_TM
00044 typedef size_t tid_t;
00045
00047
00050 const tid_t ctid=0x0001;
00051 #endif
00052
00054
00055
00056
00058
00059
00060
00061
00062
00063
00064
00065
00067
00068
00069
00070 size_t mm_try_join(size_t *ptr) {
00071 size_t *next=ptr+*ptr+1;
00072 size_t increase=0;
00073
00074 while(*next==MM_FREE && next>=&mm_start) {
00075 increase+=*(next+1) + MM_HEADER_SIZE;
00076 next +=*(next+1) + MM_HEADER_SIZE;
00077 }
00078 return (*ptr)+=increase;
00079 }
00080
00082
00084 void mm_defrag() {
00085 size_t *ptr = &mm_start;
00086 #ifdef CONF_TM
00087 ENTER_KERNEL_CRITICAL_SECTION();
00088 #endif
00089 while(ptr >= &mm_start) {
00090 if(*ptr == MM_FREE)
00091 mm_try_join(ptr+1);
00092 ptr += *(ptr+1);
00093 ptr += MM_HEADER_SIZE;
00094 }
00095 #ifdef CONF_TM
00096 LEAVE_KERNEL_CRITICAL_SECTION();
00097 #endif
00098 }
00099
00101
00103 void mm_update_first_free(size_t *start) {
00104 size_t *ptr=start;
00105
00106 while((*ptr!=MM_FREE) && (ptr>=&mm_start))
00107 ptr+=*(ptr+1)+MM_HEADER_SIZE;
00108
00109 mm_first_free=ptr;
00110 }
00111
00112
00114
00116 void mm_init() {
00117 size_t *current,*next;
00118
00119 current=&mm_start;
00120
00121
00122
00123 MM_BLOCK_FREE (&mm_start);
00124
00125
00126
00127 MM_BLOCK_RESERVED(0xef30);
00128 MM_BLOCK_FREE (0xef50);
00129 MM_BLOCK_RESERVED(0xf000);
00130 MM_BLOCK_FREE (0xfe00);
00131 MM_BLOCK_RESERVED(0xff00);
00132
00133
00134 *current=(int)(((-(int) current)-2)>>1);
00135
00136 mm_update_first_free(&mm_start);
00137 }
00138
00139
00141
00144 void *malloc(size_t size) {
00145 size_t *ptr,*next;
00146
00147 size=(size+1)>>1;
00148
00149 #ifdef CONF_TM
00150 ENTER_KERNEL_CRITICAL_SECTION();
00151 #endif
00152 ptr=mm_first_free;
00153
00154 while(ptr>=&mm_start) {
00155 if(*(ptr++)==MM_FREE) {
00156 #ifdef CONF_TM
00157 mm_try_join(ptr);
00158 #endif
00159 if(*ptr>=size) {
00160 *(ptr-1)=(size_t)ctid;
00161
00162
00163 if((*ptr-size)>=MM_SPLIT_THRESH) {
00164 next=ptr+size+1;
00165 *(next++)=MM_FREE;
00166 *(next)=*ptr-size-MM_HEADER_SIZE;
00167 mm_try_join(next);
00168
00169 *ptr=size;
00170 }
00171
00172
00173 if(ptr==mm_first_free+1)
00174 mm_update_first_free(ptr+*ptr+1);
00175
00176 #ifdef CONF_TM
00177 LEAVE_KERNEL_CRITICAL_SECTION();
00178 #endif
00179 return (void*) (ptr+1);
00180 }
00181 }
00182
00183 ptr+=(*ptr)+1;
00184 }
00185
00186 #ifdef CONF_TM
00187 LEAVE_KERNEL_CRITICAL_SECTION();
00188 #endif
00189 return NULL;
00190 }
00191
00192
00194
00198 void free(void *the_ptr) {
00199 size_t *ptr=the_ptr;
00200 #ifndef CONF_TM
00201 size_t *p2,*next;
00202 #endif
00203
00204 if(ptr==NULL || (((size_t)ptr)&1) )
00205 return;
00206
00207 ptr-=MM_HEADER_SIZE;
00208 *((size_t*) ptr)=MM_FREE;
00209
00210 #ifdef CONF_TM
00211
00212
00213
00214
00215
00216
00217 if(ptr<mm_first_free || mm_first_free<&mm_start)
00218 mm_first_free=ptr;
00219 #else
00220
00221
00222
00223 p2=&mm_start;
00224 while(p2!=ptr) {
00225 next=p2+*(p2+1)+MM_HEADER_SIZE;
00226 if(*p2==MM_FREE && next==ptr)
00227 break;
00228 p2=next;
00229 }
00230 mm_try_join(p2+1);
00231
00232 if(ptr<mm_first_free || mm_first_free<&mm_start)
00233 mm_update_first_free(ptr);
00234 #endif
00235 }
00236
00237
00239
00243 void *calloc(size_t nmemb, size_t size) {
00244 void *ptr;
00245 size_t original_size = size;
00246
00247 if (nmemb == 0 || size == 0)
00248 return 0;
00249
00250 size*=nmemb;
00251
00252
00253 if (size/nmemb != original_size)
00254 return 0;
00255
00256 if((ptr=malloc(size))!=NULL)
00257 memset(ptr,0,size);
00258
00259 return ptr;
00260 }
00261
00263
00265 void mm_reaper() {
00266 size_t *ptr;
00267
00268
00269 ptr=&mm_start;
00270 while(ptr>=&mm_start) {
00271 if(*ptr==(size_t)ctid)
00272 *ptr=MM_FREE;
00273 ptr+=*(ptr+1)+MM_HEADER_SIZE;
00274 }
00275
00276
00277
00278 mm_defrag();
00279 }
00280
00282 int mm_free_mem(void) {
00283 int free = 0;
00284 size_t *ptr;
00285
00286 #ifdef CONF_TM
00287 ENTER_KERNEL_CRITICAL_SECTION();
00288 #endif
00289
00290
00291 for (ptr = mm_first_free;
00292 ptr >= &mm_start;
00293 ptr += *(ptr+1) + MM_HEADER_SIZE)
00294 free += *(ptr+1);
00295
00296 #ifdef CONF_TM
00297 LEAVE_KERNEL_CRITICAL_SECTION();
00298 #endif
00299 return free*2;
00300 }
00301
00302 #endif