Zephyr API Documentation
4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
cleanup.h
Go to the documentation of this file.
1
5
6
#ifndef ZEPHYR_INCLUDE_CLEANUP_H_
7
#define ZEPHYR_INCLUDE_CLEANUP_H_
8
9
#include <
zephyr/toolchain.h
>
10
15
21
22
#if defined(CONFIG_SCOPE_CLEANUP_HELPERS) || defined(__DOXYGEN__)
23
85
#define SCOPE_VAR_DEFINE(_name, _type, _exit_fn, _init_fn, ...) \
86
static inline void __maybe_unused cleanup_##_name##_exit(_type *p) \
87
{ \
88
_type _T = *p; \
89
_exit_fn; \
90
} \
91
static inline _type __maybe_unused cleanup_##_name##_init(__VA_ARGS__) \
92
{ \
93
_type t = _init_fn; \
94
return t; \
95
} \
96
typedef _type cleanup_##_name##_t
97
118
#define SCOPE_GUARD_DEFINE(_name, _type, _lock, _unlock) \
119
SCOPE_VAR_DEFINE( \
120
guard_##_name, _type, if (_T != NULL) { _unlock; }, ({ \
121
_lock; \
122
_T; \
123
}), \
124
_type _T)
125
150
#define SCOPE_COND_GUARD_DEFINE(_name, _type, _try_lock, _unlock) \
151
SCOPE_VAR_DEFINE(guard_##_name, _type, if (_T != NULL) { _unlock; }, \
152
((_try_lock) ? _T : NULL), _type _T)
153
155
156
#define Z_SCOPE_DEFER_DEFINE_VOID(_func) \
157
SCOPE_VAR_DEFINE(defer_##_func, void *, (void)_T; (void)_func(), NULL, void)
158
159
#define Z_DEFER_CTX_ARG(idx, t) t arg##idx;
160
#define Z_DEFER_FUNC_ARG(idx, t) t arg##idx
161
#define Z_DEFER_INIT_ARG(idx, _) .arg##idx = arg##idx
162
#define Z_DEFER_EXIT_ARG(idx, _) _T.arg##idx
163
#define Z_COMMA ,
164
165
#define Z_SCOPE_DEFER_DEFINE_N(_func, ...) \
166
struct defer_##_func##_ctx { \
167
FOR_EACH_IDX(Z_DEFER_CTX_ARG, (), __VA_ARGS__) \
168
}; \
169
SCOPE_VAR_DEFINE(defer_##_func, struct defer_##_func##_ctx, \
170
(void)_func(FOR_EACH_IDX(Z_DEFER_EXIT_ARG, (Z_COMMA), __VA_ARGS__)), \
171
{FOR_EACH_IDX(Z_DEFER_INIT_ARG, (Z_COMMA), __VA_ARGS__)}, \
172
FOR_EACH_IDX(Z_DEFER_FUNC_ARG, (Z_COMMA), __VA_ARGS__))
173
175
192
#define SCOPE_DEFER_DEFINE(_func, ...) \
193
COND_CODE_0(NUM_VA_ARGS(__VA_ARGS__), \
194
(Z_SCOPE_DEFER_DEFINE_VOID(_func)), \
195
(Z_SCOPE_DEFER_DEFINE_N(_func, __VA_ARGS__)))
196
198
204
#define Z_UNIQUE_ID(_prefix) _CONCAT(_CONCAT(Z_UNIQUE_ID_, _prefix), __COUNTER__)
205
206
/*
207
* Block-scope wrapper for @ref scoped_guard. A single-iteration nested for-loop ties the
208
* lifetime of the guard variable (_g) - and thus its cleanup/release - to the brace body
209
* that follows. The body is guarded on _g != NULL so that a conditional guard whose
210
* acquisition fails skips the body instead of running it without the lock held.
211
* For an unconditional guard _g is always non-NULL.
212
*/
213
#define Z_SCOPED_GUARD(_name, _g, _done, ...) \
214
for (int _done = 0; _done == 0; _done = 1) \
215
for (scope_var(guard_##_name, _g)(__VA_ARGS__); _done == 0 && _g != NULL; \
216
_done = 1)
217
218
/*
219
* Block-scope wrapper for @ref scoped_cond_guard. Like Z_SCOPED_GUARD but the guard
220
* variable is named (_g) so the body can be guarded on whether the lock was acquired:
221
* when acquisition fails _g is NULL, _fail runs and the body is skipped.
222
*/
223
#define Z_SCOPED_COND_GUARD(_name, _g, _done, _fail, ...) \
224
for (int _done = 0; _done == 0; _done = 1) \
225
for (scope_var(guard_##_name, _g)(__VA_ARGS__); _done == 0; _done = 1) \
226
if (_g == NULL) { \
227
_fail; \
228
} else
229
231
251
#define scope_var(_name, _var) \
252
cleanup_##_name##_t _var __cleanup(cleanup_##_name##_exit) = cleanup_##_name##_init
253
276
#define scope_var_init(_name, _var, _init_expr) \
277
cleanup_##_name##_t _var __cleanup(cleanup_##_name##_exit) = (_init_expr)
278
292
#define scope_guard(_name) scope_var(guard_##_name, Z_UNIQUE_ID(guard))
293
325
#define scoped_guard(_name, ...) \
326
Z_SCOPED_GUARD(_name, Z_UNIQUE_ID(scoped_g), Z_UNIQUE_ID(scoped_done), __VA_ARGS__)
327
354
#define scoped_cond_guard(_name, _fail, ...) \
355
Z_SCOPED_COND_GUARD(_name, Z_UNIQUE_ID(scoped_g), Z_UNIQUE_ID(scoped_done), _fail, \
356
__VA_ARGS__)
357
371
#define scope_defer(_name) scope_var(defer_##_name, Z_UNIQUE_ID(defer))
372
376
377
#endif
/* defined(CONFIG_SCOPE_CLEANUP_HELPERS) || defined(__DOXYGEN__) */
378
379
#endif
/* ZEPHYR_INCLUDE_CLEANUP_H_ */
toolchain.h
Macros to abstract toolchain specific capabilities.
zephyr
cleanup.h
Generated on
for Zephyr API Documentation by
1.16.1