rpcmutex.h   [plain text]


/*
 * Copyright (c) 2010 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Portions of this software have been released under the following terms:
 *
 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
 *
 * To anyone who acknowledges that this file is provided "AS IS"
 * without any express or implied warranty:
 * permission to use, copy, modify, and distribute this file for any
 * purpose is hereby granted without fee, provided that the above
 * copyright notices and this notice appears in all source code copies,
 * and that none of the names of Open Software Foundation, Inc., Hewlett-
 * Packard Company or Digital Equipment Corporation be used
 * in advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission.  Neither Open Software
 * Foundation, Inc., Hewlett-Packard Company nor Digital
 * Equipment Corporation makes any representations about the suitability
 * of this software for any purpose.
 *
 * Copyright (c) 2007, Novell, Inc. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Novell Inc. nor the names of its contributors
 *     may be used to endorse or promote products derived from this
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @APPLE_LICENSE_HEADER_END@
 */

/*
**
**  NAME:
**
**      rpcmutex.h
**
**  FACILITY:
**
**      Remote Procedure Call (RPC)
**
**  ABSTRACT:
**
**  A veneer over CMA (or anything else for that matter) to assist with
**  mutex and condition variable support for the runtime.  This provides
**  some isolation from the underlying mechanisms to allow us to (more)
**  easily slip in alternate facilities, and more importantly add features
**  that we'd like to have in the areas of correctness and debugging
**  of code using these locks as well as statistics gathering.  Note
**  that this package contains a "condition variable" veneer as well,
**  since condition variables and mutexes are tightly integrated (i.e.
**  condition variables have an associated mutex).
**
**  This package provides the following PRIVATE data types and operations:
**
**      rpc_mutex_t m;
**      rpc_cond_t c;
**
**      void RPC_MUTEX_INIT(m)
**      void RPC_MUTEX_DELETE(m)
**      void RPC_MUTEX_LOCK(m)
**      void RPC_MUTEX_TRY_LOCK(m,bp)
**      void RPC_MUTEX_UNLOCK(m)
**      void RPC_MUTEX_LOCK_ASSERT(m)
**      void RPC_MUTEX_UNLOCK_ASSERT(m)
**
**      void RPC_COND_INIT(c,m)
**      void RPC_COND_DELETE(c,m)
**      void RPC_COND_WAIT(c,m)
**      void RPC_COND_TIMED_WAIT(c,m,t)
**      void RPC_COND_SIGNAL(c,m)
**
**  This code is controlled by debug switch "rpc_e_dbg_mutex".  At levels 1
**  or higher, statistics gathering is enabled.  At levels 5 or higher,
**  assertion checking, ownership tracking, deadlock detection, etc. are
**  enabled.
**
**
*/

#ifndef _RPCMUTEX_H
#define _RPCMUTEX_H	1

/*
 * The rpc_mutex_t data type.
 *
 * If debugging isn't configured, this is just a unadorned mutex, else we adorn
 * the struct with goodies to enable assertion checking, deadlock detection
 * and statistics gathering.
 */

typedef struct rpc_mutex_stats_t
{
    unsigned32 busy;            /* total lock requests when already locked */
    unsigned32 lock;            /* total locks */
    unsigned32 try_lock;        /* total try_locks */
    unsigned32 unlock;          /* total unlocks */
    unsigned32 init;            /* total inits */
    unsigned32 deletes;         /* total deletes */
    unsigned32 lock_assert;     /* total lock_asserts */
    unsigned32 unlock_assert;
} rpc_mutex_stats_t, *rpc_mutex_stats_p_t;
#define RPC_MUTEX_STATUS_INITIALIZER {0, 0, 0, 0, 0, 0, 0, 0}

typedef struct rpc_mutex_t
{
    dcethread_mutex m;          /* the unadorned mutex lock */
#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)
    unsigned is_locked:1;       /* T=> locked */
    dcethread* owner;            /* current owner if locked */
    char *locker_file;          /* last locker */
    int locker_line;            /* last locker */
    rpc_mutex_stats_t stats;
#endif /* RPC_MUTEX_DEBUG OR RPC_MUTEX_STATS */
} rpc_mutex_t, *rpc_mutex_p_t;
#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)
# define RPC_MUTEX_INITIALIZER {DCETHREAD_MUTEX_INITIALIZER, 0, 0, NULL, 0, RPC_MUTEX_STATUS_INITIALIZER}
#else
# define RPC_MUTEX_INITIALIZER {DCETHREAD_MUTEX_INITIALIZER}
#endif

/*
 * The rpc_cond_t (condition variable) data type.
 */

typedef struct rpc_cond_stats_t
{
    unsigned32 init;            /* total inits */
    unsigned32 deletes;          /* total deletes */
    unsigned32 wait;            /* total waits */
    unsigned32 signals;         /* total signals + broadcasts */
} rpc_cond_stats_t, *rpc_cond_stats_p_t;
#define RPC_COND_STATS_INITIALIZER {0, 0, 0, 0}

typedef struct rpc_cond_t
{
    dcethread_cond c;           /* the unadorned condition variable */
    rpc_mutex_p_t mp;           /* the cv's associated mutex */
    rpc_cond_stats_t stats;
} rpc_cond_t, *rpc_cond_p_t;
#define RPC_COND_INITIALIZER {DCETHREAD_COND_INITIALIZER, NULL, RPC_COND_STATS_INITIALIZER}

/*
 * Some relatively efficient generic mutex operations that are controllable
 * at run time as well as compile time.  The "real" support routines
 * can be found in rpcmutex.c .
 */

/*
 * R P C _ M U T E X _ I N I T
 *
 * We always need to call the support routine so that the stats, etc
 * get initialized.
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_MUTEX_INIT(mutex)  \
    { \
        if (! rpc__mutex_init(&(mutex))) \
        { \
            rpc_dce_svc_printf ( \
                __FILE__, __LINE__, \
                "%s", \
                rpc_svc_mutex, \
                svc_c_sev_fatal | svc_c_action_abort, \
                rpc_m_call_failed_no_status, \
                "RPC_MUTEX_INIT/rpc__mutex_init" ); \
        } \
    }
#else
#  define RPC_MUTEX_INIT(mutex) \
    { \
        RPC_LOG_MUTEX_INIT_NTR; \
        dcethread_mutex_init_throw(&(mutex).m, NULL); \
        RPC_LOG_MUTEX_INIT_XIT; \
    }
#endif /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 * R P C _ M U T E X _ D E L E T E
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)
#  define RPC_MUTEX_DELETE(mutex)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__mutex_delete(&(mutex))) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_MUTEX_DELETE/rpc__mutex_delete" ); \
            } \
        } else { \
            dcethread_mutex_destroy_throw(&(mutex).m); \
        } \
    }
#else
#  define RPC_MUTEX_DELETE(mutex) \
    { \
        RPC_LOG_MUTEX_DELETE_NTR; \
        dcethread_mutex_destroy_throw(&(mutex).m); \
        RPC_LOG_MUTEX_DELETE_XIT; \
    }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 * R P C _ M U T E X _ L O C K
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_MUTEX_LOCK(mutex)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__mutex_lock(&(mutex), __FILE__, __LINE__)) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_MUTEX_LOCK/rpc__mutex_lock" ); \
            } \
        } else { \
            RPC_LOG_MUTEX_LOCK_NTR; \
            dcethread_mutex_lock_throw(&(mutex).m); \
            RPC_LOG_MUTEX_LOCK_XIT; \
        } \
    }
#else
#  define RPC_MUTEX_LOCK(mutex) \
    { \
        RPC_LOG_MUTEX_LOCK_NTR; \
        dcethread_mutex_lock_throw(&(mutex).m); \
        RPC_LOG_MUTEX_LOCK_XIT; \
    }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 * R P C _ M U T E X _ T R Y _ L O C K
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_MUTEX_TRY_LOCK(mutex,bp)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__mutex_try_lock(&(mutex), (bp), __FILE__, __LINE__)) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_MUTEX_TRY_LOCK/rpc__mutex_try_lock" ); \
            } \
        } else { \
            *(bp) = dcethread_mutex_trylock_throw(&(mutex).m); \
        } \
    }
#else
#  define RPC_MUTEX_TRY_LOCK(mutex,bp) \
    { \
        RPC_LOG_MUTEX_TRY_LOCK_NTR; \
        *(bp) = dcethread_mutex_trylock_throw(&(mutex).m); \
        RPC_LOG_MUTEX_TRY_LOCK_XIT; \
    }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 * R P C _ M U T E X _ U N L O C K
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_MUTEX_UNLOCK(mutex)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__mutex_unlock(&(mutex))) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_MUTEX_UNLOCK/rpc__mutex_unlock" ); \
            } \
        } else { \
            dcethread_mutex_unlock_throw(&(mutex).m); \
        } \
    }
#else
#  define RPC_MUTEX_UNLOCK(mutex) \
    { \
        RPC_LOG_MUTEX_UNLOCK_NTR; \
        dcethread_mutex_unlock_throw(&(mutex).m); \
        RPC_LOG_MUTEX_UNLOCK_XIT; \
    }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 * R P C _ M U T E X _ L O C K _ A S S E R T
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_MUTEX_LOCK_ASSERT(mutex)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__mutex_lock_assert(&(mutex))) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_MUTEX_LOCK_ASSERT/rpc__mutex_lock_assert" ); \
            } \
        } \
    }
#else
#  define RPC_MUTEX_LOCK_ASSERT(mutex)      { }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 * R P C _ M U T E X _ U N L O C K _ A S S E R T
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_MUTEX_UNLOCK_ASSERT(mutex)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__mutex_unlock_assert(&(mutex))) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_MUTEX_UNLOCK_ASSERT/rpc__mutex_unlock_assert" ); \
            } \
        } \
    }
#else
#  define RPC_MUTEX_UNLOCK_ASSERT(mutex)    { }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 *  R P C _ C O N D _ I N I T
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_COND_INIT(cond,mutex)  \
    { \
        if (! rpc__cond_init(&(cond), &(mutex))) \
        { \
            rpc_dce_svc_printf ( \
                __FILE__, __LINE__, \
                "%s", \
                rpc_svc_mutex, \
                svc_c_sev_fatal | svc_c_action_abort, \
                rpc_m_call_failed_no_status, \
                "RPC_COND_INIT/rpc__cond_init" ); \
        } \
    }
#else
#  define RPC_COND_INIT(cond,mutex) \
    { \
        RPC_LOG_COND_INIT_NTR; \
        dcethread_cond_init_throw(&(cond).c, NULL);  \
        RPC_LOG_COND_INIT_XIT; \
    }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 *  R P C _ C O N D _ D E L E T E
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_COND_DELETE(cond,mutex)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__cond_delete(&(cond), &(mutex))) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_COND_DELETE/rpc__cond_delete" ); \
            } \
        } else { \
            dcethread_cond_destroy_throw(&(cond).c); \
        } \
    }
#else
#  define RPC_COND_DELETE(cond,mutex) \
    { \
      RPC_LOG_COND_DELETE_NTR; \
      dcethread_cond_destroy_throw(&(cond).c); \
      RPC_LOG_COND_DELETE_XIT; \
  }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 *  R P C _ C O N D _ W A I T
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_COND_WAIT(cond,mutex)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__cond_wait(&(cond), &(mutex), __FILE__, __LINE__)) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_COND_WAIT/rpc__cond_wait" ); \
            } \
        } else { \
            dcethread_cond_wait_throw(&(cond).c, &(mutex).m); \
        } \
    }
#else
#  define RPC_COND_WAIT(cond,mutex) \
    { \
        RPC_LOG_COND_WAIT_NTR; \
        dcethread_cond_wait_throw(&(cond).c, &(mutex).m); \
        RPC_LOG_COND_WAIT_XIT; \
    }
#endif

/*
 *  R P C _ C O N D _ T I M E D _ W A I T
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_COND_TIMED_WAIT(cond,mutex,time)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__cond_timed_wait(&(cond), &(mutex), (time), __FILE__, __LINE__)) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_COND_TIMED_WAIT/rpc__cond_timed_wait" ); \
            } \
        } else { \
            dcethread_cond_timedwait_throw(&(cond).c, &(mutex).m, (time)); \
        } \
    }
#else
#  define RPC_COND_TIMED_WAIT(cond,mutex,time) \
    { \
        RPC_LOG_COND_TIMED_WAIT_NTR; \
        dcethread_cond_timedwait_throw(&(cond).c, &(mutex).m, (time)); \
        RPC_LOG_COND_TIMED_WAIT_XIT; \
    }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 *  R P C _ _ C O N D _ S I G N A L
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_COND_SIGNAL(cond,mutex)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__cond_signal(&(cond), &(mutex))) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_COND_SIGNAL/rpc__cond_signal" ); \
            } \
        } else { \
            dcethread_cond_signal_throw(&(cond).c); \
        } \
    }
#else
#  define RPC_COND_SIGNAL(cond,mutex) \
    { \
        RPC_LOG_COND_SIGNAL_NTR; \
        dcethread_cond_signal_throw(&(cond).c); \
        RPC_LOG_COND_SIGNAL_XIT; \
    }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/*
 *  R P C _ _ C O N D _ B R O A D C A S T
 */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

#  define RPC_COND_BROADCAST(cond,mutex)  \
    { \
        if (RPC_DBG(rpc_es_dbg_mutex, 1)) \
        { \
            if (! rpc__cond_broadcast(&(cond), &(mutex))) \
            { \
                rpc_dce_svc_printf ( \
                    __FILE__, __LINE__, \
                    "%s", \
                    rpc_svc_mutex, \
                    svc_c_sev_fatal | svc_c_action_abort, \
                    rpc_m_call_failed_no_status, \
                    "RPC_COND_BROADCAST/rpc__cond_broadcast" ); \
            } \
        } else { \
            dcethread_cond_broadcast_throw(&(cond).c); \
        } \
    }
#else
#  define RPC_COND_BROADCAST(cond,mutex) \
    { \
        RPC_LOG_COND_BROADCAST_NTR; \
        dcethread_cond_broadcast_throw(&(cond).c); \
        RPC_LOG_COND_BROADCAST_XIT; \
    }
#endif  /* RPC_MUTEX_DEBUG or RPC_MUTEX_STATS */

/* ===================================================================== */

#if defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS)

/*
 * Prototypes for the support routines.
 */

boolean rpc__mutex_init ( rpc_mutex_p_t  /*mp*/ );

boolean rpc__mutex_delete ( rpc_mutex_p_t  /*mp*/ );

boolean rpc__mutex_lock (
        rpc_mutex_p_t  /*mp*/,
        char * /*file*/,
        int  /*line*/
    );

boolean rpc__mutex_try_lock (
        rpc_mutex_p_t  /*mp*/,
        boolean * /*bp*/,
        char * /*file*/,
        int  /*line*/
    );

boolean rpc__mutex_unlock ( rpc_mutex_p_t  /*mp*/ );

boolean rpc__mutex_lock_assert ( rpc_mutex_p_t  /*mp*/);

boolean rpc__mutex_unlock_assert ( rpc_mutex_p_t  /*mp*/);

boolean rpc__cond_init (
        rpc_cond_p_t  /*cp*/,
        rpc_mutex_p_t  /*mp*/
    );

boolean rpc__cond_delete (
        rpc_cond_p_t  /*cp*/,
        rpc_mutex_p_t  /*mp*/
    );

boolean rpc__cond_wait (
        rpc_cond_p_t  /*cp*/,
        rpc_mutex_p_t  /*mp*/,
        char * /*file*/,
        int  /*line*/
    );

boolean rpc__cond_timed_wait (
        rpc_cond_p_t  /*cp*/,
        rpc_mutex_p_t  /*mp*/,
        struct timespec * /*wtime*/,
        char * /*file*/,
        int  /*line*/
    );

boolean rpc__cond_signal (
        rpc_cond_p_t  /*cp*/,
        rpc_mutex_p_t  /*mp*/
    );

boolean rpc__cond_broadcast (
        rpc_cond_p_t  /*cp*/,
        rpc_mutex_p_t  /*mp*/
    );

#else

#ifdef MIREK_NOT_DEFINED
static void rpc__mutex_none (void);
#endif
#endif /* defined(RPC_MUTEX_DEBUG) || defined(RPC_MUTEX_STATS) */

/* ===================================================================== */

#endif /* _RPCMUTEX_H */