1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2024-2025 The FreeBSD Foundation 5 * 6 * This software was developed by Björn Zeeb under sponsorship from 7 * the FreeBSD Foundation. 8 */ 9 10 #ifndef _LINUXKPI_LINUX_CLEANUP_H 11 #define _LINUXKPI_LINUX_CLEANUP_H 12 13 #define __cleanup(_f) __attribute__((__cleanup__(_f))) 14 15 /* 16 * Note: "_T" are special as they are exposed into common code for 17 * statements. Extra care should be taken when changing the code. 18 */ 19 #define DEFINE_GUARD(_n, _dt, _lock, _unlock) \ 20 \ 21 typedef _dt guard_ ## _n ## _t; \ 22 \ 23 static inline _dt \ 24 guard_ ## _n ## _create( _dt _T) \ 25 { \ 26 _dt c; \ 27 \ 28 c = ({ _lock; _T; }); \ 29 return (c); \ 30 } \ 31 \ 32 static inline void \ 33 guard_ ## _n ## _destroy(_dt *t) \ 34 { \ 35 _dt _T; \ 36 \ 37 _T = *t; \ 38 if (_T) { _unlock; }; \ 39 } 40 41 /* We need to keep these calls unique. */ 42 #define guard(_n) \ 43 guard_ ## _n ## _t guard_ ## _n ## _ ## __COUNTER__ \ 44 __cleanup(guard_ ## _n ## _destroy) = guard_ ## _n ## _create 45 46 #define DEFINE_FREE(_n, _t, _f) \ 47 static inline void \ 48 __free_ ## _n(void *p) \ 49 { \ 50 _t _T; \ 51 \ 52 _T = *(_t *)p; \ 53 _f; \ 54 } 55 56 #define __free(_n) __cleanup(__free_##_n) 57 58 /* 59 * Given this is a _0 version it should likely be broken up into parts. 60 * But we have no idead what a _1, _2, ... version would do different 61 * until we see a call. 62 * This is used for a not-real-type (rcu). We use a bool to "simulate" 63 * the lock held. Also _T still special, may not always be used, so tag 64 * with __unused (or better the LinuxKPI __maybe_unused). 65 */ 66 #define DEFINE_LOCK_GUARD_0(_n, _lock, _unlock, ...) \ 67 \ 68 typedef struct { \ 69 bool lock; \ 70 __VA_ARGS__; \ 71 } guard_ ## _n ## _t; \ 72 \ 73 static inline void \ 74 guard_ ## _n ## _destroy(guard_ ## _n ## _t *_T) \ 75 { \ 76 if (_T->lock) { \ 77 _unlock; \ 78 } \ 79 } \ 80 \ 81 static inline guard_ ## _n ## _t \ 82 guard_ ## _n ## _create(void) \ 83 { \ 84 guard_ ## _n ## _t _tmp; \ 85 guard_ ## _n ## _t *_T __maybe_unused; \ 86 \ 87 _tmp.lock = true; \ 88 _T = &_tmp; \ 89 _lock; \ 90 return (_tmp); \ 91 } 92 93 #endif /* _LINUXKPI_LINUX_CLEANUP_H */ 94