netwerk/sctp/src/netinet/sctp_process_lock.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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__
    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  */
    49 #ifdef SCTP_PER_SOCKET_LOCKING
    50 /*
    51  * per socket level locking
    52  */
    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
    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)
    80 /* Lock for INP */
    81 #define SCTP_INP_LOCK_INIT(_inp)
    82 #define SCTP_INP_LOCK_DESTROY(_inp)
    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)
    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)
    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)
   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)
   110 #else
   111 /*
   112  * per tcb level locking
   113  */
   114 #define SCTP_IPI_COUNT_INIT()
   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))
   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))
   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))
   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)
   165 #define SCTP_INP_LOCK_INIT(_inp) \
   166 	InitializeCriticalSection(&(_inp)->inp_mtx)
   168 #define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
   169 	InitializeCriticalSection(&(_inp)->inp_create_mtx)
   171 #define SCTP_INP_LOCK_DESTROY(_inp) \
   172 	DeleteCriticalSection(&(_inp)->inp_mtx)
   174 #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
   175 	DeleteCriticalSection(&(_inp)->inp_create_mtx)
   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)
   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
   189 #define SCTP_INP_RLOCK(_inp)	do { 					\
   190 	EnterCriticalSection(&(_inp)->inp_mtx);			\
   191 } while (0)
   193 #define SCTP_INP_WLOCK(_inp)	do { 					\
   194 	EnterCriticalSection(&(_inp)->inp_mtx);			\
   195 } while (0)
   196 #endif
   199 #define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
   200 	InitializeCriticalSection(&(_tcb)->tcb_send_mtx)
   202 #define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) \
   203 	DeleteCriticalSection(&(_tcb)->tcb_send_mtx)
   205 #define SCTP_TCB_SEND_LOCK(_tcb) do { \
   206 	EnterCriticalSection(&(_tcb)->tcb_send_mtx); \
   207 } while (0)
   209 #define SCTP_TCB_SEND_UNLOCK(_tcb) \
   210 	LeaveCriticalSection(&(_tcb)->tcb_send_mtx)
   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)
   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
   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)
   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  */
   241 #define SCTP_TCB_LOCK_INIT(_tcb) \
   242 	InitializeCriticalSection(&(_tcb)->tcb_mtx)
   244 #define SCTP_TCB_LOCK_DESTROY(_tcb) \
   245 	DeleteCriticalSection(&(_tcb)->tcb_mtx)
   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)
   253 #else
   254 #define SCTP_TCB_LOCK(_tcb)  do {					\
   255 	EnterCriticalSection(&(_tcb)->tcb_mtx);			\
   256 } while (0)
   257 #endif
   259 #define SCTP_TCB_TRYLOCK(_tcb) 	((TryEnterCriticalSection(&(_tcb)->tcb_mtx)))
   261 #define SCTP_TCB_UNLOCK(_tcb)	do {  \
   262 	LeaveCriticalSection(&(_tcb)->tcb_mtx);  \
   263 } while (0)
   265 #define SCTP_TCB_LOCK_ASSERT(_tcb)
   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))
   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))
   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))
   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)
   312 #define SCTP_INP_READ_DESTROY(_inp) \
   313 	(void)pthread_mutex_destroy(&(_inp)->inp_rdata_mtx)
   315 #define SCTP_INP_READ_LOCK(_inp)	do { \
   316 	(void)pthread_mutex_lock(&(_inp)->inp_rdata_mtx);    \
   317 } while (0)
   320 #define SCTP_INP_READ_UNLOCK(_inp) \
   321 	(void)pthread_mutex_unlock(&(_inp)->inp_rdata_mtx)
   323 #define SCTP_INP_LOCK_INIT(_inp) \
   324 	(void)pthread_mutex_init(&(_inp)->inp_mtx, NULL)
   326 #define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
   327 	(void)pthread_mutex_init(&(_inp)->inp_create_mtx, NULL)
   329 #define SCTP_INP_LOCK_DESTROY(_inp) \
   330 	(void)pthread_mutex_destroy(&(_inp)->inp_mtx)
   332 #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
   333 	(void)pthread_mutex_destroy(&(_inp)->inp_create_mtx)
   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)
   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)
   346 #else
   348 #define SCTP_INP_RLOCK(_inp)	do { 					\
   349 	(void)pthread_mutex_lock(&(_inp)->inp_mtx);			\
   350 } while (0)
   352 #define SCTP_INP_WLOCK(_inp)	do { 					\
   353 	(void)pthread_mutex_lock(&(_inp)->inp_mtx);			\
   354 } while (0)
   355 #endif
   358 #define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
   359 	(void)pthread_mutex_init(&(_tcb)->tcb_send_mtx, NULL)
   361 #define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) \
   362 	(void)pthread_mutex_destroy(&(_tcb)->tcb_send_mtx)
   364 #define SCTP_TCB_SEND_LOCK(_tcb) do { \
   365 	(void)pthread_mutex_lock(&(_tcb)->tcb_send_mtx); \
   366 } while (0)
   368 #define SCTP_TCB_SEND_UNLOCK(_tcb) \
   369 	(void)pthread_mutex_unlock(&(_tcb)->tcb_send_mtx)
   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)
   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
   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)
   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  */
   400 #define SCTP_TCB_LOCK_INIT(_tcb) \
   401 	(void)pthread_mutex_init(&(_tcb)->tcb_mtx, NULL)
   403 #define SCTP_TCB_LOCK_DESTROY(_tcb) \
   404 	(void)pthread_mutex_destroy(&(_tcb)->tcb_mtx)
   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)
   412 #else
   413 #define SCTP_TCB_LOCK(_tcb)  do {					\
   414 	(void)pthread_mutex_lock(&(_tcb)->tcb_mtx);			\
   415 } while (0)
   416 #endif
   418 #define SCTP_TCB_TRYLOCK(_tcb) 	(!(pthread_mutex_trylock(&(_tcb)->tcb_mtx)))
   420 #define SCTP_TCB_UNLOCK(_tcb)	(void)pthread_mutex_unlock(&(_tcb)->tcb_mtx)
   422 #define SCTP_TCB_LOCK_ASSERT(_tcb)
   423 #endif
   425 #endif /* SCTP_PER_SOCKET_LOCKING */
   428 /*
   429  * common locks
   430  */
   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 */
   438 /* socket locks */
   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
   462 #define SCTP_STATLOG_INIT_LOCK()
   463 #define SCTP_STATLOG_LOCK()
   464 #define SCTP_STATLOG_UNLOCK()
   465 #define SCTP_STATLOG_DESTROY()
   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))
   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))
   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))
   489 /* iterator locks */
   490 #define SCTP_ITERATOR_LOCK_INIT() \
   491 	InitializeCriticalSection(&sctp_it_ctl.it_mtx)
   493 #define SCTP_ITERATOR_LOCK() 						\
   494 	do {								\
   495 		EnterCriticalSection(&sctp_it_ctl.it_mtx);		\
   496 	} while (0)
   498 #define SCTP_ITERATOR_UNLOCK() \
   499 	LeaveCriticalSection(&sctp_it_ctl.it_mtx)
   501 #define SCTP_ITERATOR_LOCK_DESTROY() \
   502 	DeleteCriticalSection(&sctp_it_ctl.it_mtx)
   505 #define SCTP_IPI_ITERATOR_WQ_INIT() \
   506 	InitializeCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
   508 #define SCTP_IPI_ITERATOR_WQ_DESTROY() \
   509 	DeleteCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
   511 #define SCTP_IPI_ITERATOR_WQ_LOCK() \
   512 	do { \
   513 		EnterCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx); \
   514 	} while (0)
   516 #define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
   517 	LeaveCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
   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))
   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))
   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))
   541 /* iterator locks */
   542 #define SCTP_ITERATOR_LOCK_INIT() \
   543 	(void)pthread_mutex_init(&sctp_it_ctl.it_mtx, NULL)
   545 #define SCTP_ITERATOR_LOCK() 						\
   546 	do {								\
   547 		(void)pthread_mutex_lock(&sctp_it_ctl.it_mtx);		\
   548 	} while (0)
   550 #define SCTP_ITERATOR_UNLOCK() \
   551 	(void)pthread_mutex_unlock(&sctp_it_ctl.it_mtx)
   553 #define SCTP_ITERATOR_LOCK_DESTROY() \
   554 	(void)pthread_mutex_destroy(&sctp_it_ctl.it_mtx)
   557 #define SCTP_IPI_ITERATOR_WQ_INIT() \
   558 	(void)pthread_mutex_init(&sctp_it_ctl.ipi_iterator_wq_mtx, NULL)
   560 #define SCTP_IPI_ITERATOR_WQ_DESTROY() \
   561 	(void)pthread_mutex_destroy(&sctp_it_ctl.ipi_iterator_wq_mtx)
   563 #define SCTP_IPI_ITERATOR_WQ_LOCK() \
   564 	do { \
   565 		(void)pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx); \
   566 	} while (0)
   568 #define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
   569 	(void)pthread_mutex_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx)
   570 #endif
   572 #define SCTP_INCR_EP_COUNT() \
   573 	do { \
   574 		atomic_add_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \
   575 	} while (0)
   577 #define SCTP_DECR_EP_COUNT() \
   578 	do { \
   579 	       atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \
   580 	} while (0)
   582 #define SCTP_INCR_ASOC_COUNT() \
   583 	do { \
   584 	       atomic_add_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \
   585 	} while (0)
   587 #define SCTP_DECR_ASOC_COUNT() \
   588 	do { \
   589 	       atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \
   590 	} while (0)
   592 #define SCTP_INCR_LADDR_COUNT() \
   593 	do { \
   594 	       atomic_add_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \
   595 	} while (0)
   597 #define SCTP_DECR_LADDR_COUNT() \
   598 	do { \
   599 	       atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \
   600 	} while (0)
   602 #define SCTP_INCR_RADDR_COUNT() \
   603 	do { \
   604  	       atomic_add_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \
   605 	} while (0)
   607 #define SCTP_DECR_RADDR_COUNT() \
   608 	do { \
   609  	       atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \
   610 	} while (0)
   612 #define SCTP_INCR_CHK_COUNT() \
   613 	do { \
   614   	       atomic_add_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
   615 	} while (0)
   617 #define SCTP_DECR_CHK_COUNT() \
   618 	do { \
   619   	       atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
   620 	} while (0)
   622 #define SCTP_INCR_READQ_COUNT() \
   623 	do { \
   624 	       atomic_add_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \
   625 	} while (0)
   627 #define SCTP_DECR_READQ_COUNT() \
   628 	do { \
   629 	       atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \
   630 	} while (0)
   632 #define SCTP_INCR_STRMOQ_COUNT() \
   633 	do { \
   634 	       atomic_add_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \
   635 	} while (0)
   637 #define SCTP_DECR_STRMOQ_COUNT() \
   638 	do { \
   639 	       atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \
   640 	} while (0)
   642 #endif

mercurial