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