1/** 2@page libtalloc_pools Chapter 5: Memory pools 3 4@section pools Memory pools 5 6Allocation of a new memory is an expensive operation and large programs can 7contain thousands of calls of malloc() for a single computation, where every 8call allocates only a very small amount of the memory. This can result in an 9undesirable slowdown of the application. We can avoid this slowdown by 10decreasing the number of malloc() calls by using a memory pool. 11 12A memory pool is a preallocated memory space with a fixed size. If we need to 13allocate new data we will take the desired amount of the memory from the pool 14instead of requesting a new memory from the system. This is done by creating a 15pointer that points inside the preallocated memory. Such a pool must not be 16reallocated as it would change its location - pointers that were pointing 17inside the pool would become invalid. Therefore, a memory pool requires a very 18good estimate of the required memory space. 19 20The talloc library contains its own implementation of a memory pool. It is 21highly transparent for the programmer. The only thing that needs to be done is 22an initialization of a new pool context using talloc_pool() - 23which can be used in the same way as any other context. 24 25Refactoring of existing code (that uses talloc) to take the advantage of a 26memory pool is quite simple due to the following properties of the pool context: 27 28- if we are allocating data on a pool context, it takes the desired 29 amount of memory from the pool, 30- if the context is a descendant of the pool context, it takes the space 31 from the pool as well, 32- if the pool does not have sufficient portion of memory left, it will 33 create a new non-pool context, leaving the pool intact 34 35@code 36/* allocate 1KiB in a pool */ 37TALLOC_CTX *pool_ctx = talloc_pool(NULL, 1024); 38 39/* Take 512B from the pool, 512B is left there */ 40void *ptr = talloc_size(pool_ctx, 512); 41 42/* 1024B > 512B, this will create new talloc chunk outside 43 the pool */ 44void *ptr2 = talloc_size(ptr, 1024); 45 46/* The pool still contains 512 free bytes 47 * this will take 200B from them. */ 48void *ptr3 = talloc_size(ptr, 200); 49 50/* This will destroy context 'ptr3' but the memory 51 * is not freed, the available space in the pool 52 * will increase to 512B. */ 53talloc_free(ptr3); 54 55/* This will free memory taken by 'pool_ctx' 56 * and 'ptr2' as well. */ 57talloc_free(pool_ctx); 58@endcode 59 60The above given is very convenient, but there is one big issue to be kept in 61mind. If the parent of a talloc pool child is changed to a parent that is 62outside of this pool, the whole pool memory will not be freed until the child is 63freed. For this reason we must be very careful when stealing a descendant of a 64pool context. 65 66@code 67TALLOC_CTX *mem_ctx = talloc_new(NULL); 68TALLOC_CTX *pool_ctx = talloc_pool(NULL, 1024); 69struct foo *foo = talloc(pool_ctx, struct foo); 70 71/* mem_ctx is not in the pool */ 72talloc_steal(mem_ctx, foo); 73 74/* pool_ctx is marked as freed but the memory is not 75 deallocated, accessing the pool_ctx again will cause 76 an error */ 77talloc_free(pool_ctx); 78 79/* This deallocates the pool_ctx. */ 80talloc_free(mem_ctx); 81@endcode 82 83It may often be better to copy the memory we want instead of stealing it to 84avoid this problem. If we do not need to retain the context name (to keep the 85type information), we can use talloc_memdup() to do this. 86 87Copying the memory out of the pool may, however, discard all the performance 88boost given by the pool, depending on the size of the copied memory. Therefore, 89the code should be well profiled before taking this path. In general, the 90golden rule is: if we need to steal from the pool context, we should not 91use a pool context. 92 93*/ 94