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