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 643