Changeset 19232
- Timestamp:
- Aug 27, 2008, 8:53:12 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/sys/psMutex.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/sys/psMutex.h
r19120 r19232 5 5 #include <assert.h> 6 6 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 8 9 //#define PS_MUTEX_CAREFUL // Use error-checking mutexes, trace messages, check the results 9 10 11 typedef 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 10 16 #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 11 51 12 52 /// Initialize a mutex 13 53 #define psMutexInit(PTR) { \ 14 54 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); \ 16 56 /* Gotta go the long way, since we can't use PTHREAD_MUTEX_INITIALIZER after we declare the variable */ \ 17 57 pthread_mutexattr_t attr; /* Mutex attributes */ \ 18 58 pthread_mutexattr_init(&attr); \ 19 pthread_mutexattr_settype(&attr, P THREAD_MUTEX_ERRORCHECK_NP); \59 pthread_mutexattr_settype(&attr, PS_MUTEX_TYPE); \ 20 60 pthread_mutex_init(&(PTR)->lock, &attr); \ 21 61 pthread_mutexattr_destroy(&attr); \ … … 25 65 #define psMutexLock(PTR) { \ 26 66 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); \ 28 68 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); \ 30 70 if (pml == EINVAL) { \ 31 71 psAbort("Cannot lock mutex on %s: not initialised", #PTR); \ 32 72 } \ 33 if (pml == EDEADLK) { \ 34 psAbort("Deadlocked mutex on %s", #PTR); \ 35 } \ 73 PS_MUTEX_CHECK_DEADLOCK(PTR); \ 36 74 } 37 75 … … 39 77 #define psMutexUnlock(PTR) { \ 40 78 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); \ 42 80 int pmu = pthread_mutex_unlock(&(PTR)->lock); \ 43 81 if (pmu == EINVAL) { \ 44 82 psAbort("Cannot unlock mutex on %s: not initialised", #PTR); \ 45 83 } \ 46 if (pmu == EPERM) { \ 47 psAbort("Unlocking stolen mutex on %s", #PTR); \ 48 } \ 84 PS_MUTEX_CHECK_STOLEN(PTR); \ 49 85 } 50 51 #else // PS_MUTEX_CAREFUL52 53 /// Initialize a mutex54 #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 mutex65 #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 mutex73 #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_CAREFUL81 86 82 87 /// Destroy a mutex
Note:
See TracChangeset
for help on using the changeset viewer.
