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.

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

mercurial