Bump S-nail v14.9.25.ar ("Lubimy Gorod"), 2024-06-27
[s-mailx.git] / include / su / mem.h
blob04257679604cda9819dbf20f4fb8479890520a33
1 /*@ Memory: tools like copy, move etc., and a heap allocation interface.
3 * Copyright (c) 2001 - 2020 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
4 * SPDX-License-Identifier: ISC
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #ifndef su_MEM_H
19 #define su_MEM_H
20 #include <su/code.h>
21 #define su_HEADER
22 #include <su/code-in.h>
23 C_DECL_BEGIN
24 /* A memset that is not optimized away */
25 EXPORT_DATA void * (* volatile su_mem_set_volatile)(void*, int, uz);
26 EXPORT sz su_mem_cmp(void const *vpa, void const *vpb, uz len);
27 EXPORT void *su_mem_copy(void *vp, void const *src, uz len);
28 EXPORT void *su_mem_find(void const *vp, s32 what, uz len);
29 EXPORT void *su_mem_rfind(void const *vp, s32 what, uz len);
30 EXPORT void *su_mem_move(void *vp, void const *src, uz len);
31 EXPORT void *su_mem_set(void *vp, s32 what, uz len);
32 #if (defined su_HAVE_DEBUG && !defined su_HAVE_MEM_CANARIES_DISABLE) ||\
33 defined DOXYGEN
34 # define su_MEM_ALLOC_DEBUG
35 #endif
36 enum su_mem_alloc_flags{
37 su_MEM_ALLOC_NONE,
38 su_MEM_ALLOC_CLEAR = 1u<<1,
39 su_MEM_ALLOC_32BIT_OVERFLOW = 1u<<2,
40 su_MEM_ALLOC_31BIT_OVERFLOW = 1u<<3,
41 su_MEM_ALLOC_OVERFLOW_OK = su_STATE_ERR_OVERFLOW,
42 su_MEM_ALLOC_NOMEM_OK = su_STATE_ERR_NOMEM,
43 su_MEM_ALLOC_MAYFAIL = su_STATE_ERR_PASS,
44 su_MEM_ALLOC_MUSTFAIL = su_STATE_ERR_NOPASS,
45 su__MEM_ALLOC_MARK_SHIFT = 16u,
46 su_MEM_ALLOC_MARK_0 = 0u<<su__MEM_ALLOC_MARK_SHIFT,
47 su_MEM_ALLOC_MARK_1 = 1u<<su__MEM_ALLOC_MARK_SHIFT,
48 su_MEM_ALLOC_MARK_2 = 2u<<su__MEM_ALLOC_MARK_SHIFT,
49 su_MEM_ALLOC_MARK_3 = 3u<<su__MEM_ALLOC_MARK_SHIFT,
50 su_MEM_ALLOC_MARK_AUTO = su_MEM_ALLOC_MARK_1,
51 su_MEM_ALLOC_MARK_AUTO_HUGE = su_MEM_ALLOC_MARK_2,
52 su_MEM_ALLOC_MARK_LOFI = su_MEM_ALLOC_MARK_3,
53 su__MEM_ALLOC_MARK_MAX = 3u,
54 su__MEM_ALLOC_MARK_MASK = 3u,
55 su__MEM_ALLOC_USER_MASK = 0xFF | su_STATE_ERR_MASK |
56 (su__MEM_ALLOC_MARK_MASK << su__MEM_ALLOC_MARK_SHIFT)
58 #ifdef su_SOURCE_MEM_ALLOC
59 CTA((su_STATE_ERR_MASK & ~0xFF00u) == 0,
60 "Reuse of low order bits impossible, or mask excesses storage");
61 #endif
62 enum{
63 su_MEM_ALLOC_MIN = Z_ALIGN(1)
65 enum su_mem_conf_option{
66 su_MEM_CONF_NONE,
67 /* su_MEM_ALLOC_DEBUG only: booleans */
68 su_MEM_CONF_DEBUG = 1u<<0,
69 su_MEM_CONF_ON_ERROR_EMERG = 1u<<1,
70 su_MEM_CONF_LINGER_FREE = 1u<<2,
71 su_MEM_CONF_LINGER_FREE_RELEASE = 1u<<3,
72 /*madvise,free area count*/
73 /*say_if_empty_on_exit,statistics*/
74 su__MEM_CONF_MAX = su_MEM_CONF_LINGER_FREE_RELEASE
76 #ifdef su_MEM_ALLOC_DEBUG
77 EXPORT boole su__mem_get_can_book(uz size, uz no);
78 EXPORT boole su__mem_check(su_DBG_LOC_ARGS_DECL_SOLE);
79 EXPORT boole su__mem_trace(su_DBG_LOC_ARGS_DECL_SOLE);
80 #endif
81 EXPORT void *su_mem_allocate(uz size, uz no, u32 maf su_DBG_LOC_ARGS_DECL);
82 EXPORT void *su_mem_reallocate(void *ovp, uz size, uz no, u32 maf
83 su_DBG_LOC_ARGS_DECL);
84 EXPORT void su_mem_free(void *ovp su_DBG_LOC_ARGS_DECL);
85 #define su_MEM_ALLOCATE(SZ,NO,F) \
86 su_mem_allocate(SZ, NO, F su_DBG_LOC_ARGS_INJ)
87 #define su_MEM_REALLOCATE(OVP,SZ,NO,F) \
88 su_mem_reallocate(OVP, SZ, NO, F su_DBG_LOC_ARGS_INJ)
89 #ifdef su_HAVE_DBG_LOC_ARGS
90 # define su_MEM_ALLOCATE_LOC(SZ,NO,F,FNAME,LNNO) \
91 su_mem_allocate(SZ, NO, F, FNAME, LNNO)
92 # define su_MEM_REALLOCATE_LOC(OVP,SZ,NO,F,FNAME,LNNO) \
93 su_mem_reallocate(OVP, SZ, NO, F, FNAME, LNNO)
94 #else
95 # define su_MEM_ALLOCATE_LOC(SZ,NO,F,FNAME,LNNO) \
96 su_mem_allocate(SZ, NO, F)
97 # define su_MEM_REALLOCATE_LOC(OVP,SZ,NO,F,FNAME,LNNO) \
98 su_mem_reallocate(OVP, SZ, NO, F)
99 #endif
100 /* The "normal" interface; there X, X_LOC, and X_LOCOR */
101 #define su_MEM_ALLOC(SZ) su_MEM_ALLOCATE(SZ, 1, su_MEM_ALLOC_NONE)
102 #define su_MEM_ALLOC_LOC(SZ,FNAME,LNNO) \
103 su_MEM_ALLOCATE_LOC(SZ, 1, su_MEM_ALLOC_NONE, FNAME, LNNO)
104 #define su_MEM_ALLOC_N(SZ,NO) su_MEM_ALLOCATE(SZ, NO, su_MEM_ALLOC_NONE)
105 #define su_MEM_ALLOC_N_LOC(SZ,NO,FNAME,LNNO) \
106 su_MEM_ALLOCATE_LOC(SZ, NO, su_MEM_ALLOC_NONE, FNAME, LNNO)
107 #define su_MEM_CALLOC(SZ) su_MEM_ALLOCATE(SZ, 1, su_MEM_ALLOC_CLEAR)
108 #define su_MEM_CALLOC_LOC(SZ,FNAME,LNNO) \
109 su_MEM_ALLOCATE_LOC(SZ, 1, su_MEM_ALLOC_CLEAR, FNAME, LNNO)
110 #define su_MEM_CALLOC_N(SZ,NO) su_MEM_ALLOCATE(SZ, NO, su_MEM_ALLOC_CLEAR)
111 #define su_MEM_CALLOC_N_LOC(SZ,NO,FNAME,LNNO) \
112 su_MEM_ALLOCATE_LOC(SZ, NO, su_MEM_ALLOC_CLEAR, FNAME, LNNO)
113 #define su_MEM_REALLOC(OVP,SZ) su_MEM_REALLOCATE(OVP, SZ, 1, su_MEM_ALLOC_NONE)
114 #define su_MEM_REALLOC_LOC(OVP,SZ,FNAME,LNNO) \
115 su_MEM_REALLOCATE_LOC(OVP, SZ, 1, su_MEM_ALLOC_NONE, FNAME, LNNO)
116 #define su_MEM_REALLOC_N(OVP,SZ,NO) \
117 su_MEM_REALLOCATE(OVP, SZ, NO, su_MEM_ALLOC_NONE)
118 #define su_MEM_REALLOC_N_LOC(OVP,SZ,NO,FNAME,LNNO) \
119 su_MEM_REALLOCATE_LOC(OVP, SZ, NO, su_MEM_ALLOC_NONE, FNAME, LNNO)
120 #define su_MEM_TALLOC(T,NO) su_S(T *,su_MEM_ALLOC_N(sizeof(T), NO))
121 #define su_MEM_TALLOC_LOC(T,NO,FNAME,LNNO) \
122 su_S(T *,su_MEM_ALLOC_N_LOC(sizeof(T), NO, FNAME, LNNO))
123 #define su_MEM_TCALLOC(T,NO) su_S(T *,su_MEM_CALLOC_N(sizeof(T), NO))
124 #define su_MEM_TCALLOC_LOC(T,NO,FNAME,LNNO) \
125 su_S(T *,su_MEM_CALLOC_N_LOC(sizeof(T), NO, FNAME, LNNO))
126 #define su_MEM_TREALLOC(T,OVP,NO) \
127 su_S(T *,su_MEM_REALLOC_N(OVP, sizeof(T), NO))
128 #define su_MEM_TREALLOC_LOC(T,OVP,NO,FNAME,LNNO) \
129 su_S(T *,su_MEM_REALLOC_N_LOC(OVP, sizeof(T), NO, FNAME, LNNO))
130 #define su_MEM_TALLOCF(T,NO,F) su_S(T *,su_MEM_ALLOCATE(sizeof(T), NO, F))
131 #define su_MEM_TALLOCF_LOC(T,NO,F,FNAME,LNNO) \
132 su_S(T *,su_MEM_ALLOCATE_LOC(sizeof(T), NO, F, FNAME, LNNO))
133 #define su_MEM_TCALLOCF(T,NO,F) \
134 su_S(T *,su_MEM_ALLOCATE(sizeof(T), NO, su_MEM_ALLOC_CLEAR | (F)))
135 #define su_MEM_TCALLOCF_LOC(T,NO,F,FNAME,LNNO) \
136 su_S(T *,su_MEM_ALLOCATE_LOC(sizeof(T), NO, su_MEM_ALLOC_CLEAR | (F)),\
137 FNAME, LNNO)
138 #define su_MEM_TREALLOCF(T,OVP,NO,F) \
139 su_S(T *,su_MEM_REALLOCATE(OVP, sizeof(T), NO, F))
140 #define su_MEM_TREALLOCF_LOC(T,OVP,NO,F,FNAME,LNNO) \
141 su_S(T *,su_MEM_REALLOCATE_LOC(OVP, sizeof(T), NO, F, FNAME, LNNO))
142 #define su_MEM_FREE(OVP) su_mem_free(OVP su_DBG_LOC_ARGS_INJ)
143 #ifdef su_HAVE_DBG_LOC_ARGS
144 # define su_MEM_FREE_LOC(OVP,FNAME,LNNO) su_mem_free(OVP, FNAME, LNNO)
145 #else
146 # define su_MEM_FREE_LOC(OVP,FNAME,LNNO) su_mem_free(OVP)
147 #endif
148 /* (The painful _LOCOR series) */
149 #ifdef su_HAVE_DBG_LOC_ARGS
150 # define su_MEM_ALLOC_LOCOR(SZ,ORARGS) su_MEM_ALLOC_LOC(SZ, ORARGS)
151 # define su_MEM_ALLOC_N_LOCOR(SZ,NO,ORARGS) su_MEM_ALLOC_N_LOC(SZ, NO, ORARGS)
152 # define su_MEM_CALLOC_LOCOR(SZ,ORARGS) su_MEM_CALLOC_LOC(SZ, ORGARGS)
153 # define su_MEM_CALLOC_N_LOCOR(SZ,NO,ORARGS) \
154 su_MEM_CALLOC_N_LOC(SZ, NO, ORARGS)
155 # define su_MEM_REALLOC_LOCOR(OVP,SZ,ORARGS) \
156 su_MEM_REALLOC_LOC(OVP, SZ, ORARGS)
157 # define su_MEM_REALLOC_N_LOCOR(OVP,SZ,NO,ORARGS) \
158 su_MEM_REALLOC_N_LOC(OVP, SZ, NO, ORARGS)
159 # define su_MEM_TALLOC_LOCOR(T,NO,ORARGS) su_MEM_TALLOC_LOC(T, NO, ORARGS)
160 # define su_MEM_TCALLOC_LOCOR(T,NO,ORARGS) su_MEM_TCALLOC_LOC(T, NO, ORARGS)
161 # define su_MEM_TREALLOC_LOCOR(T,OVP,NO,ORARGS) \
162 su_MEM_TREALLOC_LOC(T, OVP, NO, ORARGS)
163 # define su_MEM_TALLOCF_LOCOR(T,NO,F,ORARGS) \
164 su_MEM_TALLOCF_LOC(T, NO, F, ORARGS)
165 # define su_MEM_TCALLOCF_LOCOR(T,NO,F,ORARGS) \
166 su_MEM_TCALLOCF_LOC(T, NO, F, ORARGS)
167 # define su_MEM_TREALLOCF_LOCOR(T,OVP,NO,F,ORARGS) \
168 su_MEM_TREALLOCF_LOC(T, OVP, NO, F, ORARGS)
169 # define su_MEM_FREE_LOCOR(OVP,ORARGS) su_MEM_FREE_LOC(OVP, ORARGS)
170 #else
171 # define su_MEM_ALLOC_LOCOR(SZ,ORARGS) su_MEM_ALLOC(SZ)
172 # define su_MEM_ALLOC_N_LOCOR(SZ,NO,ORARGS) su_MEM_ALLOC_N(SZ, NO)
173 # define su_MEM_CALLOC_LOCOR(SZ,ORARGS) su_MEM_CALLOC(SZ)
174 # define su_MEM_CALLOC_N_LOCOR(SZ,NO,ORARGS) su_MEM_CALLOC_N(SZ, NO)
175 # define su_MEM_REALLOC_LOCOR(OVP,SZ,ORARGS) su_MEM_REALLOC(OVP, SZ)
176 # define su_MEM_REALLOC_N_LOCOR(OVP,SZ,NO,ORARGS) su_MEM_REALLOC_N(OVP, SZ, NO)
177 # define su_MEM_TALLOC_LOCOR(T,NO,ORARGS) su_MEM_TALLOC(T, NO)
178 # define su_MEM_TCALLOC_LOCOR(T,NO,ORARGS) su_MEM_TCALLOC(T, NO)
179 # define su_MEM_TREALLOC_LOCOR(T,OVP,NO) su_MEM_TREALLOC(T, OVP, NO)
180 # define su_MEM_TALLOCF_LOCOR(T,NO,F,ORARGS) su_MEM_TALLOCF(T, NO, F)
181 # define su_MEM_TCALLOCF_LOCOR(T,NO,F,ORARGS) su_MEM_TCALLOCF(T, NO, F)
182 # define su_MEM_TREALLOCF_LOCOR(T,OVP,F,NO) su_MEM_TREALLOCF(T, OVP, NO, F)
183 # define su_MEM_FREE_LOCOR(OVP,ORARGS) su_MEM_FREE_LOC(OVP, ORARGS)
184 #endif /* !su_HAVE_DBG_LOC_ARGS */
185 INLINE boole su_mem_get_can_book(uz size, uz no, uz notoadd){
186 if(UZ_MAX - no <= notoadd)
187 return FAL0;
188 no += notoadd;
189 if(no == 0)
190 return TRU1;
191 no = UZ_MAX / no;
192 if(no < size || (size != 1 && no == size))
193 return FAL0;
194 #ifdef su_MEM_ALLOC_DEBUG
195 if(!su__mem_get_can_book(size, no))
196 return FAL0;
197 #endif
198 return TRU1;
200 #define su_mem_get_usable_size(SZ) su_Z_ALIGN(SZ) /* XXX fake */
201 #define su_mem_get_usable_size_32(SZ) su_S(su_u32,su_Z_ALIGN(SZ)) /*XXX*/
202 /* XXX get_usable_size_ptr(), get_memory_usage() */
203 EXPORT void su_mem_set_conf(u32 mco, uz val);
204 INLINE boole su_mem_check(void){
205 #ifdef su_MEM_ALLOC_DEBUG
206 return su__mem_check(su_DBG_LOC_ARGS_INJ_SOLE);
207 #else
208 return FAL0;
209 #endif
211 /* XXX mem_check_ptr() */
212 /* XXX mem_[usage_]info(); opt: output channel, thread ptr */
213 INLINE boole su_mem_trace(void){ /* XXX ochannel, thrptr*/
214 #ifdef su_MEM_ALLOC_DEBUG
215 return su__mem_trace(su_DBG_LOC_ARGS_INJ_SOLE);
216 #else
217 return FAL0;
218 #endif
220 C_DECL_END
221 #include <su/code-ou.h>
222 #endif /* !su_MEM_H */
223 /* s-it-mode */