00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _FAST_MUTEX_H_
00025 #define _FAST_MUTEX_H_
00026
00028
00029
00030 #if !defined(_TTHREAD_PLATFORM_DEFINED_)
00031 #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
00032 #define _TTHREAD_WIN32_
00033 #else
00034 #define _TTHREAD_POSIX_
00035 #endif
00036 #define _TTHREAD_PLATFORM_DEFINED_
00037 #endif
00038
00039
00040
00041 #if (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) || \
00042 (defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))) || \
00043 (defined(__GNUC__) && (defined(__ppc__)))
00044 #define _FAST_MUTEX_ASM_
00045 #else
00046 #define _FAST_MUTEX_SYS_
00047 #endif
00048
00049 #if defined(_TTHREAD_WIN32_)
00050 #include <windows.h>
00051 #else
00052 #ifdef _FAST_MUTEX_ASM_
00053 #include <sched.h>
00054 #else
00055 #include <pthread.h>
00056 #endif
00057 #endif
00058
00059 namespace tthread {
00060
00080 class fast_mutex {
00081 public:
00083 #if defined(_FAST_MUTEX_ASM_)
00084 fast_mutex() : mLock(0) {}
00085 #else
00086 fast_mutex()
00087 {
00088 #if defined(_TTHREAD_WIN32_)
00089 InitializeCriticalSection(&mHandle);
00090 #elif defined(_TTHREAD_POSIX_)
00091 pthread_mutex_init(&mHandle, NULL);
00092 #endif
00093 }
00094 #endif
00095
00096 #if !defined(_FAST_MUTEX_ASM_)
00097
00098 ~fast_mutex()
00099 {
00100 #if defined(_TTHREAD_WIN32_)
00101 DeleteCriticalSection(&mHandle);
00102 #elif defined(_TTHREAD_POSIX_)
00103 pthread_mutex_destroy(&mHandle);
00104 #endif
00105 }
00106 #endif
00107
00112 inline void lock()
00113 {
00114 #if defined(_FAST_MUTEX_ASM_)
00115 bool gotLock;
00116 do {
00117 gotLock = try_lock();
00118 if(!gotLock)
00119 {
00120 #if defined(_TTHREAD_WIN32_)
00121 Sleep(0);
00122 #elif defined(_TTHREAD_POSIX_)
00123 sched_yield();
00124 #endif
00125 }
00126 } while(!gotLock);
00127 #else
00128 #if defined(_TTHREAD_WIN32_)
00129 EnterCriticalSection(&mHandle);
00130 #elif defined(_TTHREAD_POSIX_)
00131 pthread_mutex_lock(&mHandle);
00132 #endif
00133 #endif
00134 }
00135
00141 inline bool try_lock()
00142 {
00143 #if defined(_FAST_MUTEX_ASM_)
00144 int oldLock;
00145 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
00146 asm volatile (
00147 "movl $1,%%eax\n\t"
00148 "xchg %%eax,%0\n\t"
00149 "movl %%eax,%1\n\t"
00150 : "=m" (mLock), "=m" (oldLock)
00151 :
00152 : "%eax", "memory"
00153 );
00154 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
00155 int *ptrLock = &mLock;
00156 __asm {
00157 mov eax,1
00158 mov ecx,ptrLock
00159 xchg eax,[ecx]
00160 mov oldLock,eax
00161 }
00162 #elif defined(__GNUC__) && (defined(__ppc__))
00163 int newLock = 1;
00164 asm volatile (
00165 "\n1:\n\t"
00166 "lwarx %0,0,%1\n\t"
00167 "cmpwi 0,%0,0\n\t"
00168 "bne- 2f\n\t"
00169 "stwcx. %2,0,%1\n\t"
00170 "bne- 1b\n\t"
00171 "isync\n"
00172 "2:\n\t"
00173 : "=&r" (oldLock)
00174 : "r" (&mLock), "r" (newLock)
00175 : "cr0", "memory"
00176 );
00177 #endif
00178 return (oldLock == 0);
00179 #else
00180 #if defined(_TTHREAD_WIN32_)
00181 return TryEnterCriticalSection(&mHandle) ? true : false;
00182 #elif defined(_TTHREAD_POSIX_)
00183 return (pthread_mutex_trylock(&mHandle) == 0) ? true : false;
00184 #endif
00185 #endif
00186 }
00187
00191 inline void unlock()
00192 {
00193 #if defined(_FAST_MUTEX_ASM_)
00194 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
00195 asm volatile (
00196 "movl $0,%%eax\n\t"
00197 "xchg %%eax,%0\n\t"
00198 : "=m" (mLock)
00199 :
00200 : "%eax", "memory"
00201 );
00202 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
00203 int *ptrLock = &mLock;
00204 __asm {
00205 mov eax,0
00206 mov ecx,ptrLock
00207 xchg eax,[ecx]
00208 }
00209 #elif defined(__GNUC__) && (defined(__ppc__))
00210 asm volatile (
00211 "sync\n\t"
00212 : : : "memory"
00213 );
00214 mLock = 0;
00215 #endif
00216 #else
00217 #if defined(_TTHREAD_WIN32_)
00218 LeaveCriticalSection(&mHandle);
00219 #elif defined(_TTHREAD_POSIX_)
00220 pthread_mutex_unlock(&mHandle);
00221 #endif
00222 #endif
00223 }
00224
00225 private:
00226 #if defined(_FAST_MUTEX_ASM_)
00227 int mLock;
00228 #else
00229 #if defined(_TTHREAD_WIN32_)
00230 CRITICAL_SECTION mHandle;
00231 #elif defined(_TTHREAD_POSIX_)
00232 pthread_mutex_t mHandle;
00233 #endif
00234 #endif
00235 };
00236
00237 }
00238
00239 #endif // _FAST_MUTEX_H_