1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME: 80** 81** rpcmutex.h 82** 83** FACILITY: 84** 85** Remote Procedure Call (RPC) 86** 87** ABSTRACT: 88** 89** A veneer over CMA (or anything else for that matter) to assist with 90** mutex and condition variable support for the runtime. This provides 91** some isolation from the underlying mechanisms to allow us to (more) 92** easily slip in alternate facilities, and more importantly add features 93** that we'd like to have in the areas of correctness and debugging 94** of code using these locks as well as statistics gathering. Note 95** that this package contains a "condition variable" veneer as well, 96** since condition variables and mutexes are tightly integrated (i.e. 97** condition variables have an associated mutex). 98** 99** This package provides the following PRIVATE data types and operations: 100** 101** rpc_mutex_t m; 102** rpc_cond_t c; 103** 104** void RPC_MUTEX_INIT(m) 105** void RPC_MUTEX_DELETE(m) 106** void RPC_MUTEX_LOCK(m) 107** void RPC_MUTEX_TRY_LOCK(m,bp) 108** void RPC_MUTEX_UNLOCK(m) 109** void RPC_MUTEX_LOCK_ASSERT(m) 110** void RPC_MUTEX_UNLOCK_ASSERT(m) 111** 112** void RPC_COND_INIT(c,m) 113** void RPC_COND_DELETE(c,m) 114** void RPC_COND_WAIT(c,m) 115** void RPC_COND_TIMED_WAIT(c,m,t) 116** void RPC_COND_SIGNAL(c,m) 117** 118** This code is controlled by debug switch "rpc_e_dbg_mutex". At levels 1 119** or higher, statistics gathering is enabled. At levels 5 or higher, 120** assertion checking, ownership tracking, deadlock detection, etc. are 121** enabled. 122** 123** 124*/ 125 126#ifndef _RPCMUTEX_H 127#define _RPCMUTEX_H 1 128 129/* 130 * The rpc_mutex_t data type. 131 * 132 * If debugging isn't configured, this is just a unadorned mutex, else we adorn 133 * the struct with goodies to enable assertion checking, deadlock detection 134 * and statistics gathering. 135 */ 136 137typedef struct rpc_mutex_stats_t 138{ 139 unsigned32 busy; /* total lock requests when already locked */ 140 unsigned32 lock; /* total locks */ 141 unsigned32 try_lock; /* total try_locks */ 142 unsigned32 unlock; /* total unlocks */ 143 unsigned32 init; /* total inits */ 144 unsigned32 deletes; /* total deletes */ 145 unsigned32 lock_assert; /* total lock_asserts */ 146 unsigned32 unlock_assert; 147} rpc_mutex_stats_t, *rpc_mutex_stats_p_t; 148#define RPC_MUTEX_STATUS_INITIALIZER {0, 0, 0, 0, 0, 0, 0, 0} 149 150typedef struct rpc_mutex_t 151{ 152 dcethread_mutex m; /* the unadorned mutex lock */ 153#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 154 unsigned is_locked:1; /* T=> locked */ 155 dcethread* owner; /* current owner if locked */ 156 char *locker_file; /* last locker */ 157 int locker_line; /* last locker */ 158 rpc_mutex_stats_t stats; 159#endif /* RPC_MUTEX_DEBUG OR RPC_MUTEX_STATS */ 160} rpc_mutex_t, *rpc_mutex_p_t; 161#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 162# define RPC_MUTEX_INITIALIZER {DCETHREAD_MUTEX_INITIALIZER, 0, 0, NULL, 0, RPC_MUTEX_STATUS_INITIALIZER} 163#else 164# define RPC_MUTEX_INITIALIZER {DCETHREAD_MUTEX_INITIALIZER} 165#endif 166 167/* 168 * The rpc_cond_t (condition variable) data type. 169 */ 170 171typedef struct rpc_cond_stats_t 172{ 173 unsigned32 init; /* total inits */ 174 unsigned32 deletes; /* total deletes */ 175 unsigned32 wait; /* total waits */ 176 unsigned32 signals; /* total signals + broadcasts */ 177} rpc_cond_stats_t, *rpc_cond_stats_p_t; 178#define RPC_COND_STATS_INITIALIZER {0, 0, 0, 0} 179 180typedef struct rpc_cond_t 181{ 182 dcethread_cond c; /* the unadorned condition variable */ 183 rpc_mutex_p_t mp; /* the cv's associated mutex */ 184 rpc_cond_stats_t stats; 185} rpc_cond_t, *rpc_cond_p_t; 186#define RPC_COND_INITIALIZER {DCETHREAD_COND_INITIALIZER, NULL, RPC_COND_STATS_INITIALIZER} 187 188/* 189 * Some relatively efficient generic mutex operations that are controllable 190 * at run time as well as compile time. The "real" support routines 191 * can be found in rpcmutex.c . 192 */ 193 194/* 195 * R P C _ M U T E X _ I N I T 196 * 197 * We always need to call the support routine so that the stats, etc 198 * get initialized. 199 */ 200 201#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 202 203# define RPC_MUTEX_INIT(mutex) \ 204 { \ 205 if (! rpc__mutex_init(&(mutex))) \ 206 { \ 207 rpc_dce_svc_printf ( \ 208 __FILE__, __LINE__, \ 209 "%s", \ 210 rpc_svc_mutex, \ 211 svc_c_sev_fatal | svc_c_action_abort, \ 212 rpc_m_call_failed_no_status, \ 213 "RPC_MUTEX_INIT/rpc__mutex_init" ); \ 214 } \ 215 } 216#else 217# define RPC_MUTEX_INIT(mutex) \ 218 { \ 219 RPC_LOG_MUTEX_INIT_NTR; \ 220 dcethread_mutex_init_throw(&(mutex).m, NULL); \ 221 RPC_LOG_MUTEX_INIT_XIT; \ 222 } 223#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 224 225/* 226 * R P C _ M U T E X _ D E L E T E 227 */ 228 229#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 230# define RPC_MUTEX_DELETE(mutex) \ 231 { \ 232 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 233 { \ 234 if (! rpc__mutex_delete(&(mutex))) \ 235 { \ 236 rpc_dce_svc_printf ( \ 237 __FILE__, __LINE__, \ 238 "%s", \ 239 rpc_svc_mutex, \ 240 svc_c_sev_fatal | svc_c_action_abort, \ 241 rpc_m_call_failed_no_status, \ 242 "RPC_MUTEX_DELETE/rpc__mutex_delete" ); \ 243 } \ 244 } else { \ 245 dcethread_mutex_destroy_throw(&(mutex).m); \ 246 } \ 247 } 248#else 249# define RPC_MUTEX_DELETE(mutex) \ 250 { \ 251 RPC_LOG_MUTEX_DELETE_NTR; \ 252 dcethread_mutex_destroy_throw(&(mutex).m); \ 253 RPC_LOG_MUTEX_DELETE_XIT; \ 254 } 255#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 256 257/* 258 * R P C _ M U T E X _ L O C K 259 */ 260 261#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 262 263# define RPC_MUTEX_LOCK(mutex) \ 264 { \ 265 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 266 { \ 267 if (! rpc__mutex_lock(&(mutex), __FILE__, __LINE__)) \ 268 { \ 269 rpc_dce_svc_printf ( \ 270 __FILE__, __LINE__, \ 271 "%s", \ 272 rpc_svc_mutex, \ 273 svc_c_sev_fatal | svc_c_action_abort, \ 274 rpc_m_call_failed_no_status, \ 275 "RPC_MUTEX_LOCK/rpc__mutex_lock" ); \ 276 } \ 277 } else { \ 278 RPC_LOG_MUTEX_LOCK_NTR; \ 279 dcethread_mutex_lock_throw(&(mutex).m); \ 280 RPC_LOG_MUTEX_LOCK_XIT; \ 281 } \ 282 } 283#else 284# define RPC_MUTEX_LOCK(mutex) \ 285 { \ 286 RPC_LOG_MUTEX_LOCK_NTR; \ 287 dcethread_mutex_lock_throw(&(mutex).m); \ 288 RPC_LOG_MUTEX_LOCK_XIT; \ 289 } 290#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 291 292/* 293 * R P C _ M U T E X _ T R Y _ L O C K 294 */ 295 296#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 297 298# define RPC_MUTEX_TRY_LOCK(mutex,bp) \ 299 { \ 300 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 301 { \ 302 if (! rpc__mutex_try_lock(&(mutex), (bp), __FILE__, __LINE__)) \ 303 { \ 304 rpc_dce_svc_printf ( \ 305 __FILE__, __LINE__, \ 306 "%s", \ 307 rpc_svc_mutex, \ 308 svc_c_sev_fatal | svc_c_action_abort, \ 309 rpc_m_call_failed_no_status, \ 310 "RPC_MUTEX_TRY_LOCK/rpc__mutex_try_lock" ); \ 311 } \ 312 } else { \ 313 *(bp) = dcethread_mutex_trylock_throw(&(mutex).m); \ 314 } \ 315 } 316#else 317# define RPC_MUTEX_TRY_LOCK(mutex,bp) \ 318 { \ 319 RPC_LOG_MUTEX_TRY_LOCK_NTR; \ 320 *(bp) = dcethread_mutex_trylock_throw(&(mutex).m); \ 321 RPC_LOG_MUTEX_TRY_LOCK_XIT; \ 322 } 323#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 324 325/* 326 * R P C _ M U T E X _ U N L O C K 327 */ 328 329#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 330 331# define RPC_MUTEX_UNLOCK(mutex) \ 332 { \ 333 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 334 { \ 335 if (! rpc__mutex_unlock(&(mutex))) \ 336 { \ 337 rpc_dce_svc_printf ( \ 338 __FILE__, __LINE__, \ 339 "%s", \ 340 rpc_svc_mutex, \ 341 svc_c_sev_fatal | svc_c_action_abort, \ 342 rpc_m_call_failed_no_status, \ 343 "RPC_MUTEX_UNLOCK/rpc__mutex_unlock" ); \ 344 } \ 345 } else { \ 346 dcethread_mutex_unlock_throw(&(mutex).m); \ 347 } \ 348 } 349#else 350# define RPC_MUTEX_UNLOCK(mutex) \ 351 { \ 352 RPC_LOG_MUTEX_UNLOCK_NTR; \ 353 dcethread_mutex_unlock_throw(&(mutex).m); \ 354 RPC_LOG_MUTEX_UNLOCK_XIT; \ 355 } 356#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 357 358/* 359 * R P C _ M U T E X _ L O C K _ A S S E R T 360 */ 361 362#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 363 364# define RPC_MUTEX_LOCK_ASSERT(mutex) \ 365 { \ 366 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 367 { \ 368 if (! rpc__mutex_lock_assert(&(mutex))) \ 369 { \ 370 rpc_dce_svc_printf ( \ 371 __FILE__, __LINE__, \ 372 "%s", \ 373 rpc_svc_mutex, \ 374 svc_c_sev_fatal | svc_c_action_abort, \ 375 rpc_m_call_failed_no_status, \ 376 "RPC_MUTEX_LOCK_ASSERT/rpc__mutex_lock_assert" ); \ 377 } \ 378 } \ 379 } 380#else 381# define RPC_MUTEX_LOCK_ASSERT(mutex) { } 382#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 383 384/* 385 * R P C _ M U T E X _ U N L O C K _ A S S E R T 386 */ 387 388#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 389 390# define RPC_MUTEX_UNLOCK_ASSERT(mutex) \ 391 { \ 392 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 393 { \ 394 if (! rpc__mutex_unlock_assert(&(mutex))) \ 395 { \ 396 rpc_dce_svc_printf ( \ 397 __FILE__, __LINE__, \ 398 "%s", \ 399 rpc_svc_mutex, \ 400 svc_c_sev_fatal | svc_c_action_abort, \ 401 rpc_m_call_failed_no_status, \ 402 "RPC_MUTEX_UNLOCK_ASSERT/rpc__mutex_unlock_assert" ); \ 403 } \ 404 } \ 405 } 406#else 407# define RPC_MUTEX_UNLOCK_ASSERT(mutex) { } 408#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 409 410/* 411 * R P C _ C O N D _ I N I T 412 */ 413 414#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 415 416# define RPC_COND_INIT(cond,mutex) \ 417 { \ 418 if (! rpc__cond_init(&(cond), &(mutex))) \ 419 { \ 420 rpc_dce_svc_printf ( \ 421 __FILE__, __LINE__, \ 422 "%s", \ 423 rpc_svc_mutex, \ 424 svc_c_sev_fatal | svc_c_action_abort, \ 425 rpc_m_call_failed_no_status, \ 426 "RPC_COND_INIT/rpc__cond_init" ); \ 427 } \ 428 } 429#else 430# define RPC_COND_INIT(cond,mutex) \ 431 { \ 432 RPC_LOG_COND_INIT_NTR; \ 433 dcethread_cond_init_throw(&(cond).c, NULL); \ 434 RPC_LOG_COND_INIT_XIT; \ 435 } 436#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 437 438/* 439 * R P C _ C O N D _ D E L E T E 440 */ 441 442#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 443 444# define RPC_COND_DELETE(cond,mutex) \ 445 { \ 446 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 447 { \ 448 if (! rpc__cond_delete(&(cond), &(mutex))) \ 449 { \ 450 rpc_dce_svc_printf ( \ 451 __FILE__, __LINE__, \ 452 "%s", \ 453 rpc_svc_mutex, \ 454 svc_c_sev_fatal | svc_c_action_abort, \ 455 rpc_m_call_failed_no_status, \ 456 "RPC_COND_DELETE/rpc__cond_delete" ); \ 457 } \ 458 } else { \ 459 dcethread_cond_destroy_throw(&(cond).c); \ 460 } \ 461 } 462#else 463# define RPC_COND_DELETE(cond,mutex) \ 464 { \ 465 RPC_LOG_COND_DELETE_NTR; \ 466 dcethread_cond_destroy_throw(&(cond).c); \ 467 RPC_LOG_COND_DELETE_XIT; \ 468 } 469#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 470 471/* 472 * R P C _ C O N D _ W A I T 473 */ 474 475#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 476 477# define RPC_COND_WAIT(cond,mutex) \ 478 { \ 479 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 480 { \ 481 if (! rpc__cond_wait(&(cond), &(mutex), __FILE__, __LINE__)) \ 482 { \ 483 rpc_dce_svc_printf ( \ 484 __FILE__, __LINE__, \ 485 "%s", \ 486 rpc_svc_mutex, \ 487 svc_c_sev_fatal | svc_c_action_abort, \ 488 rpc_m_call_failed_no_status, \ 489 "RPC_COND_WAIT/rpc__cond_wait" ); \ 490 } \ 491 } else { \ 492 dcethread_cond_wait_throw(&(cond).c, &(mutex).m); \ 493 } \ 494 } 495#else 496# define RPC_COND_WAIT(cond,mutex) \ 497 { \ 498 RPC_LOG_COND_WAIT_NTR; \ 499 dcethread_cond_wait_throw(&(cond).c, &(mutex).m); \ 500 RPC_LOG_COND_WAIT_XIT; \ 501 } 502#endif 503 504/* 505 * R P C _ C O N D _ T I M E D _ W A I T 506 */ 507 508#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 509 510# define RPC_COND_TIMED_WAIT(cond,mutex,time) \ 511 { \ 512 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 513 { \ 514 if (! rpc__cond_timed_wait(&(cond), &(mutex), (time), __FILE__, __LINE__)) \ 515 { \ 516 rpc_dce_svc_printf ( \ 517 __FILE__, __LINE__, \ 518 "%s", \ 519 rpc_svc_mutex, \ 520 svc_c_sev_fatal | svc_c_action_abort, \ 521 rpc_m_call_failed_no_status, \ 522 "RPC_COND_TIMED_WAIT/rpc__cond_timed_wait" ); \ 523 } \ 524 } else { \ 525 dcethread_cond_timedwait_throw(&(cond).c, &(mutex).m, (time)); \ 526 } \ 527 } 528#else 529# define RPC_COND_TIMED_WAIT(cond,mutex,time) \ 530 { \ 531 RPC_LOG_COND_TIMED_WAIT_NTR; \ 532 dcethread_cond_timedwait_throw(&(cond).c, &(mutex).m, (time)); \ 533 RPC_LOG_COND_TIMED_WAIT_XIT; \ 534 } 535#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 536 537/* 538 * R P C _ _ C O N D _ S I G N A L 539 */ 540 541#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 542 543# define RPC_COND_SIGNAL(cond,mutex) \ 544 { \ 545 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 546 { \ 547 if (! rpc__cond_signal(&(cond), &(mutex))) \ 548 { \ 549 rpc_dce_svc_printf ( \ 550 __FILE__, __LINE__, \ 551 "%s", \ 552 rpc_svc_mutex, \ 553 svc_c_sev_fatal | svc_c_action_abort, \ 554 rpc_m_call_failed_no_status, \ 555 "RPC_COND_SIGNAL/rpc__cond_signal" ); \ 556 } \ 557 } else { \ 558 dcethread_cond_signal_throw(&(cond).c); \ 559 } \ 560 } 561#else 562# define RPC_COND_SIGNAL(cond,mutex) \ 563 { \ 564 RPC_LOG_COND_SIGNAL_NTR; \ 565 dcethread_cond_signal_throw(&(cond).c); \ 566 RPC_LOG_COND_SIGNAL_XIT; \ 567 } 568#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 569 570/* 571 * R P C _ _ C O N D _ B R O A D C A S T 572 */ 573 574#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 575 576# define RPC_COND_BROADCAST(cond,mutex) \ 577 { \ 578 if (RPC_DBG(rpc_es_dbg_mutex, 1)) \ 579 { \ 580 if (! rpc__cond_broadcast(&(cond), &(mutex))) \ 581 { \ 582 rpc_dce_svc_printf ( \ 583 __FILE__, __LINE__, \ 584 "%s", \ 585 rpc_svc_mutex, \ 586 svc_c_sev_fatal | svc_c_action_abort, \ 587 rpc_m_call_failed_no_status, \ 588 "RPC_COND_BROADCAST/rpc__cond_broadcast" ); \ 589 } \ 590 } else { \ 591 dcethread_cond_broadcast_throw(&(cond).c); \ 592 } \ 593 } 594#else 595# define RPC_COND_BROADCAST(cond,mutex) \ 596 { \ 597 RPC_LOG_COND_BROADCAST_NTR; \ 598 dcethread_cond_broadcast_throw(&(cond).c); \ 599 RPC_LOG_COND_BROADCAST_XIT; \ 600 } 601#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */ 602 603/* ===================================================================== */ 604 605#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) 606 607/* 608 * Prototypes for the support routines. 609 */ 610 611boolean rpc__mutex_init ( rpc_mutex_p_t /*mp*/ ); 612 613boolean rpc__mutex_delete ( rpc_mutex_p_t /*mp*/ ); 614 615boolean rpc__mutex_lock ( 616 rpc_mutex_p_t /*mp*/, 617 char * /*file*/, 618 int /*line*/ 619 ); 620 621boolean rpc__mutex_try_lock ( 622 rpc_mutex_p_t /*mp*/, 623 boolean * /*bp*/, 624 char * /*file*/, 625 int /*line*/ 626 ); 627 628boolean rpc__mutex_unlock ( rpc_mutex_p_t /*mp*/ ); 629 630boolean rpc__mutex_lock_assert ( rpc_mutex_p_t /*mp*/); 631 632boolean rpc__mutex_unlock_assert ( rpc_mutex_p_t /*mp*/); 633 634boolean rpc__cond_init ( 635 rpc_cond_p_t /*cp*/, 636 rpc_mutex_p_t /*mp*/ 637 ); 638 639boolean rpc__cond_delete ( 640 rpc_cond_p_t /*cp*/, 641 rpc_mutex_p_t /*mp*/ 642 ); 643 644boolean rpc__cond_wait ( 645 rpc_cond_p_t /*cp*/, 646 rpc_mutex_p_t /*mp*/, 647 char * /*file*/, 648 int /*line*/ 649 ); 650 651boolean rpc__cond_timed_wait ( 652 rpc_cond_p_t /*cp*/, 653 rpc_mutex_p_t /*mp*/, 654 struct timespec * /*wtime*/, 655 char * /*file*/, 656 int /*line*/ 657 ); 658 659boolean rpc__cond_signal ( 660 rpc_cond_p_t /*cp*/, 661 rpc_mutex_p_t /*mp*/ 662 ); 663 664boolean rpc__cond_broadcast ( 665 rpc_cond_p_t /*cp*/, 666 rpc_mutex_p_t /*mp*/ 667 ); 668 669#else 670 671#ifdef MIREK_NOT_DEFINED 672static void rpc__mutex_none (void); 673#endif 674#endif /* defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) */ 675 676/* ===================================================================== */ 677 678#endif /* _RPCMUTEX_H */ 679