예제 #1
0
파일: mem.c 프로젝트: kingdwd/amino
AA_API void aa_mem_region_pop( aa_mem_region_t *reg, void *ptr ) {
    uint8_t *ptr8 = (uint8_t*)ptr;
    if( aa_mem_region_pop_in_node( ptr8, reg->node ) ){
        // fast path, in the top node
        aa_mem_region_align( reg, ptr8 );
    } else {
        // ugly case, iterate through nodes
        ptrdiff_t n = reg->node->end - reg->node->d;
        struct aa_mem_region_node *p = aa_mem_region_node_free( reg->node );
        // free old nodes
        while( p && !aa_mem_region_pop_in_node(ptr8, p) ) {
            n += (p->end - p->d);
            p = aa_mem_region_node_free( p );
        }
        assert( !p || (ptr8 >= p->d && ptr8 <= p->end));
        // now realloc a replacement node
        // how much of the last chunk is now unused
        ptrdiff_t popsize = p ? (p->end  - ptr8) : 0;
        assert( ( !p || ptr8 > p->d ) ?
                // popped in middle of chunk, keep it
                (!p || popsize < p->end - p->d ) :
                // poppsed start of chunk, realloc it
                ( (ptr8 == p->d) &&
                  (popsize == p->end - p->d) ) );
        reg->node =
            aa_mem_region_node_alloc( (size_t)(n+popsize),
                                  (p && aa_mem_region_alignptr(p->d) == ptr8) ?
                                  aa_mem_region_node_free(p) : p );
        reg->head = aa_mem_region_alignptr(reg->node->d);
    }
}
예제 #2
0
파일: mem.c 프로젝트: kingdwd/amino
void aa_mem_region_release( aa_mem_region_t *region ) {
    if( region->node->next ) {
        // compress buffers
        struct aa_mem_region_node *p = region->node;
        size_t n = 0;
        while (p) { n+= (size_t)(p->end - p->d); p = aa_mem_region_node_free(p); }
        region->node = aa_mem_region_node_alloc( n, NULL);
    }
    region->head = region->node->d;
}
예제 #3
0
파일: mem.c 프로젝트: golems/amino
void aa_mem_region_destroy( aa_mem_region_t *region )
{
    struct aa_mem_region_node *p = region->node;
    while (p) { p = aa_mem_region_node_free(p); }
    if( region->free_on_destroy ) {
        free(region);
    } else {
        region->node = NULL;
    }
}
예제 #4
0
파일: mem.c 프로젝트: kingdwd/amino
static void aa_mem_region_grow( aa_mem_region_t *reg, size_t size ) {
    size_t nsize = AA_MAX(2*(size_t)(reg->node->end - reg->node->d),
                          size + AA_MEMREG_ALIGN);
    // this growth strategy creates worst-case O(n) memory waste
    reg->node =
        aa_mem_region_node_alloc( nsize,
                              /* free unused chunk */
                              (aa_mem_region_alignptr(reg->node->d) == reg->head) ?
                              aa_mem_region_node_free(reg->node) : reg->node );
    aa_mem_region_align(reg, reg->node->d);
    assert( aa_mem_region_freesize(reg) >= size );
    assert( ! ((uintptr_t)reg->head%16) );
}
예제 #5
0
파일: mem.c 프로젝트: kingdwd/amino
void aa_mem_region_destroy( aa_mem_region_t *region ) {
    struct aa_mem_region_node *p = region->node;
    while (p) { p = aa_mem_region_node_free(p); }
    region->node = NULL;
}