xref: /freebsd/sys/compat/linuxkpi/common/include/linux/cleanup.h (revision fa81baa307da9a0055d7d08f6d141ea310f067ed)
1*fa81baa3SBjoern A. Zeeb /*-
2*fa81baa3SBjoern A. Zeeb  * SPDX-License-Identifier: BSD-2-Clause
3*fa81baa3SBjoern A. Zeeb  *
4*fa81baa3SBjoern A. Zeeb  * Copyright (c) 2024 The FreeBSD Foundation
5*fa81baa3SBjoern A. Zeeb  *
6*fa81baa3SBjoern A. Zeeb  * This software was developed by Björn Zeeb under sponsorship from
7*fa81baa3SBjoern A. Zeeb  * the FreeBSD Foundation.
8*fa81baa3SBjoern A. Zeeb  */
9*fa81baa3SBjoern A. Zeeb 
10*fa81baa3SBjoern A. Zeeb #ifndef	_LINUXKPI_LINUX_CLEANUP_H
11*fa81baa3SBjoern A. Zeeb #define	_LINUXKPI_LINUX_CLEANUP_H
12*fa81baa3SBjoern A. Zeeb 
13*fa81baa3SBjoern A. Zeeb #define	__cleanup(_f)		__attribute__((__cleanup__(_f)))
14*fa81baa3SBjoern A. Zeeb 
15*fa81baa3SBjoern A. Zeeb /*
16*fa81baa3SBjoern A. Zeeb  * Note: "_T" are special as they are exposed into common code for
17*fa81baa3SBjoern A. Zeeb  * statements.  Extra care should be taken when changing the code.
18*fa81baa3SBjoern A. Zeeb  */
19*fa81baa3SBjoern A. Zeeb #define	DEFINE_GUARD(_n, _dt, _lock, _unlock)				\
20*fa81baa3SBjoern A. Zeeb 									\
21*fa81baa3SBjoern A. Zeeb     typedef _dt guard_ ## _n ## _t;					\
22*fa81baa3SBjoern A. Zeeb 									\
23*fa81baa3SBjoern A. Zeeb     static inline _dt							\
24*fa81baa3SBjoern A. Zeeb     guard_ ## _n ## _create( _dt _T)					\
25*fa81baa3SBjoern A. Zeeb     {									\
26*fa81baa3SBjoern A. Zeeb 	_dt c;								\
27*fa81baa3SBjoern A. Zeeb 									\
28*fa81baa3SBjoern A. Zeeb 	c = ({ _lock; _T; });						\
29*fa81baa3SBjoern A. Zeeb 	return (c);							\
30*fa81baa3SBjoern A. Zeeb     }									\
31*fa81baa3SBjoern A. Zeeb 									\
32*fa81baa3SBjoern A. Zeeb     static inline void							\
33*fa81baa3SBjoern A. Zeeb     guard_ ## _n ## _destroy(_dt *t)					\
34*fa81baa3SBjoern A. Zeeb     {									\
35*fa81baa3SBjoern A. Zeeb 	_dt _T;								\
36*fa81baa3SBjoern A. Zeeb 									\
37*fa81baa3SBjoern A. Zeeb 	_T = *t;							\
38*fa81baa3SBjoern A. Zeeb 	if (_T) { _unlock; };						\
39*fa81baa3SBjoern A. Zeeb     }
40*fa81baa3SBjoern A. Zeeb 
41*fa81baa3SBjoern A. Zeeb /* We need to keep these calls unique. */
42*fa81baa3SBjoern A. Zeeb #define	guard(_n)							\
43*fa81baa3SBjoern A. Zeeb     guard_ ## _n ## _t guard_ ## _n ## _ ## __COUNTER__			\
44*fa81baa3SBjoern A. Zeeb 	__cleanup(guard_ ## _n ## _destroy) = guard_ ## _n ## _create
45*fa81baa3SBjoern A. Zeeb 
46*fa81baa3SBjoern A. Zeeb #endif	/* _LINUXKPI_LINUX_CLEANUP_H */
47