Mercurial > dovecot > core-2.2
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 |
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 | 5 without having to worry much about memory management like freeing the |
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 | 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 | 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 | 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 | 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 | 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 | 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 | 74 warns if you try to place them in xxx*. See strfuncs.c for examples. |
75 | |
6932 | 76 t_malloc() calls never fail. If there's not enough memory left, |
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 | 85 /* Returns the number of bytes available in data stack without allocating |
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 | 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 | 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 | 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 | 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 |