xref: /freebsd/sys/contrib/ck/include/spinlock/ticket.h (revision 1fb62fb0)
1*1fb62fb0SOlivier Houchard /*
2*1fb62fb0SOlivier Houchard  * Copyright 2010-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_SPINLOCK_TICKET_H
28*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_H
29*1fb62fb0SOlivier Houchard 
30*1fb62fb0SOlivier Houchard #include <ck_backoff.h>
31*1fb62fb0SOlivier Houchard #include <ck_cc.h>
32*1fb62fb0SOlivier Houchard #include <ck_elide.h>
33*1fb62fb0SOlivier Houchard #include <ck_md.h>
34*1fb62fb0SOlivier Houchard #include <ck_pr.h>
35*1fb62fb0SOlivier Houchard #include <ck_stdbool.h>
36*1fb62fb0SOlivier Houchard 
37*1fb62fb0SOlivier Houchard #ifndef CK_F_SPINLOCK_TICKET
38*1fb62fb0SOlivier Houchard #define CK_F_SPINLOCK_TICKET
39*1fb62fb0SOlivier Houchard /*
40*1fb62fb0SOlivier Houchard  * If 16-bit or 32-bit increment is supported, implement support for
41*1fb62fb0SOlivier Houchard  * trylock functionality on availability of 32-bit or 64-bit fetch-and-add
42*1fb62fb0SOlivier Houchard  * and compare-and-swap. This code path is only applied to x86*.
43*1fb62fb0SOlivier Houchard  */
44*1fb62fb0SOlivier Houchard #if defined(CK_MD_TSO) && (defined(__x86__) || defined(__x86_64__))
45*1fb62fb0SOlivier Houchard #if defined(CK_F_PR_FAA_32) && defined(CK_F_PR_INC_16) && defined(CK_F_PR_CAS_32)
46*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_TYPE		uint32_t
47*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_TYPE_BASE	uint16_t
48*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_INC(x)	ck_pr_inc_16(x)
49*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_CAS(x, y, z) ck_pr_cas_32(x, y, z)
50*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_FAA(x, y)	ck_pr_faa_32(x, y)
51*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_LOAD(x)	ck_pr_load_32(x)
52*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_INCREMENT	(0x00010000UL)
53*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_MASK		(0xFFFFUL)
54*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_SHIFT	(16)
55*1fb62fb0SOlivier Houchard #elif defined(CK_F_PR_FAA_64) && defined(CK_F_PR_INC_32) && defined(CK_F_PR_CAS_64)
56*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_TYPE		uint64_t
57*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_TYPE_BASE	uint32_t
58*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_INC(x)	ck_pr_inc_32(x)
59*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_CAS(x, y, z) ck_pr_cas_64(x, y, z)
60*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_FAA(x, y)	ck_pr_faa_64(x, y)
61*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_LOAD(x)	ck_pr_load_64(x)
62*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_INCREMENT	(0x0000000100000000ULL)
63*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_MASK		(0xFFFFFFFFULL)
64*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_SHIFT	(32)
65*1fb62fb0SOlivier Houchard #endif
66*1fb62fb0SOlivier Houchard #endif /* CK_MD_TSO */
67*1fb62fb0SOlivier Houchard 
68*1fb62fb0SOlivier Houchard #if defined(CK_SPINLOCK_TICKET_TYPE)
69*1fb62fb0SOlivier Houchard #define CK_F_SPINLOCK_TICKET_TRYLOCK
70*1fb62fb0SOlivier Houchard 
71*1fb62fb0SOlivier Houchard struct ck_spinlock_ticket {
72*1fb62fb0SOlivier Houchard 	CK_SPINLOCK_TICKET_TYPE value;
73*1fb62fb0SOlivier Houchard };
74*1fb62fb0SOlivier Houchard typedef struct ck_spinlock_ticket ck_spinlock_ticket_t;
75*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_INITIALIZER { .value = 0 }
76*1fb62fb0SOlivier Houchard 
77*1fb62fb0SOlivier Houchard CK_CC_INLINE static void
ck_spinlock_ticket_init(struct ck_spinlock_ticket * ticket)78*1fb62fb0SOlivier Houchard ck_spinlock_ticket_init(struct ck_spinlock_ticket *ticket)
79*1fb62fb0SOlivier Houchard {
80*1fb62fb0SOlivier Houchard 
81*1fb62fb0SOlivier Houchard 	ticket->value = 0;
82*1fb62fb0SOlivier Houchard 	ck_pr_barrier();
83*1fb62fb0SOlivier Houchard 	return;
84*1fb62fb0SOlivier Houchard }
85*1fb62fb0SOlivier Houchard 
86*1fb62fb0SOlivier Houchard CK_CC_INLINE static bool
ck_spinlock_ticket_locked(struct ck_spinlock_ticket * ticket)87*1fb62fb0SOlivier Houchard ck_spinlock_ticket_locked(struct ck_spinlock_ticket *ticket)
88*1fb62fb0SOlivier Houchard {
89*1fb62fb0SOlivier Houchard 	CK_SPINLOCK_TICKET_TYPE request, position;
90*1fb62fb0SOlivier Houchard 
91*1fb62fb0SOlivier Houchard 	request = CK_SPINLOCK_TICKET_LOAD(&ticket->value);
92*1fb62fb0SOlivier Houchard 	position = request & CK_SPINLOCK_TICKET_MASK;
93*1fb62fb0SOlivier Houchard 	request >>= CK_SPINLOCK_TICKET_SHIFT;
94*1fb62fb0SOlivier Houchard 
95*1fb62fb0SOlivier Houchard 	ck_pr_fence_acquire();
96*1fb62fb0SOlivier Houchard 	return request != position;
97*1fb62fb0SOlivier Houchard }
98*1fb62fb0SOlivier Houchard 
99*1fb62fb0SOlivier Houchard CK_CC_INLINE static void
ck_spinlock_ticket_lock(struct ck_spinlock_ticket * ticket)100*1fb62fb0SOlivier Houchard ck_spinlock_ticket_lock(struct ck_spinlock_ticket *ticket)
101*1fb62fb0SOlivier Houchard {
102*1fb62fb0SOlivier Houchard 	CK_SPINLOCK_TICKET_TYPE request, position;
103*1fb62fb0SOlivier Houchard 
104*1fb62fb0SOlivier Houchard 	/* Get our ticket number and set next ticket number. */
105*1fb62fb0SOlivier Houchard 	request = CK_SPINLOCK_TICKET_FAA(&ticket->value,
106*1fb62fb0SOlivier Houchard 	    CK_SPINLOCK_TICKET_INCREMENT);
107*1fb62fb0SOlivier Houchard 
108*1fb62fb0SOlivier Houchard 	position = request & CK_SPINLOCK_TICKET_MASK;
109*1fb62fb0SOlivier Houchard 	request >>= CK_SPINLOCK_TICKET_SHIFT;
110*1fb62fb0SOlivier Houchard 
111*1fb62fb0SOlivier Houchard 	while (request != position) {
112*1fb62fb0SOlivier Houchard 		ck_pr_stall();
113*1fb62fb0SOlivier Houchard 		position = CK_SPINLOCK_TICKET_LOAD(&ticket->value) &
114*1fb62fb0SOlivier Houchard 		    CK_SPINLOCK_TICKET_MASK;
115*1fb62fb0SOlivier Houchard 	}
116*1fb62fb0SOlivier Houchard 
117*1fb62fb0SOlivier Houchard 	ck_pr_fence_lock();
118*1fb62fb0SOlivier Houchard 	return;
119*1fb62fb0SOlivier Houchard }
120*1fb62fb0SOlivier Houchard 
121*1fb62fb0SOlivier Houchard CK_CC_INLINE static void
ck_spinlock_ticket_lock_pb(struct ck_spinlock_ticket * ticket,unsigned int c)122*1fb62fb0SOlivier Houchard ck_spinlock_ticket_lock_pb(struct ck_spinlock_ticket *ticket, unsigned int c)
123*1fb62fb0SOlivier Houchard {
124*1fb62fb0SOlivier Houchard 	CK_SPINLOCK_TICKET_TYPE request, position;
125*1fb62fb0SOlivier Houchard 	ck_backoff_t backoff;
126*1fb62fb0SOlivier Houchard 
127*1fb62fb0SOlivier Houchard 	/* Get our ticket number and set next ticket number. */
128*1fb62fb0SOlivier Houchard 	request = CK_SPINLOCK_TICKET_FAA(&ticket->value,
129*1fb62fb0SOlivier Houchard 	    CK_SPINLOCK_TICKET_INCREMENT);
130*1fb62fb0SOlivier Houchard 
131*1fb62fb0SOlivier Houchard 	position = request & CK_SPINLOCK_TICKET_MASK;
132*1fb62fb0SOlivier Houchard 	request >>= CK_SPINLOCK_TICKET_SHIFT;
133*1fb62fb0SOlivier Houchard 
134*1fb62fb0SOlivier Houchard 	while (request != position) {
135*1fb62fb0SOlivier Houchard 		ck_pr_stall();
136*1fb62fb0SOlivier Houchard 		position = CK_SPINLOCK_TICKET_LOAD(&ticket->value) &
137*1fb62fb0SOlivier Houchard 		    CK_SPINLOCK_TICKET_MASK;
138*1fb62fb0SOlivier Houchard 
139*1fb62fb0SOlivier Houchard 		backoff = (request - position) & CK_SPINLOCK_TICKET_MASK;
140*1fb62fb0SOlivier Houchard 		backoff <<= c;
141*1fb62fb0SOlivier Houchard 		ck_backoff_eb(&backoff);
142*1fb62fb0SOlivier Houchard 	}
143*1fb62fb0SOlivier Houchard 
144*1fb62fb0SOlivier Houchard 	ck_pr_fence_lock();
145*1fb62fb0SOlivier Houchard 	return;
146*1fb62fb0SOlivier Houchard }
147*1fb62fb0SOlivier Houchard 
148*1fb62fb0SOlivier Houchard CK_CC_INLINE static bool
ck_spinlock_ticket_trylock(struct ck_spinlock_ticket * ticket)149*1fb62fb0SOlivier Houchard ck_spinlock_ticket_trylock(struct ck_spinlock_ticket *ticket)
150*1fb62fb0SOlivier Houchard {
151*1fb62fb0SOlivier Houchard 	CK_SPINLOCK_TICKET_TYPE snapshot, request, position;
152*1fb62fb0SOlivier Houchard 
153*1fb62fb0SOlivier Houchard 	snapshot = CK_SPINLOCK_TICKET_LOAD(&ticket->value);
154*1fb62fb0SOlivier Houchard 	position = snapshot & CK_SPINLOCK_TICKET_MASK;
155*1fb62fb0SOlivier Houchard 	request = snapshot >> CK_SPINLOCK_TICKET_SHIFT;
156*1fb62fb0SOlivier Houchard 
157*1fb62fb0SOlivier Houchard 	if (position != request)
158*1fb62fb0SOlivier Houchard 		return false;
159*1fb62fb0SOlivier Houchard 
160*1fb62fb0SOlivier Houchard 	if (CK_SPINLOCK_TICKET_CAS(&ticket->value,
161*1fb62fb0SOlivier Houchard 	    snapshot, snapshot + CK_SPINLOCK_TICKET_INCREMENT) == false) {
162*1fb62fb0SOlivier Houchard 		return false;
163*1fb62fb0SOlivier Houchard 	}
164*1fb62fb0SOlivier Houchard 
165*1fb62fb0SOlivier Houchard 	ck_pr_fence_lock();
166*1fb62fb0SOlivier Houchard 	return true;
167*1fb62fb0SOlivier Houchard }
168*1fb62fb0SOlivier Houchard 
169*1fb62fb0SOlivier Houchard CK_CC_INLINE static void
ck_spinlock_ticket_unlock(struct ck_spinlock_ticket * ticket)170*1fb62fb0SOlivier Houchard ck_spinlock_ticket_unlock(struct ck_spinlock_ticket *ticket)
171*1fb62fb0SOlivier Houchard {
172*1fb62fb0SOlivier Houchard 
173*1fb62fb0SOlivier Houchard 	ck_pr_fence_unlock();
174*1fb62fb0SOlivier Houchard 	CK_SPINLOCK_TICKET_INC((CK_SPINLOCK_TICKET_TYPE_BASE *)(void *)&ticket->value);
175*1fb62fb0SOlivier Houchard 	return;
176*1fb62fb0SOlivier Houchard }
177*1fb62fb0SOlivier Houchard 
178*1fb62fb0SOlivier Houchard #undef CK_SPINLOCK_TICKET_TYPE
179*1fb62fb0SOlivier Houchard #undef CK_SPINLOCK_TICKET_TYPE_BASE
180*1fb62fb0SOlivier Houchard #undef CK_SPINLOCK_TICKET_INC
181*1fb62fb0SOlivier Houchard #undef CK_SPINLOCK_TICKET_FAA
182*1fb62fb0SOlivier Houchard #undef CK_SPINLOCK_TICKET_LOAD
183*1fb62fb0SOlivier Houchard #undef CK_SPINLOCK_TICKET_INCREMENT
184*1fb62fb0SOlivier Houchard #undef CK_SPINLOCK_TICKET_MASK
185*1fb62fb0SOlivier Houchard #undef CK_SPINLOCK_TICKET_SHIFT
186*1fb62fb0SOlivier Houchard #else
187*1fb62fb0SOlivier Houchard /*
188*1fb62fb0SOlivier Houchard  * MESI benefits from cacheline padding between next and current. This avoids
189*1fb62fb0SOlivier Houchard  * invalidation of current from the cache due to incoming lock requests.
190*1fb62fb0SOlivier Houchard  */
191*1fb62fb0SOlivier Houchard struct ck_spinlock_ticket {
192*1fb62fb0SOlivier Houchard 	unsigned int next;
193*1fb62fb0SOlivier Houchard 	unsigned int position;
194*1fb62fb0SOlivier Houchard };
195*1fb62fb0SOlivier Houchard typedef struct ck_spinlock_ticket ck_spinlock_ticket_t;
196*1fb62fb0SOlivier Houchard 
197*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_TICKET_INITIALIZER {.next = 0, .position = 0}
198*1fb62fb0SOlivier Houchard 
199*1fb62fb0SOlivier Houchard CK_CC_INLINE static void
ck_spinlock_ticket_init(struct ck_spinlock_ticket * ticket)200*1fb62fb0SOlivier Houchard ck_spinlock_ticket_init(struct ck_spinlock_ticket *ticket)
201*1fb62fb0SOlivier Houchard {
202*1fb62fb0SOlivier Houchard 
203*1fb62fb0SOlivier Houchard 	ticket->next = 0;
204*1fb62fb0SOlivier Houchard 	ticket->position = 0;
205*1fb62fb0SOlivier Houchard 	ck_pr_barrier();
206*1fb62fb0SOlivier Houchard 
207*1fb62fb0SOlivier Houchard 	return;
208*1fb62fb0SOlivier Houchard }
209*1fb62fb0SOlivier Houchard 
210*1fb62fb0SOlivier Houchard CK_CC_INLINE static bool
ck_spinlock_ticket_locked(struct ck_spinlock_ticket * ticket)211*1fb62fb0SOlivier Houchard ck_spinlock_ticket_locked(struct ck_spinlock_ticket *ticket)
212*1fb62fb0SOlivier Houchard {
213*1fb62fb0SOlivier Houchard 	bool r;
214*1fb62fb0SOlivier Houchard 
215*1fb62fb0SOlivier Houchard 	r = ck_pr_load_uint(&ticket->position) !=
216*1fb62fb0SOlivier Houchard 	    ck_pr_load_uint(&ticket->next);
217*1fb62fb0SOlivier Houchard 	ck_pr_fence_acquire();
218*1fb62fb0SOlivier Houchard 	return r;
219*1fb62fb0SOlivier Houchard }
220*1fb62fb0SOlivier Houchard 
221*1fb62fb0SOlivier Houchard CK_CC_INLINE static void
ck_spinlock_ticket_lock(struct ck_spinlock_ticket * ticket)222*1fb62fb0SOlivier Houchard ck_spinlock_ticket_lock(struct ck_spinlock_ticket *ticket)
223*1fb62fb0SOlivier Houchard {
224*1fb62fb0SOlivier Houchard 	unsigned int request;
225*1fb62fb0SOlivier Houchard 
226*1fb62fb0SOlivier Houchard 	/* Get our ticket number and set next ticket number. */
227*1fb62fb0SOlivier Houchard 	request = ck_pr_faa_uint(&ticket->next, 1);
228*1fb62fb0SOlivier Houchard 
229*1fb62fb0SOlivier Houchard 	/*
230*1fb62fb0SOlivier Houchard 	 * Busy-wait until our ticket number is current.
231*1fb62fb0SOlivier Houchard 	 * We can get away without a fence here assuming
232*1fb62fb0SOlivier Houchard 	 * our position counter does not overflow.
233*1fb62fb0SOlivier Houchard 	 */
234*1fb62fb0SOlivier Houchard 	while (ck_pr_load_uint(&ticket->position) != request)
235*1fb62fb0SOlivier Houchard 		ck_pr_stall();
236*1fb62fb0SOlivier Houchard 
237*1fb62fb0SOlivier Houchard 	ck_pr_fence_lock();
238*1fb62fb0SOlivier Houchard 	return;
239*1fb62fb0SOlivier Houchard }
240*1fb62fb0SOlivier Houchard 
241*1fb62fb0SOlivier Houchard CK_CC_INLINE static void
ck_spinlock_ticket_lock_pb(struct ck_spinlock_ticket * ticket,unsigned int c)242*1fb62fb0SOlivier Houchard ck_spinlock_ticket_lock_pb(struct ck_spinlock_ticket *ticket, unsigned int c)
243*1fb62fb0SOlivier Houchard {
244*1fb62fb0SOlivier Houchard 	ck_backoff_t backoff;
245*1fb62fb0SOlivier Houchard 	unsigned int request, position;
246*1fb62fb0SOlivier Houchard 
247*1fb62fb0SOlivier Houchard 	request = ck_pr_faa_uint(&ticket->next, 1);
248*1fb62fb0SOlivier Houchard 
249*1fb62fb0SOlivier Houchard 	for (;;) {
250*1fb62fb0SOlivier Houchard 		position = ck_pr_load_uint(&ticket->position);
251*1fb62fb0SOlivier Houchard 		if (position == request)
252*1fb62fb0SOlivier Houchard 			break;
253*1fb62fb0SOlivier Houchard 
254*1fb62fb0SOlivier Houchard 		backoff = request - position;
255*1fb62fb0SOlivier Houchard 		backoff <<= c;
256*1fb62fb0SOlivier Houchard 
257*1fb62fb0SOlivier Houchard 		/*
258*1fb62fb0SOlivier Houchard 		 * Ideally, back-off from generating cache traffic for at least
259*1fb62fb0SOlivier Houchard 		 * the amount of time necessary for the number of pending lock
260*1fb62fb0SOlivier Houchard 		 * acquisition and relinquish operations (assuming an empty
261*1fb62fb0SOlivier Houchard 		 * critical section).
262*1fb62fb0SOlivier Houchard 		 */
263*1fb62fb0SOlivier Houchard 		ck_backoff_eb(&backoff);
264*1fb62fb0SOlivier Houchard 	}
265*1fb62fb0SOlivier Houchard 
266*1fb62fb0SOlivier Houchard 	ck_pr_fence_lock();
267*1fb62fb0SOlivier Houchard 	return;
268*1fb62fb0SOlivier Houchard }
269*1fb62fb0SOlivier Houchard 
270*1fb62fb0SOlivier Houchard CK_CC_INLINE static void
ck_spinlock_ticket_unlock(struct ck_spinlock_ticket * ticket)271*1fb62fb0SOlivier Houchard ck_spinlock_ticket_unlock(struct ck_spinlock_ticket *ticket)
272*1fb62fb0SOlivier Houchard {
273*1fb62fb0SOlivier Houchard 	unsigned int update;
274*1fb62fb0SOlivier Houchard 
275*1fb62fb0SOlivier Houchard 	ck_pr_fence_unlock();
276*1fb62fb0SOlivier Houchard 
277*1fb62fb0SOlivier Houchard 	/*
278*1fb62fb0SOlivier Houchard 	 * Update current ticket value so next lock request can proceed.
279*1fb62fb0SOlivier Houchard 	 * Overflow behavior is assumed to be roll-over, in which case,
280*1fb62fb0SOlivier Houchard 	 * it is only an issue if there are 2^32 pending lock requests.
281*1fb62fb0SOlivier Houchard 	 */
282*1fb62fb0SOlivier Houchard 	update = ck_pr_load_uint(&ticket->position);
283*1fb62fb0SOlivier Houchard 	ck_pr_store_uint(&ticket->position, update + 1);
284*1fb62fb0SOlivier Houchard 	return;
285*1fb62fb0SOlivier Houchard }
286*1fb62fb0SOlivier Houchard #endif /* !CK_F_SPINLOCK_TICKET_TRYLOCK */
287*1fb62fb0SOlivier Houchard 
288*1fb62fb0SOlivier Houchard CK_ELIDE_PROTOTYPE(ck_spinlock_ticket, ck_spinlock_ticket_t,
289*1fb62fb0SOlivier Houchard     ck_spinlock_ticket_locked, ck_spinlock_ticket_lock,
290*1fb62fb0SOlivier Houchard     ck_spinlock_ticket_locked, ck_spinlock_ticket_unlock)
291*1fb62fb0SOlivier Houchard 
292*1fb62fb0SOlivier Houchard CK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock_ticket, ck_spinlock_ticket_t,
293*1fb62fb0SOlivier Houchard     ck_spinlock_ticket_locked, ck_spinlock_ticket_trylock)
294*1fb62fb0SOlivier Houchard 
295*1fb62fb0SOlivier Houchard #endif /* CK_F_SPINLOCK_TICKET */
296*1fb62fb0SOlivier Houchard #endif /* CK_SPINLOCK_TICKET_H */
297