xref: /freebsd/sys/contrib/ck/include/ck_elide.h (revision 4f9d94bf6491250b649f5bc931b6d93e68373005)
1*1fb62fb0SOlivier Houchard /*
2*1fb62fb0SOlivier Houchard  * Copyright 2013-2015 Samy Al Bahra.
3*1fb62fb0SOlivier Houchard  * All rights reserved.
4*1fb62fb0SOlivier Houchard  *
5*1fb62fb0SOlivier Houchard  * Redistribution and use in source and binary forms, with or without
6*1fb62fb0SOlivier Houchard  * modification, are permitted provided that the following conditions
7*1fb62fb0SOlivier Houchard  * are met:
8*1fb62fb0SOlivier Houchard  * 1. Redistributions of source code must retain the above copyright
9*1fb62fb0SOlivier Houchard  *    notice, this list of conditions and the following disclaimer.
10*1fb62fb0SOlivier Houchard  * 2. Redistributions in binary form must reproduce the above copyright
11*1fb62fb0SOlivier Houchard  *    notice, this list of conditions and the following disclaimer in the
12*1fb62fb0SOlivier Houchard  *    documentation and/or other materials provided with the distribution.
13*1fb62fb0SOlivier Houchard  *
14*1fb62fb0SOlivier Houchard  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*1fb62fb0SOlivier Houchard  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*1fb62fb0SOlivier Houchard  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*1fb62fb0SOlivier Houchard  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*1fb62fb0SOlivier Houchard  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*1fb62fb0SOlivier Houchard  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*1fb62fb0SOlivier Houchard  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*1fb62fb0SOlivier Houchard  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*1fb62fb0SOlivier Houchard  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*1fb62fb0SOlivier Houchard  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*1fb62fb0SOlivier Houchard  * SUCH DAMAGE.
25*1fb62fb0SOlivier Houchard  */
26*1fb62fb0SOlivier Houchard 
27*1fb62fb0SOlivier Houchard #ifndef CK_ELIDE_H
28*1fb62fb0SOlivier Houchard #define CK_ELIDE_H
29*1fb62fb0SOlivier Houchard 
30*1fb62fb0SOlivier Houchard /*
31*1fb62fb0SOlivier Houchard  * As RTM is currently only supported on TSO x86 architectures,
32*1fb62fb0SOlivier Houchard  * fences have been omitted. They will be necessary for other
33*1fb62fb0SOlivier Houchard  * non-TSO architectures with TM support.
34*1fb62fb0SOlivier Houchard  */
35*1fb62fb0SOlivier Houchard 
36*1fb62fb0SOlivier Houchard #include <ck_cc.h>
37*1fb62fb0SOlivier Houchard #include <ck_pr.h>
38*1fb62fb0SOlivier Houchard #include <ck_string.h>
39*1fb62fb0SOlivier Houchard 
40*1fb62fb0SOlivier Houchard /*
41*1fb62fb0SOlivier Houchard  * skip_-prefixed counters represent the number of consecutive
42*1fb62fb0SOlivier Houchard  * elisions to forfeit. retry_-prefixed counters represent the
43*1fb62fb0SOlivier Houchard  * number of elision retries to attempt before forfeit.
44*1fb62fb0SOlivier Houchard  *
45*1fb62fb0SOlivier Houchard  *     _busy: Lock was busy
46*1fb62fb0SOlivier Houchard  *    _other: Unknown explicit abort
47*1fb62fb0SOlivier Houchard  * _conflict: Data conflict in elision section
48*1fb62fb0SOlivier Houchard  */
49*1fb62fb0SOlivier Houchard struct ck_elide_config {
50*1fb62fb0SOlivier Houchard 	unsigned short skip_busy;
51*1fb62fb0SOlivier Houchard 	short retry_busy;
52*1fb62fb0SOlivier Houchard 	unsigned short skip_other;
53*1fb62fb0SOlivier Houchard 	short retry_other;
54*1fb62fb0SOlivier Houchard 	unsigned short skip_conflict;
55*1fb62fb0SOlivier Houchard 	short retry_conflict;
56*1fb62fb0SOlivier Houchard };
57*1fb62fb0SOlivier Houchard 
58*1fb62fb0SOlivier Houchard #define CK_ELIDE_CONFIG_DEFAULT_INITIALIZER {	\
59*1fb62fb0SOlivier Houchard 	.skip_busy = 5,				\
60*1fb62fb0SOlivier Houchard 	.retry_busy = 256,			\
61*1fb62fb0SOlivier Houchard 	.skip_other = 3,			\
62*1fb62fb0SOlivier Houchard 	.retry_other = 3,			\
63*1fb62fb0SOlivier Houchard 	.skip_conflict = 2,			\
64*1fb62fb0SOlivier Houchard 	.retry_conflict = 5			\
65*1fb62fb0SOlivier Houchard }
66*1fb62fb0SOlivier Houchard 
67*1fb62fb0SOlivier Houchard struct ck_elide_stat {
68*1fb62fb0SOlivier Houchard 	unsigned int n_fallback;
69*1fb62fb0SOlivier Houchard 	unsigned int n_elide;
70*1fb62fb0SOlivier Houchard 	unsigned short skip;
71*1fb62fb0SOlivier Houchard };
72*1fb62fb0SOlivier Houchard typedef struct ck_elide_stat ck_elide_stat_t;
73*1fb62fb0SOlivier Houchard 
74*1fb62fb0SOlivier Houchard #define CK_ELIDE_STAT_INITIALIZER { 0, 0, 0 }
75*1fb62fb0SOlivier Houchard 
76*1fb62fb0SOlivier Houchard CK_CC_INLINE static void
ck_elide_stat_init(ck_elide_stat_t * st)77*1fb62fb0SOlivier Houchard ck_elide_stat_init(ck_elide_stat_t *st)
78*1fb62fb0SOlivier Houchard {
79*1fb62fb0SOlivier Houchard 
80*1fb62fb0SOlivier Houchard 	memset(st, 0, sizeof(*st));
81*1fb62fb0SOlivier Houchard 	return;
82*1fb62fb0SOlivier Houchard }
83*1fb62fb0SOlivier Houchard 
84*1fb62fb0SOlivier Houchard #ifdef CK_F_PR_RTM
85*1fb62fb0SOlivier Houchard enum _ck_elide_hint {
86*1fb62fb0SOlivier Houchard 	CK_ELIDE_HINT_RETRY = 0,
87*1fb62fb0SOlivier Houchard 	CK_ELIDE_HINT_SPIN,
88*1fb62fb0SOlivier Houchard 	CK_ELIDE_HINT_STOP
89*1fb62fb0SOlivier Houchard };
90*1fb62fb0SOlivier Houchard 
91*1fb62fb0SOlivier Houchard #define CK_ELIDE_LOCK_BUSY 0xFF
92*1fb62fb0SOlivier Houchard 
93*1fb62fb0SOlivier Houchard static enum _ck_elide_hint
_ck_elide_fallback(int * retry,struct ck_elide_stat * st,struct ck_elide_config * c,unsigned int status)94*1fb62fb0SOlivier Houchard _ck_elide_fallback(int *retry,
95*1fb62fb0SOlivier Houchard     struct ck_elide_stat *st,
96*1fb62fb0SOlivier Houchard     struct ck_elide_config *c,
97*1fb62fb0SOlivier Houchard     unsigned int status)
98*1fb62fb0SOlivier Houchard {
99*1fb62fb0SOlivier Houchard 
100*1fb62fb0SOlivier Houchard 	st->n_fallback++;
101*1fb62fb0SOlivier Houchard 	if (*retry > 0)
102*1fb62fb0SOlivier Houchard 		return CK_ELIDE_HINT_RETRY;
103*1fb62fb0SOlivier Houchard 
104*1fb62fb0SOlivier Houchard 	if (st->skip != 0)
105*1fb62fb0SOlivier Houchard 		return CK_ELIDE_HINT_STOP;
106*1fb62fb0SOlivier Houchard 
107*1fb62fb0SOlivier Houchard 	if (status & CK_PR_RTM_EXPLICIT) {
108*1fb62fb0SOlivier Houchard 		if (CK_PR_RTM_CODE(status) == CK_ELIDE_LOCK_BUSY) {
109*1fb62fb0SOlivier Houchard 			st->skip = c->skip_busy;
110*1fb62fb0SOlivier Houchard 			*retry = c->retry_busy;
111*1fb62fb0SOlivier Houchard 			return CK_ELIDE_HINT_SPIN;
112*1fb62fb0SOlivier Houchard 		}
113*1fb62fb0SOlivier Houchard 
114*1fb62fb0SOlivier Houchard 		st->skip = c->skip_other;
115*1fb62fb0SOlivier Houchard 		return CK_ELIDE_HINT_STOP;
116*1fb62fb0SOlivier Houchard 	}
117*1fb62fb0SOlivier Houchard 
118*1fb62fb0SOlivier Houchard 	if ((status & CK_PR_RTM_RETRY) &&
119*1fb62fb0SOlivier Houchard 	    (status & CK_PR_RTM_CONFLICT)) {
120*1fb62fb0SOlivier Houchard 		st->skip = c->skip_conflict;
121*1fb62fb0SOlivier Houchard 		*retry = c->retry_conflict;
122*1fb62fb0SOlivier Houchard 		return CK_ELIDE_HINT_RETRY;
123*1fb62fb0SOlivier Houchard 	}
124*1fb62fb0SOlivier Houchard 
125*1fb62fb0SOlivier Houchard 	/*
126*1fb62fb0SOlivier Houchard 	 * Capacity, debug and nesting abortions are likely to be
127*1fb62fb0SOlivier Houchard 	 * invariant conditions for the acquisition, execute regular
128*1fb62fb0SOlivier Houchard 	 * path instead. If retry bit is not set, then take the hint.
129*1fb62fb0SOlivier Houchard 	 */
130*1fb62fb0SOlivier Houchard 	st->skip = USHRT_MAX;
131*1fb62fb0SOlivier Houchard 	return CK_ELIDE_HINT_STOP;
132*1fb62fb0SOlivier Houchard }
133*1fb62fb0SOlivier Houchard 
134*1fb62fb0SOlivier Houchard /*
135*1fb62fb0SOlivier Houchard  * Defines an elision implementation according to the following variables:
136*1fb62fb0SOlivier Houchard  *     N - Namespace of elision implementation.
137*1fb62fb0SOlivier Houchard  *     T - Typename of mutex.
138*1fb62fb0SOlivier Houchard  *   L_P - Lock predicate, returns false if resource is available.
139*1fb62fb0SOlivier Houchard  *     L - Function to call if resource is unavailable of transaction aborts.
140*1fb62fb0SOlivier Houchard  *   U_P - Unlock predicate, returns false if elision failed.
141*1fb62fb0SOlivier Houchard  *     U - Function to call if transaction failed.
142*1fb62fb0SOlivier Houchard  */
143*1fb62fb0SOlivier Houchard #define CK_ELIDE_PROTOTYPE(N, T, L_P, L, U_P, U)					\
144*1fb62fb0SOlivier Houchard 	CK_CC_INLINE static void							\
145*1fb62fb0SOlivier Houchard 	ck_elide_##N##_lock_adaptive(T *lock,						\
146*1fb62fb0SOlivier Houchard 	    struct ck_elide_stat *st,							\
147*1fb62fb0SOlivier Houchard 	    struct ck_elide_config *c)							\
148*1fb62fb0SOlivier Houchard 	{										\
149*1fb62fb0SOlivier Houchard 		enum _ck_elide_hint hint;						\
150*1fb62fb0SOlivier Houchard 		int retry;								\
151*1fb62fb0SOlivier Houchard 											\
152*1fb62fb0SOlivier Houchard 		if (CK_CC_UNLIKELY(st->skip != 0)) {					\
153*1fb62fb0SOlivier Houchard 			st->skip--;							\
154*1fb62fb0SOlivier Houchard 			goto acquire;							\
155*1fb62fb0SOlivier Houchard 		}									\
156*1fb62fb0SOlivier Houchard 											\
157*1fb62fb0SOlivier Houchard 		retry = c->retry_conflict;						\
158*1fb62fb0SOlivier Houchard 		do {									\
159*1fb62fb0SOlivier Houchard 			unsigned int status = ck_pr_rtm_begin();			\
160*1fb62fb0SOlivier Houchard 			if (status == CK_PR_RTM_STARTED) {				\
161*1fb62fb0SOlivier Houchard 				if (L_P(lock) == true)					\
162*1fb62fb0SOlivier Houchard 					ck_pr_rtm_abort(CK_ELIDE_LOCK_BUSY);		\
163*1fb62fb0SOlivier Houchard 											\
164*1fb62fb0SOlivier Houchard 				return;							\
165*1fb62fb0SOlivier Houchard 			}								\
166*1fb62fb0SOlivier Houchard 											\
167*1fb62fb0SOlivier Houchard 			hint = _ck_elide_fallback(&retry, st, c, status);		\
168*1fb62fb0SOlivier Houchard 			if (hint == CK_ELIDE_HINT_RETRY)				\
169*1fb62fb0SOlivier Houchard 				continue;						\
170*1fb62fb0SOlivier Houchard 											\
171*1fb62fb0SOlivier Houchard 			if (hint == CK_ELIDE_HINT_SPIN) {				\
172*1fb62fb0SOlivier Houchard 				while (--retry != 0) {					\
173*1fb62fb0SOlivier Houchard 					if (L_P(lock) == false)				\
174*1fb62fb0SOlivier Houchard 						break;					\
175*1fb62fb0SOlivier Houchard 											\
176*1fb62fb0SOlivier Houchard 					ck_pr_stall();					\
177*1fb62fb0SOlivier Houchard 				}							\
178*1fb62fb0SOlivier Houchard 											\
179*1fb62fb0SOlivier Houchard 				continue;						\
180*1fb62fb0SOlivier Houchard 			}								\
181*1fb62fb0SOlivier Houchard 											\
182*1fb62fb0SOlivier Houchard 			if (hint == CK_ELIDE_HINT_STOP)					\
183*1fb62fb0SOlivier Houchard 				break;							\
184*1fb62fb0SOlivier Houchard 		} while (CK_CC_LIKELY(--retry > 0));					\
185*1fb62fb0SOlivier Houchard 											\
186*1fb62fb0SOlivier Houchard 	acquire:									\
187*1fb62fb0SOlivier Houchard 		L(lock);								\
188*1fb62fb0SOlivier Houchard 		return;									\
189*1fb62fb0SOlivier Houchard 	}										\
190*1fb62fb0SOlivier Houchard 	CK_CC_INLINE static void							\
191*1fb62fb0SOlivier Houchard 	ck_elide_##N##_unlock_adaptive(struct ck_elide_stat *st, T *lock)		\
192*1fb62fb0SOlivier Houchard 	{										\
193*1fb62fb0SOlivier Houchard 											\
194*1fb62fb0SOlivier Houchard 		if (U_P(lock) == false) {						\
195*1fb62fb0SOlivier Houchard 			ck_pr_rtm_end();						\
196*1fb62fb0SOlivier Houchard 			st->skip = 0;							\
197*1fb62fb0SOlivier Houchard 			st->n_elide++;							\
198*1fb62fb0SOlivier Houchard 		} else {								\
199*1fb62fb0SOlivier Houchard 			U(lock);							\
200*1fb62fb0SOlivier Houchard 		}									\
201*1fb62fb0SOlivier Houchard 											\
202*1fb62fb0SOlivier Houchard 		return;									\
203*1fb62fb0SOlivier Houchard 	}										\
204*1fb62fb0SOlivier Houchard 	CK_CC_INLINE static void							\
205*1fb62fb0SOlivier Houchard 	ck_elide_##N##_lock(T *lock)							\
206*1fb62fb0SOlivier Houchard 	{										\
207*1fb62fb0SOlivier Houchard 											\
208*1fb62fb0SOlivier Houchard 		if (ck_pr_rtm_begin() != CK_PR_RTM_STARTED) {				\
209*1fb62fb0SOlivier Houchard 			L(lock);							\
210*1fb62fb0SOlivier Houchard 			return;								\
211*1fb62fb0SOlivier Houchard 		}									\
212*1fb62fb0SOlivier Houchard 											\
213*1fb62fb0SOlivier Houchard 		if (L_P(lock) == true)							\
214*1fb62fb0SOlivier Houchard 			ck_pr_rtm_abort(CK_ELIDE_LOCK_BUSY);				\
215*1fb62fb0SOlivier Houchard 											\
216*1fb62fb0SOlivier Houchard 		return;									\
217*1fb62fb0SOlivier Houchard 	}										\
218*1fb62fb0SOlivier Houchard 	CK_CC_INLINE static void							\
219*1fb62fb0SOlivier Houchard 	ck_elide_##N##_unlock(T *lock)							\
220*1fb62fb0SOlivier Houchard 	{										\
221*1fb62fb0SOlivier Houchard 											\
222*1fb62fb0SOlivier Houchard 		if (U_P(lock) == false) {						\
223*1fb62fb0SOlivier Houchard 			ck_pr_rtm_end();						\
224*1fb62fb0SOlivier Houchard 		} else {								\
225*1fb62fb0SOlivier Houchard 			U(lock);							\
226*1fb62fb0SOlivier Houchard 		}									\
227*1fb62fb0SOlivier Houchard 											\
228*1fb62fb0SOlivier Houchard 		return;									\
229*1fb62fb0SOlivier Houchard 	}
230*1fb62fb0SOlivier Houchard 
231*1fb62fb0SOlivier Houchard #define CK_ELIDE_TRYLOCK_PROTOTYPE(N, T, TL_P, TL)			\
232*1fb62fb0SOlivier Houchard 	CK_CC_INLINE static bool					\
233*1fb62fb0SOlivier Houchard 	ck_elide_##N##_trylock(T *lock)					\
234*1fb62fb0SOlivier Houchard 	{								\
235*1fb62fb0SOlivier Houchard 									\
236*1fb62fb0SOlivier Houchard 		if (ck_pr_rtm_begin() != CK_PR_RTM_STARTED)		\
237*1fb62fb0SOlivier Houchard 			return false;					\
238*1fb62fb0SOlivier Houchard 									\
239*1fb62fb0SOlivier Houchard 		if (TL_P(lock) == true)					\
240*1fb62fb0SOlivier Houchard 			ck_pr_rtm_abort(CK_ELIDE_LOCK_BUSY);		\
241*1fb62fb0SOlivier Houchard 									\
242*1fb62fb0SOlivier Houchard 		return true;						\
243*1fb62fb0SOlivier Houchard 	}
244*1fb62fb0SOlivier Houchard #else
245*1fb62fb0SOlivier Houchard /*
246*1fb62fb0SOlivier Houchard  * If RTM is not enabled on the target platform (CK_F_PR_RTM) then these
247*1fb62fb0SOlivier Houchard  * elision wrappers directly calls into the user-specified lock operations.
248*1fb62fb0SOlivier Houchard  * Unfortunately, the storage cost of both ck_elide_config and ck_elide_stat
249*1fb62fb0SOlivier Houchard  * are paid (typically a storage cost that is a function of lock objects and
250*1fb62fb0SOlivier Houchard  * thread count).
251*1fb62fb0SOlivier Houchard  */
252*1fb62fb0SOlivier Houchard #define CK_ELIDE_PROTOTYPE(N, T, L_P, L, U_P, U)			\
253*1fb62fb0SOlivier Houchard 	CK_CC_INLINE static void					\
254*1fb62fb0SOlivier Houchard 	ck_elide_##N##_lock_adaptive(T *lock,				\
255*1fb62fb0SOlivier Houchard 	    struct ck_elide_stat *st,					\
256*1fb62fb0SOlivier Houchard 	    struct ck_elide_config *c)					\
257*1fb62fb0SOlivier Houchard 	{								\
258*1fb62fb0SOlivier Houchard 									\
259*1fb62fb0SOlivier Houchard 		(void)st;						\
260*1fb62fb0SOlivier Houchard 		(void)c;						\
261*1fb62fb0SOlivier Houchard 		L(lock);						\
262*1fb62fb0SOlivier Houchard 		return;							\
263*1fb62fb0SOlivier Houchard 	}								\
264*1fb62fb0SOlivier Houchard 	CK_CC_INLINE static void					\
265*1fb62fb0SOlivier Houchard 	ck_elide_##N##_unlock_adaptive(struct ck_elide_stat *st,	\
266*1fb62fb0SOlivier Houchard 	    T *lock)							\
267*1fb62fb0SOlivier Houchard 	{								\
268*1fb62fb0SOlivier Houchard 									\
269*1fb62fb0SOlivier Houchard 		(void)st;						\
270*1fb62fb0SOlivier Houchard 		U(lock);						\
271*1fb62fb0SOlivier Houchard 		return;							\
272*1fb62fb0SOlivier Houchard 	}								\
273*1fb62fb0SOlivier Houchard 	CK_CC_INLINE static void					\
274*1fb62fb0SOlivier Houchard 	ck_elide_##N##_lock(T *lock)					\
275*1fb62fb0SOlivier Houchard 	{								\
276*1fb62fb0SOlivier Houchard 									\
277*1fb62fb0SOlivier Houchard 		L(lock);						\
278*1fb62fb0SOlivier Houchard 		return;							\
279*1fb62fb0SOlivier Houchard 	}								\
280*1fb62fb0SOlivier Houchard 	CK_CC_INLINE static void					\
281*1fb62fb0SOlivier Houchard 	ck_elide_##N##_unlock(T *lock)					\
282*1fb62fb0SOlivier Houchard 	{								\
283*1fb62fb0SOlivier Houchard 									\
284*1fb62fb0SOlivier Houchard 		U(lock);						\
285*1fb62fb0SOlivier Houchard 		return;							\
286*1fb62fb0SOlivier Houchard 	}
287*1fb62fb0SOlivier Houchard 
288*1fb62fb0SOlivier Houchard #define CK_ELIDE_TRYLOCK_PROTOTYPE(N, T, TL_P, TL)			\
289*1fb62fb0SOlivier Houchard 	CK_CC_INLINE static bool					\
290*1fb62fb0SOlivier Houchard 	ck_elide_##N##_trylock(T *lock)					\
291*1fb62fb0SOlivier Houchard 	{								\
292*1fb62fb0SOlivier Houchard 									\
293*1fb62fb0SOlivier Houchard 		return TL_P(lock);					\
294*1fb62fb0SOlivier Houchard 	}
295*1fb62fb0SOlivier Houchard #endif /* !CK_F_PR_RTM */
296*1fb62fb0SOlivier Houchard 
297*1fb62fb0SOlivier Houchard /*
298*1fb62fb0SOlivier Houchard  * Best-effort elision lock operations. First argument is name (N)
299*1fb62fb0SOlivier Houchard  * associated with implementation and the second is a pointer to
300*1fb62fb0SOlivier Houchard  * the type specified above (T).
301*1fb62fb0SOlivier Houchard  *
302*1fb62fb0SOlivier Houchard  * Unlike the adaptive variant, this interface does not have any retry
303*1fb62fb0SOlivier Houchard  * semantics. In environments where jitter is low, this may yield a tighter
304*1fb62fb0SOlivier Houchard  * fast path.
305*1fb62fb0SOlivier Houchard  */
306*1fb62fb0SOlivier Houchard #define CK_ELIDE_LOCK(NAME, LOCK)	ck_elide_##NAME##_lock(LOCK)
307*1fb62fb0SOlivier Houchard #define CK_ELIDE_UNLOCK(NAME, LOCK)	ck_elide_##NAME##_unlock(LOCK)
308*1fb62fb0SOlivier Houchard #define CK_ELIDE_TRYLOCK(NAME, LOCK)	ck_elide_##NAME##_trylock(LOCK)
309*1fb62fb0SOlivier Houchard 
310*1fb62fb0SOlivier Houchard /*
311*1fb62fb0SOlivier Houchard  * Adaptive elision lock operations. In addition to name and pointer
312*1fb62fb0SOlivier Houchard  * to the lock, you must pass in a pointer to an initialized
313*1fb62fb0SOlivier Houchard  * ck_elide_config structure along with a per-thread stat structure.
314*1fb62fb0SOlivier Houchard  */
315*1fb62fb0SOlivier Houchard #define CK_ELIDE_LOCK_ADAPTIVE(NAME, STAT, CONFIG, LOCK) \
316*1fb62fb0SOlivier Houchard 	ck_elide_##NAME##_lock_adaptive(LOCK, STAT, CONFIG)
317*1fb62fb0SOlivier Houchard 
318*1fb62fb0SOlivier Houchard #define CK_ELIDE_UNLOCK_ADAPTIVE(NAME, STAT, LOCK) \
319*1fb62fb0SOlivier Houchard 	ck_elide_##NAME##_unlock_adaptive(STAT, LOCK)
320*1fb62fb0SOlivier Houchard 
321*1fb62fb0SOlivier Houchard #endif /* CK_ELIDE_H */
322