Modifying pool allocators

Simple pool allocators allow an application to specify a location identifier when allocating memory. More sophisticated pool allocators also support pool-level operations such as freeing or printing an entire pool with one function call.

If you are using a simple pool allocator, you can defeat the pool allocator when the program is Purify'd in the same manner described for fixed-size allocators.

If you are using a sophisticated pool allocator, you can take advantage of Purify's pool support to implement the pool-level operations such as freeing a pool. Purify can handle each allocation request by calling malloc, and also labeling the returned block with the correct pool-id. Pool-level operations can then be performed later by mapping a function over all blocks with a given pool-id.

As with fixed-size allocators, you can use a run-time flag instead of a compile-time flag.

Purify's pool interface functions assume that pool-id is a 32-bit sized datum. For a complete list of functions for pool allocation, click

PoolId AllocatePool() {
    if (purify_is_running()) {
        static PoolId pool_counter = 0;
        /* return unique id, but allocate no mem */
        return pool_counter++;
        } else {
        ... original code for AllocatePool() ...
        }
}

char* AllocateFromPool(PoolId id, int size) {
    if (purify_is_running()) {
        char* ret = malloc(size);
        purify_set_pool_id(ret, id);
        return ret;
    } else {
      ... original code for AllocateFromPool ...
    }
}
    
void FreeToPool(char* mem) {
    if (purify_is_running()) {
        free(mem); /* this clears the pool id */
    } else {
      ... original code for FreeToPool ...
    }
}
    
void FreeEntirePool(PoolId id) {
    if (purify_is_running()) {
        /* call 'free' on each block in this pool */
        purify_map_pool(id, free);
    } else {
      ... original code for FreeEntirePool ...
    }
}
    
void PrintPool(PoolId id) {
    if (purify_is_running()) {
        /* PrintBlock operates on a single block */
        /* call PrintBlock on every block in this pool */
        purify_map_pool(id, PrintBlock);
    } else {
       ... original code for PrintPool ...
    }
}