webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
sctp_process_lock.h
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3  * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
4  * Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * a) Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * b) Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the distribution.
15  *
16  * c) Neither the name of Cisco Systems, Inc. nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 #ifndef __sctp_process_lock_h__
33 #define __sctp_process_lock_h__
34 
35 /*
36  * Need to yet define five atomic fuctions or
37  * their equivalant.
38  * - atomic_add_int(&foo, val) - add atomically the value
39  * - atomic_fetchadd_int(&foo, val) - does same as atomic_add_int
40  * but value it was is returned.
41  * - atomic_subtract_int(&foo, val) - can be made from atomic_add_int()
42  *
43  * - atomic_cmpset_int(&foo, value, newvalue) - Does a set of newvalue
44  * in foo if and only if
45  * foo is value. Returns 0
46  * on success.
47  */
48 
49 #ifdef SCTP_PER_SOCKET_LOCKING
50 /*
51  * per socket level locking
52  */
53 
54 #if defined(__Userspace_os_Windows)
55 /* Lock for INFO stuff */
56 #define SCTP_INP_INFO_LOCK_INIT()
57 #define SCTP_INP_INFO_RLOCK()
58 #define SCTP_INP_INFO_RUNLOCK()
59 #define SCTP_INP_INFO_WLOCK()
60 #define SCTP_INP_INFO_WUNLOCK()
61 #define SCTP_INP_INFO_LOCK_DESTROY()
62 #define SCTP_IPI_COUNT_INIT()
63 #define SCTP_IPI_COUNT_DESTROY()
64 #else
65 #define SCTP_INP_INFO_LOCK_INIT()
66 #define SCTP_INP_INFO_RLOCK()
67 #define SCTP_INP_INFO_RUNLOCK()
68 #define SCTP_INP_INFO_WLOCK()
69 #define SCTP_INP_INFO_WUNLOCK()
70 #define SCTP_INP_INFO_LOCK_DESTROY()
71 #define SCTP_IPI_COUNT_INIT()
72 #define SCTP_IPI_COUNT_DESTROY()
73 #endif
74 
75 #define SCTP_TCB_SEND_LOCK_INIT(_tcb)
76 #define SCTP_TCB_SEND_LOCK_DESTROY(_tcb)
77 #define SCTP_TCB_SEND_LOCK(_tcb)
78 #define SCTP_TCB_SEND_UNLOCK(_tcb)
79 
80 /* Lock for INP */
81 #define SCTP_INP_LOCK_INIT(_inp)
82 #define SCTP_INP_LOCK_DESTROY(_inp)
83 
84 #define SCTP_INP_RLOCK(_inp)
85 #define SCTP_INP_RUNLOCK(_inp)
86 #define SCTP_INP_WLOCK(_inp)
87 #define SCTP_INP_WUNLOCK(_inep)
88 #define SCTP_INP_INCR_REF(_inp)
89 #define SCTP_INP_DECR_REF(_inp)
90 
91 #define SCTP_ASOC_CREATE_LOCK_INIT(_inp)
92 #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp)
93 #define SCTP_ASOC_CREATE_LOCK(_inp)
94 #define SCTP_ASOC_CREATE_UNLOCK(_inp)
95 
96 #define SCTP_INP_READ_INIT(_inp)
97 #define SCTP_INP_READ_DESTROY(_inp)
98 #define SCTP_INP_READ_LOCK(_inp)
99 #define SCTP_INP_READ_UNLOCK(_inp)
100 
101 /* Lock for TCB */
102 #define SCTP_TCB_LOCK_INIT(_tcb)
103 #define SCTP_TCB_LOCK_DESTROY(_tcb)
104 #define SCTP_TCB_LOCK(_tcb)
105 #define SCTP_TCB_TRYLOCK(_tcb) 1
106 #define SCTP_TCB_UNLOCK(_tcb)
107 #define SCTP_TCB_UNLOCK_IFOWNED(_tcb)
108 #define SCTP_TCB_LOCK_ASSERT(_tcb)
109 
110 #else
111 /*
112  * per tcb level locking
113  */
114 #define SCTP_IPI_COUNT_INIT()
115 
116 #if defined(__Userspace_os_Windows)
117 #define SCTP_WQ_ADDR_INIT() \
118  InitializeCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx))
119 #define SCTP_WQ_ADDR_DESTROY() \
120  DeleteCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx))
121 #define SCTP_WQ_ADDR_LOCK() \
122  EnterCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx))
123 #define SCTP_WQ_ADDR_UNLOCK() \
124  LeaveCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx))
125 
126 
127 #define SCTP_INP_INFO_LOCK_INIT() \
128  InitializeCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
129 #define SCTP_INP_INFO_LOCK_DESTROY() \
130  DeleteCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
131 #define SCTP_INP_INFO_RLOCK() \
132  EnterCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
133 #define SCTP_INP_INFO_TRYLOCK() \
134  TryEnterCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
135 #define SCTP_INP_INFO_WLOCK() \
136  EnterCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
137 #define SCTP_INP_INFO_RUNLOCK() \
138  LeaveCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
139 #define SCTP_INP_INFO_WUNLOCK() \
140  LeaveCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
141 
142 #define SCTP_IP_PKTLOG_INIT() \
143  InitializeCriticalSection(&SCTP_BASE_INFO(ipi_pktlog_mtx))
144 #define SCTP_IP_PKTLOG_DESTROY () \
145  DeleteCriticalSection(&SCTP_BASE_INFO(ipi_pktlog_mtx))
146 #define SCTP_IP_PKTLOG_LOCK() \
147  EnterCriticalSection(&SCTP_BASE_INFO(ipi_pktlog_mtx))
148 #define SCTP_IP_PKTLOG_UNLOCK() \
149  LeaveCriticalSection(&SCTP_BASE_INFO(ipi_pktlog_mtx))
150 
151 /*
152  * The INP locks we will use for locking an SCTP endpoint, so for example if
153  * we want to change something at the endpoint level for example random_store
154  * or cookie secrets we lock the INP level.
155  */
156 #define SCTP_INP_READ_INIT(_inp) \
157  InitializeCriticalSection(&(_inp)->inp_rdata_mtx)
158 #define SCTP_INP_READ_DESTROY(_inp) \
159  DeleteCriticalSection(&(_inp)->inp_rdata_mtx)
160 #define SCTP_INP_READ_LOCK(_inp) \
161  EnterCriticalSection(&(_inp)->inp_rdata_mtx)
162 #define SCTP_INP_READ_UNLOCK(_inp) \
163  LeaveCriticalSection(&(_inp)->inp_rdata_mtx)
164 
165 #define SCTP_INP_LOCK_INIT(_inp) \
166  InitializeCriticalSection(&(_inp)->inp_mtx)
167 
168 #define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
169  InitializeCriticalSection(&(_inp)->inp_create_mtx)
170 
171 #define SCTP_INP_LOCK_DESTROY(_inp) \
172  DeleteCriticalSection(&(_inp)->inp_mtx)
173 
174 #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
175  DeleteCriticalSection(&(_inp)->inp_create_mtx)
176 
177 #ifdef SCTP_LOCK_LOGGING
178 #define SCTP_INP_RLOCK(_inp) do { \
179  if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\
180  EnterCriticalSection(&(_inp)->inp_mtx); \
181 } while (0)
182 
183 #define SCTP_INP_WLOCK(_inp) do { \
184  sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\
185  EnterCriticalSection(&(_inp)->inp_mtx); \
186 } while (0)
187 #else
188 
189 #define SCTP_INP_RLOCK(_inp) do { \
190  EnterCriticalSection(&(_inp)->inp_mtx); \
191 } while (0)
192 
193 #define SCTP_INP_WLOCK(_inp) do { \
194  EnterCriticalSection(&(_inp)->inp_mtx); \
195 } while (0)
196 #endif
197 
198 
199 #define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
200  InitializeCriticalSection(&(_tcb)->tcb_send_mtx)
201 
202 #define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) \
203  DeleteCriticalSection(&(_tcb)->tcb_send_mtx)
204 
205 #define SCTP_TCB_SEND_LOCK(_tcb) do { \
206  EnterCriticalSection(&(_tcb)->tcb_send_mtx); \
207 } while (0)
208 
209 #define SCTP_TCB_SEND_UNLOCK(_tcb) \
210  LeaveCriticalSection(&(_tcb)->tcb_send_mtx)
211 
212 #define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1)
213 #define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1)
214 
215 #ifdef SCTP_LOCK_LOGGING
216 #define SCTP_ASOC_CREATE_LOCK(_inp) do { \
217  if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_CREATE); \
218  EnterCriticalSection(&(_inp)->inp_create_mtx); \
219 } while (0)
220 #else
221 #define SCTP_ASOC_CREATE_LOCK(_inp) do { \
222  EnterCriticalSection(&(_inp)->inp_create_mtx); \
223 } while (0)
224 #endif
225 
226 #define SCTP_INP_RUNLOCK(_inp) \
227  LeaveCriticalSection(&(_inp)->inp_mtx)
228 #define SCTP_INP_WUNLOCK(_inp) \
229  LeaveCriticalSection(&(_inp)->inp_mtx)
230 #define SCTP_ASOC_CREATE_UNLOCK(_inp) \
231  LeaveCriticalSection(&(_inp)->inp_create_mtx)
232 
233 /*
234  * For the majority of things (once we have found the association) we will
235  * lock the actual association mutex. This will protect all the assoiciation
236  * level queues and streams and such. We will need to lock the socket layer
237  * when we stuff data up into the receiving sb_mb. I.e. we will need to do an
238  * extra SOCKBUF_LOCK(&so->so_rcv) even though the association is locked.
239  */
240 
241 #define SCTP_TCB_LOCK_INIT(_tcb) \
242  InitializeCriticalSection(&(_tcb)->tcb_mtx)
243 
244 #define SCTP_TCB_LOCK_DESTROY(_tcb) \
245  DeleteCriticalSection(&(_tcb)->tcb_mtx)
246 
247 #ifdef SCTP_LOCK_LOGGING
248 #define SCTP_TCB_LOCK(_tcb) do { \
249  if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \
250  EnterCriticalSection(&(_tcb)->tcb_mtx); \
251 } while (0)
252 
253 #else
254 #define SCTP_TCB_LOCK(_tcb) do { \
255  EnterCriticalSection(&(_tcb)->tcb_mtx); \
256 } while (0)
257 #endif
258 
259 #define SCTP_TCB_TRYLOCK(_tcb) ((TryEnterCriticalSection(&(_tcb)->tcb_mtx)))
260 
261 #define SCTP_TCB_UNLOCK(_tcb) do { \
262  LeaveCriticalSection(&(_tcb)->tcb_mtx); \
263 } while (0)
264 
265 #define SCTP_TCB_LOCK_ASSERT(_tcb)
266 
267 #else /* all Userspaces except Windows */
268 #define SCTP_WQ_ADDR_INIT() \
269  (void)pthread_mutex_init(&SCTP_BASE_INFO(wq_addr_mtx), NULL)
270 #define SCTP_WQ_ADDR_DESTROY() \
271  (void)pthread_mutex_destroy(&SCTP_BASE_INFO(wq_addr_mtx))
272 #define SCTP_WQ_ADDR_LOCK() \
273  (void)pthread_mutex_lock(&SCTP_BASE_INFO(wq_addr_mtx))
274 #define SCTP_WQ_ADDR_UNLOCK() \
275  (void)pthread_mutex_unlock(&SCTP_BASE_INFO(wq_addr_mtx))
276 
277 
278 #define SCTP_INP_INFO_LOCK_INIT() \
279  (void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_ep_mtx), NULL)
280 #define SCTP_INP_INFO_LOCK_DESTROY() \
281  (void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_ep_mtx))
282 #define SCTP_INP_INFO_RLOCK() \
283  (void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx))
284 #define SCTP_INP_INFO_TRYLOCK() \
285  (!(pthread_mutex_trylock(&SCTP_BASE_INFO(ipi_ep_mtx))))
286 #define SCTP_INP_INFO_WLOCK() \
287  (void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx))
288 #define SCTP_INP_INFO_RUNLOCK() \
289  (void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx))
290 #define SCTP_INP_INFO_WUNLOCK() \
291  (void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx))
292 
293 #define SCTP_IP_PKTLOG_INIT() \
294  (void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_pktlog_mtx), NULL)
295 #define SCTP_IP_PKTLOG_DESTROY() \
296  (void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_pktlog_mtx))
297 #define SCTP_IP_PKTLOG_LOCK() \
298  (void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_pktlog_mtx))
299 #define SCTP_IP_PKTLOG_UNLOCK() \
300  (void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_pktlog_mtx))
301 
302 
303 
304 /*
305  * The INP locks we will use for locking an SCTP endpoint, so for example if
306  * we want to change something at the endpoint level for example random_store
307  * or cookie secrets we lock the INP level.
308  */
309 #define SCTP_INP_READ_INIT(_inp) \
310  (void)pthread_mutex_init(&(_inp)->inp_rdata_mtx, NULL)
311 
312 #define SCTP_INP_READ_DESTROY(_inp) \
313  (void)pthread_mutex_destroy(&(_inp)->inp_rdata_mtx)
314 
315 #define SCTP_INP_READ_LOCK(_inp) do { \
316  (void)pthread_mutex_lock(&(_inp)->inp_rdata_mtx); \
317 } while (0)
318 
319 
320 #define SCTP_INP_READ_UNLOCK(_inp) \
321  (void)pthread_mutex_unlock(&(_inp)->inp_rdata_mtx)
322 
323 #define SCTP_INP_LOCK_INIT(_inp) \
324  (void)pthread_mutex_init(&(_inp)->inp_mtx, NULL)
325 
326 #define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
327  (void)pthread_mutex_init(&(_inp)->inp_create_mtx, NULL)
328 
329 #define SCTP_INP_LOCK_DESTROY(_inp) \
330  (void)pthread_mutex_destroy(&(_inp)->inp_mtx)
331 
332 #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
333  (void)pthread_mutex_destroy(&(_inp)->inp_create_mtx)
334 
335 #ifdef SCTP_LOCK_LOGGING
336 #define SCTP_INP_RLOCK(_inp) do { \
337  if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\
338  (void)pthread_mutex_lock(&(_inp)->inp_mtx); \
339 } while (0)
340 
341 #define SCTP_INP_WLOCK(_inp) do { \
342  sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\
343  (void)pthread_mutex_lock(&(_inp)->inp_mtx); \
344 } while (0)
345 
346 #else
347 
348 #define SCTP_INP_RLOCK(_inp) do { \
349  (void)pthread_mutex_lock(&(_inp)->inp_mtx); \
350 } while (0)
351 
352 #define SCTP_INP_WLOCK(_inp) do { \
353  (void)pthread_mutex_lock(&(_inp)->inp_mtx); \
354 } while (0)
355 #endif
356 
357 
358 #define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
359  (void)pthread_mutex_init(&(_tcb)->tcb_send_mtx, NULL)
360 
361 #define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) \
362  (void)pthread_mutex_destroy(&(_tcb)->tcb_send_mtx)
363 
364 #define SCTP_TCB_SEND_LOCK(_tcb) do { \
365  (void)pthread_mutex_lock(&(_tcb)->tcb_send_mtx); \
366 } while (0)
367 
368 #define SCTP_TCB_SEND_UNLOCK(_tcb) \
369  (void)pthread_mutex_unlock(&(_tcb)->tcb_send_mtx)
370 
371 #define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1)
372 #define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1)
373 
374 #ifdef SCTP_LOCK_LOGGING
375 #define SCTP_ASOC_CREATE_LOCK(_inp) do { \
376  if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_CREATE); \
377  (void)pthread_mutex_lock(&(_inp)->inp_create_mtx); \
378 } while (0)
379 #else
380 #define SCTP_ASOC_CREATE_LOCK(_inp) do { \
381  (void)pthread_mutex_lock(&(_inp)->inp_create_mtx); \
382 } while (0)
383 #endif
384 
385 #define SCTP_INP_RUNLOCK(_inp) \
386  (void)pthread_mutex_unlock(&(_inp)->inp_mtx)
387 #define SCTP_INP_WUNLOCK(_inp) \
388  (void)pthread_mutex_unlock(&(_inp)->inp_mtx)
389 #define SCTP_ASOC_CREATE_UNLOCK(_inp) \
390  (void)pthread_mutex_unlock(&(_inp)->inp_create_mtx)
391 
392 /*
393  * For the majority of things (once we have found the association) we will
394  * lock the actual association mutex. This will protect all the assoiciation
395  * level queues and streams and such. We will need to lock the socket layer
396  * when we stuff data up into the receiving sb_mb. I.e. we will need to do an
397  * extra SOCKBUF_LOCK(&so->so_rcv) even though the association is locked.
398  */
399 
400 #define SCTP_TCB_LOCK_INIT(_tcb) \
401  (void)pthread_mutex_init(&(_tcb)->tcb_mtx, NULL)
402 
403 #define SCTP_TCB_LOCK_DESTROY(_tcb) \
404  (void)pthread_mutex_destroy(&(_tcb)->tcb_mtx)
405 
406 #ifdef SCTP_LOCK_LOGGING
407 #define SCTP_TCB_LOCK(_tcb) do { \
408  if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \
409  (void)pthread_mutex_lock(&(_tcb)->tcb_mtx); \
410 } while (0)
411 
412 #else
413 #define SCTP_TCB_LOCK(_tcb) do { \
414  (void)pthread_mutex_lock(&(_tcb)->tcb_mtx); \
415 } while (0)
416 #endif
417 
418 #define SCTP_TCB_TRYLOCK(_tcb) (!(pthread_mutex_trylock(&(_tcb)->tcb_mtx)))
419 
420 #define SCTP_TCB_UNLOCK(_tcb) (void)pthread_mutex_unlock(&(_tcb)->tcb_mtx)
421 
422 #define SCTP_TCB_LOCK_ASSERT(_tcb)
423 #endif
424 
425 #endif /* SCTP_PER_SOCKET_LOCKING */
426 
427 
428 /*
429  * common locks
430  */
431 
432 /* copied over to compile */
433 #define SCTP_INP_LOCK_CONTENDED(_inp) (0) /* Don't know if this is possible */
434 #define SCTP_INP_READ_CONTENDED(_inp) (0) /* Don't know if this is possible */
435 #define SCTP_ASOC_CREATE_LOCK_CONTENDED(_inp) (0) /* Don't know if this is possible */
436 
437 
438 /* socket locks */
439 
440 #if defined(__Userspace__)
441 #if defined(__Userspace_os_Windows)
442 #define SOCKBUF_LOCK_ASSERT(_so_buf)
443 #define SOCKBUF_LOCK(_so_buf) EnterCriticalSection(&(_so_buf)->sb_mtx)
444 #define SOCKBUF_UNLOCK(_so_buf) LeaveCriticalSection(&(_so_buf)->sb_mtx)
445 #define SOCK_LOCK(_so) SOCKBUF_LOCK(&(_so)->so_rcv)
446 #define SOCK_UNLOCK(_so) SOCKBUF_UNLOCK(&(_so)->so_rcv)
447 #else
448 #define SOCKBUF_LOCK_ASSERT(_so_buf) KASSERT(pthread_mutex_trylock(SOCKBUF_MTX(_so_buf)) == EBUSY, ("%s: socket buffer not locked", __func__))
449 #define SOCKBUF_LOCK(_so_buf) pthread_mutex_lock(SOCKBUF_MTX(_so_buf))
450 #define SOCKBUF_UNLOCK(_so_buf) pthread_mutex_unlock(SOCKBUF_MTX(_so_buf))
451 #define SOCK_LOCK(_so) SOCKBUF_LOCK(&(_so)->so_rcv)
452 #define SOCK_UNLOCK(_so) SOCKBUF_UNLOCK(&(_so)->so_rcv)
453 #endif
454 #else
455 #define SOCK_LOCK(_so)
456 #define SOCK_UNLOCK(_so)
457 #define SOCKBUF_LOCK(_so_buf)
458 #define SOCKBUF_UNLOCK(_so_buf)
459 #define SOCKBUF_LOCK_ASSERT(_so_buf)
460 #endif
461 
462 #define SCTP_STATLOG_INIT_LOCK()
463 #define SCTP_STATLOG_LOCK()
464 #define SCTP_STATLOG_UNLOCK()
465 #define SCTP_STATLOG_DESTROY()
466 
467 #if defined(__Userspace_os_Windows)
468 /* address list locks */
469 #define SCTP_IPI_ADDR_INIT() \
470  InitializeCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
471 #define SCTP_IPI_ADDR_DESTROY() \
472  DeleteCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
473 
474 #define SCTP_IPI_ADDR_RLOCK() \
475  do { \
476  EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx)); \
477  } while (0)
478 #define SCTP_IPI_ADDR_RUNLOCK() \
479  LeaveCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
480 
481 #define SCTP_IPI_ADDR_WLOCK() \
482  do { \
483  EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx)); \
484  } while (0)
485 #define SCTP_IPI_ADDR_WUNLOCK() \
486  LeaveCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
487 
488 
489 /* iterator locks */
490 #define SCTP_ITERATOR_LOCK_INIT() \
491  InitializeCriticalSection(&sctp_it_ctl.it_mtx)
492 
493 #define SCTP_ITERATOR_LOCK() \
494  do { \
495  EnterCriticalSection(&sctp_it_ctl.it_mtx); \
496  } while (0)
497 
498 #define SCTP_ITERATOR_UNLOCK() \
499  LeaveCriticalSection(&sctp_it_ctl.it_mtx)
500 
501 #define SCTP_ITERATOR_LOCK_DESTROY() \
502  DeleteCriticalSection(&sctp_it_ctl.it_mtx)
503 
504 
505 #define SCTP_IPI_ITERATOR_WQ_INIT() \
506  InitializeCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
507 
508 #define SCTP_IPI_ITERATOR_WQ_DESTROY() \
509  DeleteCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
510 
511 #define SCTP_IPI_ITERATOR_WQ_LOCK() \
512  do { \
513  EnterCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx); \
514  } while (0)
515 
516 #define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
517  LeaveCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
518 
519 #else /* end of __Userspace_os_Windows */
520 /* address list locks */
521 #define SCTP_IPI_ADDR_INIT() \
522  (void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_addr_mtx), NULL)
523 #define SCTP_IPI_ADDR_DESTROY() \
524  (void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_addr_mtx))
525 
526 #define SCTP_IPI_ADDR_RLOCK() \
527  do { \
528  (void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)); \
529  } while (0)
530 #define SCTP_IPI_ADDR_RUNLOCK() \
531  (void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx))
532 
533 #define SCTP_IPI_ADDR_WLOCK() \
534  do { \
535  (void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)); \
536  } while (0)
537 #define SCTP_IPI_ADDR_WUNLOCK() \
538  (void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx))
539 
540 
541 /* iterator locks */
542 #define SCTP_ITERATOR_LOCK_INIT() \
543  (void)pthread_mutex_init(&sctp_it_ctl.it_mtx, NULL)
544 
545 #define SCTP_ITERATOR_LOCK() \
546  do { \
547  (void)pthread_mutex_lock(&sctp_it_ctl.it_mtx); \
548  } while (0)
549 
550 #define SCTP_ITERATOR_UNLOCK() \
551  (void)pthread_mutex_unlock(&sctp_it_ctl.it_mtx)
552 
553 #define SCTP_ITERATOR_LOCK_DESTROY() \
554  (void)pthread_mutex_destroy(&sctp_it_ctl.it_mtx)
555 
556 
557 #define SCTP_IPI_ITERATOR_WQ_INIT() \
558  (void)pthread_mutex_init(&sctp_it_ctl.ipi_iterator_wq_mtx, NULL)
559 
560 #define SCTP_IPI_ITERATOR_WQ_DESTROY() \
561  (void)pthread_mutex_destroy(&sctp_it_ctl.ipi_iterator_wq_mtx)
562 
563 #define SCTP_IPI_ITERATOR_WQ_LOCK() \
564  do { \
565  (void)pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx); \
566  } while (0)
567 
568 #define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
569  (void)pthread_mutex_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx)
570 #endif
571 
572 #define SCTP_INCR_EP_COUNT() \
573  do { \
574  atomic_add_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \
575  } while (0)
576 
577 #define SCTP_DECR_EP_COUNT() \
578  do { \
579  atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \
580  } while (0)
581 
582 #define SCTP_INCR_ASOC_COUNT() \
583  do { \
584  atomic_add_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \
585  } while (0)
586 
587 #define SCTP_DECR_ASOC_COUNT() \
588  do { \
589  atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \
590  } while (0)
591 
592 #define SCTP_INCR_LADDR_COUNT() \
593  do { \
594  atomic_add_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \
595  } while (0)
596 
597 #define SCTP_DECR_LADDR_COUNT() \
598  do { \
599  atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \
600  } while (0)
601 
602 #define SCTP_INCR_RADDR_COUNT() \
603  do { \
604  atomic_add_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \
605  } while (0)
606 
607 #define SCTP_DECR_RADDR_COUNT() \
608  do { \
609  atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \
610  } while (0)
611 
612 #define SCTP_INCR_CHK_COUNT() \
613  do { \
614  atomic_add_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
615  } while (0)
616 
617 #define SCTP_DECR_CHK_COUNT() \
618  do { \
619  atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
620  } while (0)
621 
622 #define SCTP_INCR_READQ_COUNT() \
623  do { \
624  atomic_add_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \
625  } while (0)
626 
627 #define SCTP_DECR_READQ_COUNT() \
628  do { \
629  atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \
630  } while (0)
631 
632 #define SCTP_INCR_STRMOQ_COUNT() \
633  do { \
634  atomic_add_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \
635  } while (0)
636 
637 #define SCTP_DECR_STRMOQ_COUNT() \
638  do { \
639  atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \
640  } while (0)
641 
642 #endif