Changeset 49 for trunk/mem.c
- Timestamp:
- 05/30/2006 02:05:58 AM (2 years ago)
- Files:
-
- 1 modified
-
trunk/mem.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/mem.c
r1 r49 1 #ifdef TEST 2 #include <limits.h> 3 #include <stdio.h> 4 #else 1 5 #include <php.h> 6 #endif 7 8 #include <assert.h> 2 9 #include <stdlib.h> 10 #include <string.h> 3 11 #include "mem.h" 4 12 #include "align.h" 5 #define PADD(p, a) (((char*)p) + a) 13 14 #ifdef TEST 15 # define ALLOC_DEBUG 16 #endif 17 #ifdef ALLOC_DEBUG 18 # define ALLOC_DEBUG_BLOCK_CHECK 19 #endif 20 21 #if 0 22 #undef ALLOC_DEBUG_BLOCK_CHECK 23 #endif 24 25 #define CHAR_PTR(p) ((char *) (p)) 26 #define PADD(p, a) (CHAR_PTR(p) + a) 27 #define PSUB(p1, p2) (CHAR_PTR(p1) - CHAR_PTR(p2)) 6 28 7 29 // {{{ mem 8 30 struct _xc_block_t { 9 #ifdef ALLOC_DEBUG 31 #ifdef ALLOC_DEBUG_BLOCK_CHECK 10 32 unsigned int magic; 11 33 #endif … … 20 42 }; 21 43 22 #ifndef offsetof 23 # define offsetof(type, field) ((int) ((char *) &((type *) 0)->field)) 24 #endif 44 #ifndef XtOffsetOf 45 # include <linux/stddef.h> 46 # define XtOffsetOf(s_type, field) offsetof(s_type, field) 47 #endif 48 25 49 #define SizeOf(type, field) sizeof( ((type *) 0)->field ) 26 #define BLOCK_HEADER_SIZE() (ALIGN( offsetof(xc_block_t, size) + SizeOf(xc_block_t, size) ))50 #define BLOCK_HEADER_SIZE() (ALIGN( XtOffsetOf(xc_block_t, size) + SizeOf(xc_block_t, size) )) 27 51 28 52 #define BLOCK_MAGIC ((unsigned int) 0x87655678) … … 31 55 static inline void xc_block_setup(xc_block_t *b, xc_memsize_t size, xc_block_t *next) /* {{{ */ 32 56 { 33 #ifdef ALLOC_DEBUG 57 #ifdef ALLOC_DEBUG_BLOCK_CHECK 34 58 b->magic = BLOCK_MAGIC; 35 59 #endif … … 38 62 } 39 63 /* }}} */ 40 #ifdef ALLOC_DEBUG 64 #ifdef ALLOC_DEBUG_BLOCK_CHECK 41 65 static void xc_block_check(xc_block_t *b) /* {{{ */ 42 66 { … … 63 87 realsize = ALIGN(realsize); 64 88 89 #ifdef ALLOC_DEBUG 90 fprintf(stderr, "avail: %d (%dKB). Allocate size: %d realsize: %d (%dKB)" 91 , mem->avail, mem->avail / 1024 92 , size 93 , realsize, realsize / 1024 94 ); 95 #endif 65 96 do { 66 97 p = NULL; 67 98 if (mem->avail < realsize) { 99 #ifdef ALLOC_DEBUG 100 fprintf(stderr, " oom\n"); 101 #endif 68 102 break; 69 103 } … … 94 128 95 129 if (b == NULL) { 130 #ifdef ALLOC_DEBUG 131 fprintf(stderr, " no fit chunk\n"); 132 #endif 96 133 break; 97 134 } … … 105 142 mem->avail -= realsize; 106 143 107 /* perfect fit, just unlink */144 /* perfect fit, just unlink */ 108 145 if (cur->size == realsize) { 109 146 prev->next = cur->next; 147 #ifdef ALLOC_DEBUG 148 fprintf(stderr, " perfect fit. Got: %p\n", p); 149 #endif 110 150 break; 111 151 } … … 126 166 127 167 #ifdef ALLOC_DEBUG 128 fprintf(stderr, "avail: %d (%dKB). size: %d %d (%dKB) new next: %p offset: %d %dKB\n" 129 , mem->avail, mem->avail/1024 130 , size 131 , realsize, realsize/1024 168 fprintf(stderr, " -> avail: %d (%dKB). new next: %p offset: %d %dKB. Got: %p\n" 169 , mem->avail, mem->avail / 1024 132 170 , newb 133 , ((char*)newb - mem->rw), ((char*)newb - mem->rw) / 1024 171 , PSUB(newb, mem), PSUB(newb, mem) / 1024 172 , p 134 173 ); 135 174 #endif … … 149 188 int size; 150 189 151 cur = (xc_block_t *) (((char *) p) - BLOCK_HEADER_SIZE()); 190 cur = (xc_block_t *) (CHAR_PTR(p) - BLOCK_HEADER_SIZE()); 191 #ifdef ALLOC_DEBUG 192 fprintf(stderr, "freeing: %p", p); 193 fprintf(stderr, ", size=%d", cur->size); 194 #endif 152 195 xc_block_check(cur); 153 196 assert((char*)mem < (char*)cur && (char*)cur < (char*)mem + mem->size); … … 164 207 size = cur->size; 165 208 209 #ifdef ALLOC_DEBUG 210 fprintf(stderr, ", avail %d (%dKB)", mem->avail, mem->avail / 1024); 211 #endif 166 212 mem->avail += size; 167 213 … … 171 217 b->next = cur->next; 172 218 cur = b; 219 #ifdef ALLOC_DEBUG 220 fprintf(stderr, ", combine prev"); 221 #endif 173 222 } 174 223 … … 178 227 cur->size += b->size; 179 228 cur->next = b->next; 180 } 229 #ifdef ALLOC_DEBUG 230 fprintf(stderr, ", combine next"); 231 #endif 232 } 233 #ifdef ALLOC_DEBUG 234 fprintf(stderr, " -> avail %d (%dKB)\n", mem->avail, mem->avail / 1024); 235 #endif 181 236 return size; 182 237 } … … 246 301 xc_mem_t *xc_mem_init(void *ptr, xc_memsize_t size) /* {{{ */ 247 302 { 248 xc_mem_t *mem = (xc_mem_t *) ptr; 249 xc_block_t *b; 250 303 xc_mem_t *mem; 304 xc_block_t *b; 305 306 #define MINSIZE (ALIGN(sizeof(xc_mem_t)) + sizeof(xc_block_t)) 307 /* requires at least the header and 1 tail block */ 308 if (size < MINSIZE) { 309 fprintf(stderr, "xc_mem_init requires %d bytes at least\n", MINSIZE); 310 return NULL; 311 } 312 mem = (xc_mem_t *) ptr; 251 313 mem->size = size; 252 mem->avail = size - ALIGN(sizeof(xc_mem_t));253 254 /* pointer to first block */314 mem->avail = size - MINSIZE; 315 316 /* pointer to first block, right after ALIGNed header */ 255 317 b = mem->headblock; 256 xc_block_setup(b, 0, (xc_block_t *) (mem +ALIGN(sizeof(xc_mem_t))));318 xc_block_setup(b, 0, (xc_block_t *) PADD(mem, ALIGN(sizeof(xc_mem_t)))); 257 319 258 320 /* first block*/ 259 321 b = b->next; 260 322 xc_block_setup(b, mem->avail, 0); 323 #undef MINSIZE 261 324 262 325 return mem; … … 267 330 } 268 331 /* }}} */ 332 333 #ifdef TEST 334 /* {{{ */ 335 #undef CHECK 336 #define CHECK(a, msg) do { if ((a) == NULL) { puts(msg); return -1; } } while (0) 337 #include <time.h> 338 339 int main() 340 { 341 int count = 0; 342 void *p; 343 void *memory; 344 xc_mem_t *mem; 345 void **ptrs; 346 int size, i; 347 348 #if 0 349 fprintf(stderr, "%s", "Input test size: "); 350 scanf("%d", &size); 351 #else 352 size = 100; 353 #endif 354 CHECK(memory = malloc(size), "OOM"); 355 CHECK(ptrs = malloc(size * sizeof(void*)), "OOM"); 356 CHECK(mem = xc_mem_init(memory, size), "Failed init memory allocator"); 357 358 while ((p = xc_mem_malloc(mem, 1))) { 359 ptrs[count ++] = p; 360 } 361 fprintf(stderr, "count=%d, random freeing\n", count); 362 srandom(time(NULL)); 363 while (count) { 364 i = (random() % count); 365 fprintf(stderr, "freeing %d: ", i); 366 xc_mem_free(mem, ptrs[i]); 367 ptrs[i] = ptrs[count - 1]; 368 count --; 369 } 370 371 free(memory); 372 return 0; 373 } 374 /* }}} */ 375 #endif

