1libtalloc_context(3)                talloc                libtalloc_context(3)
2
3
4

NAME

6       libtalloc_context - Chapter 1: Talloc context
7

Talloc context

9       The talloc context is the most important part of this library and is
10       responsible for every single feature of this memory allocator. It is a
11       logical unit which represents a memory space managed by talloc.
12
13       From the programmer's point of view, the talloc context is completely
14       equivalent to a pointer that would be returned by the memory routines
15       from the C standard library. This means that every context that is
16       returned from the talloc library can be used directly in functions that
17       do not use talloc internally. For example we can do the following:
18
19       char *str1 = strdup('I am NOT a talloc context');
20       char *str2 = talloc_strdup(NULL, 'I AM a talloc context');
21
22       printf('%d0, strcmp(str1, str2) == 0);
23
24       free(str1);
25       talloc_free(str2); /* we can not use free() on str2 */
26
27       This is possible because the context is internally handled as a special
28       fixed-length structure called talloc chunk. Each chunk stores context
29       metadata followed by the memory space requested by the programmer. When
30       a talloc function returns a context (pointer), it will in fact return a
31       pointer to the user space portion of the talloc chunk. If we to
32       manipulate this context using talloc functions, the talloc library
33       transforms the user-space pointer back to the starting address of the
34       chunk. This is also the reason why we were unable to use free(str2) in
35       the previous example - because str2 does not point at the beginning of
36       the allocated block of memory. This is illustrated on the next image:
37
38       The type TALLOC_CTX is defined in talloc.h to identify a talloc context
39       in function parameters. However, this type is just an alias for void
40       and exists only for semantical reasons - thus we can differentiate
41       between void * (arbitrary data) and TALLOC_CTX * (talloc context).
42
43   Context meta data
44       Every talloc context carries several pieces of internal information
45       along with the allocated memory:
46
47       · name - which is used in reports of context hierarchy and to simulate
48         a dynamic type system,
49
50       · size of the requested memory in bytes - this can be used to determine
51         the number of elements in arrays,
52
53       · attached destructor - which is executed just before the memory block
54         is about to be freed,
55
56       · references to the context
57
58       · children and parent contexts - create the hierarchical view on the
59         memory.
60

Hierarchy of talloc context

62       Every talloc context contains information about its parent and
63       children. Talloc uses this information to create a hierarchical model
64       of memory or to be more precise, it creates an n-ary tree where each
65       node represents a single talloc context. The root node of the tree is
66       referred to as a top level context - a context without any parent.
67
68       This approach has several advantages:
69
70       · as a consequence of freeing a talloc context, all of its children
71         will be properly deallocated as well,
72
73       · the parent of a context can be changed at any time, which results in
74         moving the whole subtree under another node,
75
76       · it creates a more natural way of managing data structures.
77
78   Example
79       We have a structure that stores basic information about a user -
80       his/her name, identification number and groups he/she is a member of:
81
82       struct user {
83         uid_t uid;
84         char *username;
85         size_t num_groups;
86         char **groups;
87       };
88
89       We will allocate this structure using talloc. The result will be the
90       following context tree:
91
92       /* create new top level context */
93       struct user *user = talloc(NULL, struct user);
94
95       user->uid = 1000;
96       user->num_groups = N;
97
98       /* make user the parent of following contexts */
99       user->username = talloc_strdup(user, 'Test user');
100       user->groups = talloc_array(user, char*, user->num_groups);
101
102       for (i = 0; i < user->num_groups; i++) {
103         /* make user->groups the parent of following context */
104         user->groups[i] = talloc_asprintf(user->groups,
105                                           'Test group %d', i);
106       }
107
108       This way, we have gained a lot of additional capabilities, one of which
109       is very simple deallocation of the structure and all of its elements.
110
111       With the C standard library we need first to iterate over the array of
112       groups and free every element separately. Then we must deallocate the
113       array that stores them. Next we deallocate the username and as the last
114       step free the structure itself. But with talloc, the only operation we
115       need to execute is freeing the structure context. Its descendants will
116       be freed automatically.
117
118       talloc_free(user);
119

Always keep the hieararchy steady!

121       The talloc is a hierarchy memory allocator. The hierarchy nature is
122       what makes the programming more error proof. It makes the memory easier
123       to manage and to free. Therefore, the first thing we should have on our
124       mind is: always project our data structures into the talloc context
125       hierarchy.
126
127       That means if we have a structure, we should always use it as a parent
128       context for its elements. This way we will not encounter any troubles
129       when freeing this structure or when changing its parent. The same rule
130       applies for arrays.
131

Creating a talloc context

133       Here are the most important functions that create a new talloc context.
134
135   Type-safe functions
136       It allocates the size that is necessary for the given type and returns
137       a new, properly-casted pointer. This is the preferred way to create a
138       new context as we can rely on the compiler to detect type mismatches.
139
140       The name of the context is automatically set to the name of the data
141       type which is used to simulate a dynamic type system.
142
143       struct user *user = talloc(ctx, struct user);
144
145       /* initialize to default values */
146       user->uid = 0;
147       user->name = NULL;
148       user->num_groups = 0;
149       user->groups = NULL;
150
151       /* or we can achieve the same result with */
152       struct user *user_zero = talloc_zero(ctx, struct user);
153
154   Zero-length contexts
155       The zero-length context is basically a context without any special
156       semantical meaning. We can use it the same way as any other context.
157       The only difference is that it consists only of the meta data about the
158       context. Therefore, it is strictly of type TALLOC_CTX*. It is often
159       used in cases where we want to aggregate several data structures under
160       one parent (zero-length) context, such as a temporary context to
161       contain memory needed within a single function that is not interesting
162       to the caller. Allocating on a zero-length temporary context will make
163       clean-up of the function simpler.
164
165       TALLOC_CTX *tmp_ctx = NULL;
166       struct foo *foo = NULL;
167       struct bar *bar = NULL;
168
169       /* new zero-length top level context */
170       tmp_ctx = talloc_new(NULL);
171       if (tmp_ctx == NULL) {
172         return ENOMEM;
173       }
174
175       foo = talloc(tmp_ctx, struct foo);
176       bar = talloc(tmp_ctx, struct bar);
177
178       /* free everything at once */
179       talloc_free(tmp_ctx);
180
181   See also
182       · talloc_size()
183
184       · talloc_named()
185
186       · The talloc array functions
187
188       · The talloc string functions.
189
190Version 2.0                       12 Apr 2016             libtalloc_context(3)
Impressum