Loading...
Searching...
No Matches
Go to the documentation of this file. 1#ifndef __LINUX_CLEANUP_H__
2#define __LINUX_CLEANUP_H__
71#define __cleanup(fn) __attribute__((cleanup(fn)))
91#define CLASS(name, var) name##_t var __cleanup(name##_destructor) = name##_constructor
120#define DEFINE_FREE(_name, _type, _free) \
121 static __always_inline void __free_##_name(void *p) { _type _T = *(_type *)p; _free; }
123#define __free(_name) __cleanup(__free_##_name)
125#define no_free_ptr(p) \
126 ({ __auto_type __ptr = (p); (p) = NULL; __ptr; })
127#define return_ptr(p) return no_free_ptr(p)
129#define DCL_CAT2(a, b) a##b
130#define DCL_CAT(a, b) DCL_CAT2(a, b)
131#define DCL_UID(base) DCL_CAT(base, __COUNTER__)
147#define DCL_LOCK_GUARD_TYPES(name, type, release) \
148 typedef struct { type* lock; } dclg_##name; \
149 static inline void dclg_##name##_release(dclg_##name* g) \
151 type* _T = g->lock; \
152 if (_T) { release; } \
168#define DCL_LOCK_GUARD(name, type, acquire, release) \
169 DCL_LOCK_GUARD_TYPES(name, type, release) \
170 static inline dclg_##name dclg_##name##_ctor(type* p) \
180#define DCL_LOCK_GUARD_COND(name, type, acquire, release) \
181 DCL_LOCK_GUARD_TYPES(name, type, release) \
182 static inline dclg_##name dclg_##name##_ctor(type* p) \
186 int _r = (acquire); \
188 g.lock = (_r == 0) ? p : 0; \
223#define DEFINE_GUARD(_name, _type, _lock, _unlock) \
224 typedef struct { _type lock; } dclg_##_name; \
225 static inline void dclg_##_name##_release(dclg_##_name* g) \
227 _type _T = g->lock; \
228 if (_T) { _unlock; } \
230 static inline dclg_##_name dclg_##_name##_ctor(_type p) \
255#define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock, ...) \
256 typedef struct { _type* lock; __VA_ARGS__; } dclg_##_name; \
257 typedef _type dcllt_##_name; \
258 static inline void dclg_##_name##_release(dclg_##_name* _T) \
260 if (_T->lock) { _unlock; } \
262 static inline dclg_##_name dclg_##_name##_ctor(_type* p) \
264 dclg_##_name g = { .lock = p }; \
265 dclg_##_name* _T = &g; \
290#define DECLARE_LOCK_GUARD_1_ATTRS(_name, _lock, _unlock) \
291 static inline dclg_##_name dclg_##_name##_ctor(dcllt_##_name *_T) _lock;\
292 static __always_inline void dclg_##_name##_unlock_ctx(dclg_##_name **_T)\
295#define WITH_LOCK_GUARD_1_ATTRS(_name, _T) \
296 dclg_##_name##_ctor(_T), \
297 *DCL_UID(unlock) __cleanup(dclg_##_name##_unlock_ctx) = \
298 (void *)(unsigned long)(_T)
320#define DEFINE_LOCK_GUARD_0(_name, _lock, _unlock, ...) \
321 typedef struct { void *lock; __VA_ARGS__; } dclg_##_name; \
322 static inline void dclg_##_name##_release(dclg_##_name* _T) \
324 if (_T->lock) { _unlock; } \
326 static inline dclg_##_name dclg_##_name##_ctor(void) \
328 dclg_##_name _t = { .lock = (void*)1 }; \
329 dclg_##_name* _T = &_t; \
342 dclg_##name DCL_UID(dclg_##name) \
343 __cleanup(dclg_##name##_release) = dclg_##name##_ctor
353#define scoped_guard(name, args...) \
354 for (dclg_##name _dclg __cleanup(dclg_##name##_release) \
355 = dclg_##name##_ctor(args), *_dclg_done = 0; \
356 !_dclg_done; _dclg_done = (void*)1)
366#define scoped_cond_guard(name, fail, args...) \
367 for (dclg_##name _dclg __cleanup(dclg_##name##_release) \
368 = dclg_##name##_ctor(args), *_dclg_done = 0; \
369 !_dclg_done; _dclg_done = (void*)1) \
370 if (_dclg.lock == 0) { fail; } else