Changeset 49


Ignore:
Timestamp:
2006-05-30T04:05:58+02:00 (9 years ago)
Author:
moo
Message:

big diff yet small change: fix ran into outside of shared memory. and commit the test that figure it out.
valgrind rocks even for our code for shared memory.

Location:
trunk
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/mem.c

    r1 r49  
     1#ifdef TEST 
     2#include <limits.h> 
     3#include <stdio.h> 
     4#else 
    15#include <php.h> 
     6#endif 
     7 
     8#include <assert.h> 
    29#include <stdlib.h> 
     10#include <string.h> 
    311#include "mem.h" 
    412#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)) 
    628 
    729// {{{ mem 
    830struct _xc_block_t { 
    9 #ifdef ALLOC_DEBUG 
     31#ifdef ALLOC_DEBUG_BLOCK_CHECK 
    1032    unsigned int magic; 
    1133#endif 
     
    2042}; 
    2143 
    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 
    2549#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) )) 
    2751 
    2852#define BLOCK_MAGIC ((unsigned int) 0x87655678) 
     
    3155static inline void xc_block_setup(xc_block_t *b, xc_memsize_t size, xc_block_t *next) /* {{{ */ 
    3256{ 
    33 #ifdef ALLOC_DEBUG 
     57#ifdef ALLOC_DEBUG_BLOCK_CHECK 
    3458    b->magic = BLOCK_MAGIC; 
    3559#endif 
     
    3862} 
    3963/* }}} */ 
    40 #ifdef ALLOC_DEBUG 
     64#ifdef ALLOC_DEBUG_BLOCK_CHECK 
    4165static void xc_block_check(xc_block_t *b) /* {{{ */ 
    4266{ 
     
    6387    realsize = ALIGN(realsize); 
    6488 
     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 
    6596    do { 
    6697        p = NULL; 
    6798        if (mem->avail < realsize) { 
     99#ifdef ALLOC_DEBUG 
     100            fprintf(stderr, " oom\n"); 
     101#endif 
    68102            break; 
    69103        } 
     
    94128 
    95129        if (b == NULL) { 
     130#ifdef ALLOC_DEBUG 
     131            fprintf(stderr, " no fit chunk\n"); 
     132#endif 
    96133            break; 
    97134        } 
     
    105142        mem->avail -= realsize; 
    106143 
    107         /*perfect fit, just unlink */ 
     144        /* perfect fit, just unlink */ 
    108145        if (cur->size == realsize) { 
    109146            prev->next = cur->next; 
     147#ifdef ALLOC_DEBUG 
     148            fprintf(stderr, " perfect fit. Got: %p\n", p); 
     149#endif 
    110150            break; 
    111151        } 
     
    126166 
    127167#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 
    132170                , newb 
    133                 , ((char*)newb - mem->rw), ((char*)newb - mem->rw) / 1024 
     171                , PSUB(newb, mem), PSUB(newb, mem) / 1024 
     172                , p 
    134173                ); 
    135174#endif 
     
    149188    int size; 
    150189 
    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 
    152195    xc_block_check(cur); 
    153196    assert((char*)mem < (char*)cur && (char*)cur < (char*)mem + mem->size); 
     
    164207    size = cur->size; 
    165208 
     209#ifdef ALLOC_DEBUG 
     210    fprintf(stderr, ", avail %d (%dKB)", mem->avail, mem->avail / 1024); 
     211#endif 
    166212    mem->avail += size; 
    167213 
     
    171217        b->next = cur->next; 
    172218        cur = b; 
     219#ifdef ALLOC_DEBUG 
     220        fprintf(stderr, ", combine prev"); 
     221#endif 
    173222    } 
    174223 
     
    178227        cur->size += b->size; 
    179228        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 
    181236    return size; 
    182237} 
     
    246301xc_mem_t *xc_mem_init(void *ptr, xc_memsize_t size) /* {{{ */ 
    247302{ 
    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; 
    251313    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 */ 
    255317    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)))); 
    257319 
    258320    /* first block*/ 
    259321    b = b->next; 
    260322    xc_block_setup(b, mem->avail, 0); 
     323#undef MINSIZE 
    261324 
    262325    return mem; 
     
    267330} 
    268331/* }}} */ 
     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 
     339int 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 
  • trunk/xcache.c

    r39 r49  
    892892    xc_mem_t *mem; 
    893893    int i; 
    894  
    895     xc_memsize_t memsize = shmsize / hcache->size; 
     894    xc_memsize_t memsize; 
     895 
     896    memsize = shmsize / hcache->size; 
     897 
     898    /* Don't let it break out of mem after ALIGNed 
     899     * This is important for  
     900     * Simply loop until it fit our need 
     901     */ 
     902    while (ALIGN(memsize) * hcache->size > shmsize && ALIGN(memsize) != memsize) { 
     903        if (memsize < ALIGN(1)) { 
     904            CHECK(NULL, "cache too small"); 
     905        } 
     906        memsize --; 
     907    } 
    896908 
    897909    CHECK(caches = calloc(hcache->size, sizeof(xc_cache_t *)), "caches OOM"); 
    898910 
    899911    for (i = 0; i < hcache->size; i ++) { 
    900         mem = xc_mem_init(ptr, memsize); 
    901         ptr += ALIGN(memsize); 
     912        CHECK(mem            = xc_mem_init(ptr, memsize), "Failed init memory allocator"); 
     913        ptr += memsize; 
    902914        CHECK(cache          = xc_mem_calloc(mem, 1, sizeof(xc_cache_t)), "cache OOM"); 
    903915        CHECK(cache->entries = xc_mem_calloc(mem, hentry->size, sizeof(xc_entry_t*)), "entries OOM"); 
Note: See TracChangeset for help on using the changeset viewer.