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