Changeset 49 in svn for trunk/mem.c


Ignore:
Timestamp:
2006-05-30T02:05:58Z (9 years ago)
Author:
Xuefer
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.

File:
1 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
Note: See TracChangeset for help on using the changeset viewer.