- Timestamp:
- Mar 16, 2004, 6:24:54 PM (21 years ago)
- Location:
- trunk/src/odincrt
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/odincrt/critsect.cpp
r10186 r10533 1 /* $Id: critsect.cpp,v 1.1 0 2003-07-28 17:32:58sandervl Exp $ */1 /* $Id: critsect.cpp,v 1.11 2004-03-16 17:24:53 sandervl Exp $ */ 2 2 /* 3 3 * Critical sections in the Win32 sense … … 6 6 * 7 7 */ 8 #define INCL_DOS 8 9 #define INCL_DOSPROCESS 9 10 #define INCL_DOSERRORS 10 11 #define INCL_DOSSEMAPHORES 11 #include <os2wrap.h> 12 #include <win32type.h> 13 #include <win32api.h> 12 #include <os2.h> 13 14 #include "dbglog.h" 15 16 #include <odincrt.h> 14 17 #include <FastInfoBlocks.h> 15 18 16 19 #undef fibGetPid 17 20 18 #include <assert.h> 19 #include <stdio.h> 20 21 #include <odincrt.h> 22 23 #ifdef DEBUG 24 #define DebugInt3() _interrupt(3) 25 #else 21 #undef dprintf 22 #undef DebugInt3 23 24 #define dprintf(a) 26 25 #define DebugInt3() 27 #endif28 29 26 30 27 //****************************************************************************** … … 68 65 //****************************************************************************** 69 66 //****************************************************************************** 70 inline ULONG GetCurrentProcessId() 71 { 72 #ifdef fibGetPid 73 return fibGetPid(); 74 #else 75 PTIB ptib; 76 PPIB ppib; 67 ULONG WIN32API DosInitializeCriticalSection(CRITICAL_SECTION_OS2 *crit, char *pszSemName, BOOL fShared) 68 { 77 69 APIRET rc; 78 70 79 rc = DosGetInfoBlocks(&ptib, &ppib); 80 if(rc == NO_ERROR) { 81 return ppib->pib_ulpid; 82 } 83 DebugInt3(); 84 return 0; 85 #endif 86 } 87 88 /*********************************************************************** 89 * DosInitializeCriticalSection 90 */ 91 ULONG WIN32API DosInitializeCriticalSection(CRITICAL_SECTION_OS2 *crit, 92 PSZ pszSemName, BOOL fShared) 93 { 94 APIRET rc; 95 71 rc = DosCreateEventSem(pszSemName, &crit->hevLock, (pszSemName || fShared)? DC_SEM_SHARED: 0, 0); 72 73 if(rc != NO_ERROR) 74 { 75 crit->hevLock = 0; 76 return rc; 77 } 78 96 79 // initialize lock count with special value -1, meaning noone posesses it 97 80 crit->LockCount = -1; … … 99 82 crit->OwningThread = 0; 100 83 101 rc = DosCreateEventSem(pszSemName, &crit->hmtxLock, (pszSemName || fShared) ? DC_SEM_SHARED : 0, 0);102 if(rc != NO_ERROR) {103 DebugInt3();104 crit->hmtxLock = 0;105 return rc;106 }107 84 crit->CreationCount = 1; 108 crit->Reserved = GetCurrentProcessId(); 109 return NO_ERROR; 110 } 111 112 113 /*********************************************************************** 114 * DosAccessCriticalSection 115 */ 116 ULONG WIN32API DosAccessCriticalSection(CRITICAL_SECTION_OS2 *crit, PSZ pszSemName) 117 { 118 HMTX hmtxLock = 0; 119 APIRET rc; 120 121 if(pszSemName == NULL && crit->hmtxLock == 0) { 122 DebugInt3(); 123 return ERROR_INVALID_PARAMETER; 124 } 125 if(pszSemName == NULL) { 126 hmtxLock = crit->hmtxLock; 127 } 128 129 rc = DosOpenEventSem(pszSemName, &hmtxLock); 130 if(rc != NO_ERROR) { 131 DebugInt3(); 132 return rc; 133 } 85 crit->Reserved = 0; 86 87 return NO_ERROR; 88 } 89 90 ULONG WIN32API DosValidateCriticalSection (CRITICAL_SECTION_OS2 *crit) 91 { 92 if (crit->hevLock != NULLHANDLE) 93 { 94 return NO_ERROR; 95 } 96 97 return ERROR_INVALID_PARAMETER; 98 } 99 100 // Initializes or opens a critical section 101 ULONG WIN32API DosAccessCriticalSection(CRITICAL_SECTION_OS2 *crit, char *pszSemName) 102 { 103 APIRET rc = NO_ERROR; 104 105 // Increment creation counter to prevent the section to be destroyed while 106 // we are checking it. Assume that an unitialized section has the counter == 0 134 107 DosInterlockedIncrement(&crit->CreationCount); 135 return NO_ERROR; 136 } 137 /*********************************************************************** 138 * DosDeleteCriticalSection 139 */ 108 109 if (DosValidateCriticalSection (crit) == NO_ERROR) 110 { 111 // the section already initialized, use it 112 HEV hevLock = NULLHANDLE; 113 114 if (pszSemName == NULL) 115 { 116 hevLock = crit->hevLock; 117 } 118 119 rc = DosOpenEventSem(pszSemName, &hevLock); 120 121 if (rc != NO_ERROR) 122 { 123 DosInterlockedDecrement(&crit->CreationCount); 124 DebugInt3(); 125 } 126 } 127 else 128 { 129 rc = DosInitializeCriticalSection (crit, pszSemName, TRUE); 130 } 131 132 return NO_ERROR; 133 } 134 140 135 ULONG WIN32API DosDeleteCriticalSection( CRITICAL_SECTION_OS2 *crit ) 141 136 { 142 if (crit->hmtxLock) 143 { 144 #ifdef DEBUG 145 if ( (crit->LockCount != -1 && crit->CreationCount == 1) 146 || crit->OwningThread 147 || crit->RecursionCount) /* Should not happen */ 148 { 149 DebugInt3(); 150 } 151 #endif 152 DosCloseEventSem(crit->hmtxLock); 137 if (DosValidateCriticalSection (crit)) 138 { 139 DosCloseEventSem (crit->hevLock); 140 153 141 if(DosInterlockedDecrement(&crit->CreationCount) == 0) 154 142 { … … 156 144 crit->RecursionCount = 0; 157 145 crit->OwningThread = 0; 158 crit->hmtxLock = 0; 159 crit->Reserved = (DWORD)-1; 160 } 161 } 162 return NO_ERROR; 163 } 164 165 166 /*********************************************************************** 167 * DosEnterCriticalSection 146 crit->hevLock = 0; 147 crit->Reserved = 0; 148 } 149 } 150 return NO_ERROR; 151 } 152 153 154 ULONG WIN32API DosEnterCriticalSection( CRITICAL_SECTION_OS2 *crit, ULONG ulTimeout ) 155 { 156 APIRET rc = NO_ERROR; 157 158 ULONG threadid = GetCurrentThreadId(); 159 160 if (!crit->hevLock) 161 { 162 rc = DosInitializeCriticalSection (crit, NULL, FALSE); 163 if (rc != NO_ERROR) 164 { 165 return rc; 166 } 167 } 168 169 dprintf(("Entering the section: owner = %8.8X\n", crit->OwningThread)); 170 171 // We want to acquire the section, count the entering 172 DosInterlockedIncrement (&crit->LockCount); 173 174 // try to acquire the section 175 for (;;) 176 { 177 // try to assign owning thread id atomically 178 if (DosInterlockedCompareExchange((PLONG)&crit->OwningThread, threadid, 0) == 0) 179 { 180 ULONG ulnrposts = 0; 181 182 dprintf(("Acquired the section: owner = %8.8X\n", crit->OwningThread)); 183 DosResetEventSem (crit->hevLock, &ulnrposts); 184 break; 185 } 186 187 if (crit->OwningThread == threadid) 188 { 189 // This thread already owns the section 190 crit->RecursionCount++; 191 dprintf(("Recursion: %d\n", crit->RecursionCount)); 192 return NO_ERROR; 193 } 194 195 // Arise any timing problems and let others to run 196 DosSleep (0); 197 198 dprintf(("Waiting on sem: owner = %8.8X\n", crit->OwningThread)); 199 rc = DosWaitEventSem (crit->hevLock, ulTimeout); 200 dprintf(("Returned from wait: owner = %8.8X, rc = %d\n", crit->OwningThread, rc)); 201 202 if (rc != NO_ERROR) 203 { 204 dprintf(("Returned from wait: FAILED!!!\n")); 205 // We fail, deregister itself 206 DosInterlockedDecrement (&crit->LockCount); 207 return rc; 208 } 209 } 210 211 // the section was successfully aquired 212 crit->RecursionCount = 1; 213 214 if (crit->Reserved != 0) 215 { 216 // the section already entered!!!! 217 DosBeep (2000, 200); 218 } 219 220 crit->Reserved = 1; 221 222 return NO_ERROR; 223 } 224 225 226 ULONG WIN32API DosLeaveCriticalSection( CRITICAL_SECTION_OS2 *crit ) 227 { 228 dprintf(("Leaving the section\n")); 229 if (crit->OwningThread != GetCurrentThreadId()) { 230 dprintf(("WRONG THREAD ID!!! owner is %8.8X\n", crit->OwningThread)); 231 return ERROR_INVALID_PARAMETER; 232 } 233 234 if (--crit->RecursionCount) 235 { 236 dprintf(("Recursion exit: %d\n", crit->RecursionCount)); 237 DosInterlockedDecrement( &crit->LockCount ); 238 return NO_ERROR; 239 } 240 241 crit->Reserved = 0; 242 crit->OwningThread = 0; 243 244 dprintf(("Released the section\n")); 245 246 if (DosInterlockedDecrement( &crit->LockCount ) >= 0) 247 { 248 dprintf(("Posted the semaphore\n")); 249 DosPostEventSem(crit->hevLock); 250 } 251 252 return NO_ERROR; 253 } 254 255 256 /** 257 * Checks if the current thread is in the critical section or now. 258 * 259 * @returns NO_ERROR if in the critical section. 260 * @returns ERROR_NOT_OWNER if not in the critical section. 261 * @param pCrit Pointer to the critical section. 168 262 */ 169 ULONG WIN32API DosEnterCriticalSection( CRITICAL_SECTION_OS2 *crit, ULONG ulTimeout ) 170 { 171 DWORD res; 172 DWORD threadid = GetCurrentThreadId(); 173 174 // create crit sect just in time... 175 if (!crit->hmtxLock) 176 { 177 DosInitializeCriticalSection(crit, NULL); 178 } 179 // if the same thread is requesting it again, memorize it 180 if (crit->OwningThread == threadid) 181 { 182 crit->RecursionCount++; 183 return NO_ERROR; 184 } 185 186 // do an atomic increase of the lockcounter 187 DosInterlockedIncrement(&crit->LockCount); 188 189 // do an atomic operation where we compare the owning thread id with 0 190 // and if this is true, exchange it with the id of the current thread. 191 testenter: 192 if(DosInterlockedCompareExchange((PLONG)&crit->OwningThread, threadid, 0)) 193 { 194 // the crit sect is in use 195 ULONG ulnrposts; 196 197 // now wait for it 198 APIRET rc = DosWaitEventSem(crit->hmtxLock, ulTimeout); 199 if(rc != NO_ERROR) { 200 DebugInt3(); 201 return rc; 202 } 203 DosResetEventSem(crit->hmtxLock, &ulnrposts); 204 // multiple waiters could be running now. Repeat the logic so that 205 // only one actually can get the critical section 206 goto testenter; 207 } 208 crit->RecursionCount = 1; 209 return NO_ERROR; 210 } 211 212 213 /*********************************************************************** 214 * DosLeaveCriticalSection 215 */ 216 ULONG WIN32API DosLeaveCriticalSection( CRITICAL_SECTION_OS2 *crit ) 217 { 218 if (crit->OwningThread != GetCurrentThreadId()) { 219 DebugInt3(); 220 return ERROR_INVALID_PARAMETER; 221 } 222 223 if (--crit->RecursionCount) 224 { 225 //just return 226 return NO_ERROR; 227 } 228 crit->OwningThread = 0; 229 if (DosInterlockedDecrement( &crit->LockCount ) >= 0) 230 { 231 /* Someone is waiting */ 232 DosPostEventSem(crit->hmtxLock); 233 } 234 return NO_ERROR; 235 } 263 ULONG WIN32API DosIsInCriticalSection( CRITICAL_SECTION_OS2 *pCrit ) 264 { 265 return (pCrit->hevLock && pCrit->OwningThread == GetCurrentThreadId() ? NO_ERROR : ERROR_NOT_OWNER); 266 } 267 -
trunk/src/odincrt/odin36.def
r10185 r10533 1 ; $Id: odin36.def,v 1.1 0 2003-07-28 11:30:17sandervl Exp $1 ; $Id: odin36.def,v 1.11 2004-03-16 17:24:53 sandervl Exp $ 2 2 ; Odin VAC++ 3.6.5 shared multithreaded runtime 3 3 LIBRARY ODINCRT INITINSTANCE TERMINSTANCE … … 986 986 _DosInterlockedExchangeAdd@8 @1208 NONAME 987 987 _DosInterlockedIncrement@4 @1209 NONAME 988 _DosValidateCriticalSection@4 @1210 NONAME -
trunk/src/odincrt/odin36d.def
r10185 r10533 1 ; $Id: odin36d.def,v 1.1 0 2003-07-28 11:30:18sandervl Exp $1 ; $Id: odin36d.def,v 1.11 2004-03-16 17:24:54 sandervl Exp $ 2 2 ; Odin VAC++ 3.6.5 shared multithreaded runtime 3 3 LIBRARY ODINCRTD INITINSTANCE TERMINSTANCE … … 994 994 _DosInterlockedExchangeAdd@8 @1208 NONAME 995 995 _DosInterlockedIncrement@4 @1209 NONAME 996 _DosValidateCriticalSection@4 @1210 NONAME -
trunk/src/odincrt/odincrt.def
r10185 r10533 1 ; $Id: odincrt.def,v 1.3 0 2003-07-28 11:30:19sandervl Exp $1 ; $Id: odincrt.def,v 1.31 2004-03-16 17:24:54 sandervl Exp $ 2 2 ; Odin VAC++ 3.08 shared multithreaded runtime 3 3 LIBRARY ODINCRT INITINSTANCE TERMINSTANCE … … 967 967 _DosInterlockedExchangeAdd@8 @1208 NONAME 968 968 _DosInterlockedIncrement@4 @1209 NONAME 969 _DosValidateCriticalSection@4 @1210 NONAME -
trunk/src/odincrt/odincrtd.def
r10185 r10533 1 ; $Id: odincrtd.def,v 1.1 1 2003-07-28 11:30:19sandervl Exp $1 ; $Id: odincrtd.def,v 1.12 2004-03-16 17:24:54 sandervl Exp $ 2 2 ; Odin VAC++ 3.08 shared multithreaded runtime 3 3 LIBRARY ODINCRTD INITINSTANCE TERMINSTANCE … … 966 966 _DosInterlockedExchangeAdd@8 @1208 NONAME 967 967 _DosInterlockedIncrement@4 @1209 NONAME 968 _DosValidateCriticalSection@4 @1210 NONAME -
trunk/src/odincrt/odincrtp.def
r10185 r10533 1 ; $Id: odincrtp.def,v 1. 8 2003-07-28 11:30:20sandervl Exp $1 ; $Id: odincrtp.def,v 1.9 2004-03-16 17:24:54 sandervl Exp $ 2 2 ; Odin VAC++ 3.08 shared multithreaded runtime 3 3 LIBRARY ODINCRTP INITINSTANCE TERMINSTANCE … … 987 987 _DosInterlockedExchangeAdd@8 @1208 NONAME 988 988 _DosInterlockedIncrement@4 @1209 NONAME 989 _DosValidateCriticalSection@4 @1210 NONAME
Note:
See TracChangeset
for help on using the changeset viewer.