IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 19232


Ignore:
Timestamp:
Aug 27, 2008, 8:53:12 AM (18 years ago)
Author:
Paul Price
Message:

GNU systems define a "fast" mutex that is non-portable (i.e.,
non-standard) that we'd like to use if we can. Using macros to define
a suitable mutex type. Instead of breaking the code into chunks for
different options (with a lot of duplication), using macros to define
the optional bits.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/sys/psMutex.h

    r19120 r19232  
    55#include <assert.h>
    66
    7 typedef pthread_mutex_t psMutex;        /// Mutual Exclusion using pthreads
     7// We desire that these functions be fast (they may get called a lot), so we've defined them as macros.
     8
    89//#define PS_MUTEX_CAREFUL                // Use error-checking mutexes, trace messages, check the results
    910
     11typedef pthread_mutex_t psMutex;        /// Mutual Exclusion using pthreads
     12
     13// Set type of mutex to use based on what sort of system we're using.
     14// GNU systems define a "fast" mutex that is non-portable (i.e., non-standard) that we'd like to use if we can
     15#ifdef __USE_GNU
    1016#ifdef PS_MUTEX_CAREFUL
     17
     18// These bells and whistles are only defined if PS_MUTEX_CAREFUL and __USE_GNU are both defined
     19#define PS_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK_NP // Error-checking mutex
     20#define PS_MUTEX_TRACE(LEVEL, STRING, PTR) psTrace("psLib.sys.mutex", LEVEL, STRING, #PTR); // Trace message
     21#define PS_MUTEX_TRACE_THREAD(LEVEL, STRING, PTR) \ // Trace message with thread and pointer
     22    psTrace("psLib.sys.mutex", LEVEL, STRING, (void*)pthread_self(), #PTR);
     23#define PS_MUTEX_CHECK_DEADLOCK() \     // Check for dead-locked mutex
     24    if (pml == EDEADLK) { \
     25        psAbort("Deadlocked mutex on %s", #PTR); \
     26    }
     27#define PS_MUTEX_CHECK_STOLEN(PTR) \       // Check for stolen mutex
     28    if (pmu == EPERM) { \
     29        psAbort("Unlocking stolen mutex on %s", #PTR); \
     30    }
     31
     32#else  // PS_MUTEX_CAREFUL
     33
     34#define PS_MUTEX_TYPE PTHREAD_MUTEX_FAST_NP // Fast mutex
     35#define PS_MUTEX_TRACE(LEVEL, STRING, PTR) // No action
     36#define PS_MUTEX_TRACE_THREAD(LEVEL, STRING, PTR) // No action
     37#define PS_MUTEX_CHECK_DEADLOCK(PTR)    // No action
     38#define PS_MUTEX_CHECK_STOLEN(PTR)      // No action
     39
     40#endif // PS_MUTEX_CAREFUL
     41#else  // __USE_GNU
     42
     43#define PS_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT // Default mutex type: portable
     44#define PS_MUTEX_TRACE(LEVEL, STRING, PTR) // No action
     45#define PS_MUTEX_TRACE_THREAD(LEVEL, STRING, PTR) // No action
     46#define PS_MUTEX_CHECK_DEADLOCK(PTR)    // No action
     47#define PS_MUTEX_CHECK_STOLEN(PTR)      // No action
     48
     49#endif
     50
    1151
    1252/// Initialize a mutex
    1353#define psMutexInit(PTR) { \
    1454    psAssert(PTR, "Require non-NULL pointer to initialise mutex"); \
    15     psTrace("psLib.sys.mutex", 3, "Initialising mutex on %s...", #PTR); \
     55    PS_MUTEX_TRACE(3, "Initialising mutex on %s...", PTR); \
    1656    /* Gotta go the long way, since we can't use PTHREAD_MUTEX_INITIALIZER after we declare the variable */ \
    1757    pthread_mutexattr_t attr; /* Mutex attributes */ \
    1858    pthread_mutexattr_init(&attr); \
    19     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP); \
     59    pthread_mutexattr_settype(&attr, PS_MUTEX_TYPE); \
    2060    pthread_mutex_init(&(PTR)->lock, &attr); \
    2161    pthread_mutexattr_destroy(&attr); \
     
    2565#define psMutexLock(PTR) { \
    2666    psAssert(PTR, "Require non-NULL pointer to lock mutex"); \
    27     psTrace("psLib.sys.mutex", 1, "Thread %p waiting for mutex lock on %s...", (void*)pthread_self(), #PTR); \
     67    PS_MUTEX_TRACE_THREAD(1, "Thread %p waiting for mutex lock on %s...", PTR); \
    2868    int pml = pthread_mutex_lock(&(PTR)->lock); \
    29     psTrace("psLib.sys.mutex", 1, "Thread %p locked mutex on %s", (void*)pthread_self(), #PTR); \
     69    PS_MUTEX_TRACE_THREAD(1, "Thread %p locked mutex on %s", PTR); \
    3070    if (pml == EINVAL) { \
    3171        psAbort("Cannot lock mutex on %s: not initialised", #PTR); \
    3272    } \
    33     if (pml == EDEADLK) { \
    34         psAbort("Deadlocked mutex on %s", #PTR); \
    35     } \
     73    PS_MUTEX_CHECK_DEADLOCK(PTR); \
    3674}
    3775
     
    3977#define psMutexUnlock(PTR) { \
    4078    psAssert(PTR, "Require non-NULL pointer to unlock mutex"); \
    41     psTrace("psLib.sys.mutex", 1, "Thread %p unlocking mutex on %s", (void*)pthread_self(), #PTR); \
     79    PS_MUTEX_TRACE_THREAD(1, "Thread %p unlocking mutex on %s", PTR); \
    4280    int pmu = pthread_mutex_unlock(&(PTR)->lock); \
    4381    if (pmu == EINVAL) { \
    4482        psAbort("Cannot unlock mutex on %s: not initialised", #PTR); \
    4583    } \
    46     if (pmu == EPERM) { \
    47         psAbort("Unlocking stolen mutex on %s", #PTR); \
    48     } \
     84    PS_MUTEX_CHECK_STOLEN(PTR); \
    4985}
    50 
    51 #else  // PS_MUTEX_CAREFUL
    52 
    53 /// Initialize a mutex
    54 #define psMutexInit(PTR) { \
    55     psAssert(PTR, "Require non-NULL pointer to initialise mutex"); \
    56     /* Gotta go the long way, since we can't use PTHREAD_MUTEX_INITIALIZER after we declare the variable */ \
    57     pthread_mutexattr_t attr; /* Mutex attributes */ \
    58     pthread_mutexattr_init(&attr); \
    59     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_FAST_NP); \
    60     pthread_mutex_init(&(PTR)->lock, &attr); \
    61     pthread_mutexattr_destroy(&attr); \
    62 }
    63 
    64 /// Lock a mutex
    65 #define psMutexLock(PTR) { \
    66     psAssert(PTR, "Require non-NULL pointer to lock mutex"); \
    67     if (pthread_mutex_lock(&(PTR)->lock) == EINVAL) { \
    68         psAbort("Cannot lock mutex on %s: not initialised", #PTR); \
    69     } \
    70 }
    71 
    72 /// Unlock a mutex
    73 #define psMutexUnlock(PTR) { \
    74     psAssert(PTR, "Require non-NULL pointer to unlock mutex"); \
    75     if (pthread_mutex_unlock(&(PTR)->lock) == EINVAL) { \
    76         psAbort("Cannot unlock mutex on %s: not initialised", #PTR); \
    77     } \
    78 }
    79 
    80 #endif // PS_MUTEX_CAREFUL
    8186
    8287/// Destroy a mutex
Note: See TracChangeset for help on using the changeset viewer.