annotate src/lib/data-stack.h @ 22664:fea53c2725c0

director: Fix director_max_parallel_moves/kicks type Should be uint, not time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 09 Nov 2017 12:24:16 +0200
parents 1bdfc555f6a3
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6410
e4eb71ae8e96 Changed .h ifdef/defines to use <NAME>_H format.
Timo Sirainen <tss@iki.fi>
parents: 5362
diff changeset
1 #ifndef DATA_STACK_H
e4eb71ae8e96 Changed .h ifdef/defines to use <NAME>_H format.
Timo Sirainen <tss@iki.fi>
parents: 5362
diff changeset
2 #define DATA_STACK_H
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 /* Data stack makes it very easy to implement functions returning dynamic data
6932
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
5 without having to worry much about memory management like freeing the
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
6 result or having large enough buffers for the result.
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 t_ prefix was chosen to describe functions allocating memory from data
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 stack. "t" meaning temporary.
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10
6932
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
11 Advantages over control stack and alloca():
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 - Functions can return a value allocated from data stack
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 - We can portably specify how much data we want to allocate at runtime
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 Advantages over malloc():
401
ec0b16ee7ef9 typofix
Timo Sirainen <tss@iki.fi>
parents: 399
diff changeset
16 - FAST, most of the time allocating memory means only updating a couple of
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 pointers and integers. Freeing the memory all at once also is a fast
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 operation.
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19 - No need to free() each allocation resulting in prettier code
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 - No memory leaks
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 - No memory fragmentation
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 Disadvantages:
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 - Allocating memory inside loops can accidentally allocate a lot of memory
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 if the loops are long and you forgot to place t_push() and t_pop() there.
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 - t_malloc()ed data could be accidentally stored into permanent location
6932
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
27 and accessed after it's already been freed. const'ing the return values
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 helps for most uses though (see the t_malloc() description).
7027
ae06eb5e2638 Removed DISABLE_DATA_STACK. Using it was probably broken anyway and it was
Timo Sirainen <tss@iki.fi>
parents: 6939
diff changeset
29 - Debugging invalid memory usage may be difficult using existing tools,
ae06eb5e2638 Removed DISABLE_DATA_STACK. Using it was probably broken anyway and it was
Timo Sirainen <tss@iki.fi>
parents: 6939
diff changeset
30 although compiling with DEBUG enabled helps finding simple buffer
ae06eb5e2638 Removed DISABLE_DATA_STACK. Using it was probably broken anyway and it was
Timo Sirainen <tss@iki.fi>
parents: 6939
diff changeset
31 overflows.
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 */
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33
536
37893ed97492 changed t_push() and t_pop() to return unsigned int. added global
Timo Sirainen <tss@iki.fi>
parents: 402
diff changeset
34 extern unsigned int data_stack_frame;
37893ed97492 changed t_push() and t_pop() to return unsigned int. added global
Timo Sirainen <tss@iki.fi>
parents: 402
diff changeset
35
17635
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
36 /* All t_..() allocations between t_push*() and t_pop() are freed after t_pop()
6932
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
37 is called. Returns the current stack frame number, which can be used
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 to detect missing t_pop() calls:
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39
17635
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
40 x = t_push(__func__); .. if (t_pop() != x) abort();
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
41
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
42 In DEBUG mode, t_push_named() makes a temporary allocation for the name,
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
43 but is safe to call in a loop as it performs the allocation within its own
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
44 frame. However, you should always prefer to use T_BEGIN { ... } T_END below.
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 */
17635
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
46 unsigned int t_push(const char *marker) ATTR_HOT;
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
47 unsigned int t_push_named(const char *format, ...) ATTR_HOT ATTR_FORMAT(1, 2);
9946
12089b6343bf Added ATTR_HOT and ATTR_COLD macros. Use them in a couple of places.
Timo Sirainen <tss@iki.fi>
parents: 7912
diff changeset
48 unsigned int t_pop(void) ATTR_HOT;
6939
c7b42fea5fcc Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents: 6932
diff changeset
49 /* Simplifies the if (t_pop() != x) check by comparing it internally and
c7b42fea5fcc Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents: 6932
diff changeset
50 panicking if it doesn't match. */
9946
12089b6343bf Added ATTR_HOT and ATTR_COLD macros. Use them in a couple of places.
Timo Sirainen <tss@iki.fi>
parents: 7912
diff changeset
51 void t_pop_check(unsigned int *id) ATTR_HOT;
6939
c7b42fea5fcc Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents: 6932
diff changeset
52
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7027
diff changeset
53 /* Usage: T_BEGIN { code } T_END */
17635
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
54 #ifndef DEBUG
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7027
diff changeset
55 #define T_BEGIN \
17635
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
56 STMT_START { unsigned int _data_stack_cur_id = t_push(NULL);
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
57 #elif defined (__GNUC__) && !defined (__STRICT_ANSI__)
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
58 #define T_BEGIN \
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
59 STMT_START { unsigned int _data_stack_cur_id = t_push(__FUNCTION__);
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
60 #else
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
61 #define T_CAT2(a,b) (a ":" #b)
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
62 #define T_BEGIN \
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
63 STMT_START { unsigned int _data_stack_cur_id = t_push(T_CAT2(__FILE__,__LINE__));
6ea0584e3861 lib: add identifying markers to data-stack frames
Phil Carmody <phil@dovecot.fi>
parents: 17502
diff changeset
64 #endif
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7027
diff changeset
65 #define T_END \
6939
c7b42fea5fcc Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents: 6932
diff changeset
66 t_pop_check(&_data_stack_cur_id); } STMT_END
c7b42fea5fcc Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents: 6932
diff changeset
67
6932
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
68 /* WARNING: Be careful when using these functions, it's too easy to
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 accidentally save the returned value somewhere permanently.
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70
6932
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
71 You probably should never use these functions directly, rather
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 create functions that return 'const xxx*' types and use t_malloc()
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 internally in them. This is a lot safer, since usually compiler
402
e90b95f6d962 s/t_try_grow/t_try_realloc/
Timo Sirainen <tss@iki.fi>
parents: 401
diff changeset
74 warns if you try to place them in xxx*. See strfuncs.c for examples.
e90b95f6d962 s/t_try_grow/t_try_realloc/
Timo Sirainen <tss@iki.fi>
parents: 401
diff changeset
75
6932
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
76 t_malloc() calls never fail. If there's not enough memory left,
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
77 i_panic() will be called. */
17502
6abf982c268d lib: Use __attribute__((returns_nonnull)) for the common memory/string functions.
Timo Sirainen <tss@iki.fi>
parents: 9946
diff changeset
78 void *t_malloc(size_t size) ATTR_MALLOC ATTR_RETURNS_NONNULL;
6abf982c268d lib: Use __attribute__((returns_nonnull)) for the common memory/string functions.
Timo Sirainen <tss@iki.fi>
parents: 9946
diff changeset
79 void *t_malloc0(size_t size) ATTR_MALLOC ATTR_RETURNS_NONNULL;
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81 /* Try growing allocated memory. Returns TRUE if successful. Works only
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82 for last allocated memory in current stack frame. */
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3232
diff changeset
83 bool t_try_realloc(void *mem, size_t size);
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84
3232
8508869ab276 Added t_get_bytes_available().
Timo Sirainen <tss@iki.fi>
parents: 536
diff changeset
85 /* Returns the number of bytes available in data stack without allocating
8508869ab276 Added t_get_bytes_available().
Timo Sirainen <tss@iki.fi>
parents: 536
diff changeset
86 more memory. */
7912
81806d402514 Added more consts, ATTR_CONSTs and ATTR_PUREs.
Timo Sirainen <tss@iki.fi>
parents: 7326
diff changeset
87 size_t t_get_bytes_available(void) ATTR_PURE;
3232
8508869ab276 Added t_get_bytes_available().
Timo Sirainen <tss@iki.fi>
parents: 536
diff changeset
88
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
89 #define t_new(type, count) \
21320
1bdfc555f6a3 lib: *_new(): Use the new MALLOC_MULTIPLY() macro to avoid overflows
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21318
diff changeset
90 ((type *) t_malloc0(MALLOC_MULTIPLY((unsigned int)sizeof(type), (count))) + \
1bdfc555f6a3 lib: *_new(): Use the new MALLOC_MULTIPLY() macro to avoid overflows
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21318
diff changeset
91 COMPILE_ERROR_IF_TRUE(sizeof(type) > UINT_MAX))
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92
6932
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
93 /* Returns pointer to a temporary buffer you can use. The buffer will be
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94 invalid as soon as next t_malloc() is called!
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
95
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
96 If you wish to grow the buffer, you must give the full wanted size
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97 in the size parameter. If return value doesn't point to the same value
6932
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
98 as last time, you need to memcpy() data from the old buffer to the
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99 new one (or do some other trickery). See t_buffer_reget(). */
17502
6abf982c268d lib: Use __attribute__((returns_nonnull)) for the common memory/string functions.
Timo Sirainen <tss@iki.fi>
parents: 9946
diff changeset
100 void *t_buffer_get(size_t size) ATTR_RETURNS_NONNULL;
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102 /* Grow the buffer, memcpy()ing the memory to new location if needed. */
17502
6abf982c268d lib: Use __attribute__((returns_nonnull)) for the common memory/string functions.
Timo Sirainen <tss@iki.fi>
parents: 9946
diff changeset
103 void *t_buffer_reget(void *buffer, size_t size) ATTR_RETURNS_NONNULL;
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104
6932
90b63ce0c6a5 Comment updates
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
105 /* Make the last t_buffer_get()ed buffer permanent. Note that size MUST be
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106 less or equal than the size you gave with last t_buffer_get() or the
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107 result will be undefined. */
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
108 void t_buffer_alloc(size_t size);
7326
5017c74367e3 Added t_buffer_alloc_last_full().
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
109 /* Allocate the last t_buffer_get()ed data entirely. */
5017c74367e3 Added t_buffer_alloc_last_full().
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
110 void t_buffer_alloc_last_full(void);
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111
5362
9e86dbe68663 Added data_stack_set_clean_after_pop()
Timo Sirainen <tss@iki.fi>
parents: 4720
diff changeset
112 /* If enabled, all the used memory is cleared after t_pop(). */
9e86dbe68663 Added data_stack_set_clean_after_pop()
Timo Sirainen <tss@iki.fi>
parents: 4720
diff changeset
113 void data_stack_set_clean_after_pop(bool enable);
9e86dbe68663 Added data_stack_set_clean_after_pop()
Timo Sirainen <tss@iki.fi>
parents: 4720
diff changeset
114
399
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115 void data_stack_init(void);
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116 void data_stack_deinit(void);
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117
383503837741 s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 #endif