Mercurial > flash_v2
comparison host/tools/Utils/common/eCosThreadUtils.cpp @ 82:6736c52df507 ecos-sw-2000-04-14
Merge from eCos master repository on 2000-04-14-13:35:46-BST
| author | jlarmour |
|---|---|
| date | Tue, 18 Apr 2000 21:51:55 +0000 |
| parents | 435cced73e2f |
| children | 94f334d9be6e |
comparison
equal
deleted
inserted
replaced
| 81:89fef2181d7d | 82:6736c52df507 |
|---|---|
| 88 #ifdef _WIN32 | 88 #ifdef _WIN32 |
| 89 // FIXME: CreateThread incompatible with C runtime calls? | 89 // FIXME: CreateThread incompatible with C runtime calls? |
| 90 DWORD dwID; | 90 DWORD dwID; |
| 91 HANDLE hThread=CreateThread(NULL,0,SThreadFunc, pInfo, 0, &dwID); | 91 HANDLE hThread=CreateThread(NULL,0,SThreadFunc, pInfo, 0, &dwID); |
| 92 if(hThread){ | 92 if(hThread){ |
| 93 TRACE(_T("RunThread: - new thread=%x\n"),dwID); | |
| 94 ::CloseHandle(hThread); | 93 ::CloseHandle(hThread); |
| 95 rc=true; | 94 rc=true; |
| 96 } else { | 95 } else { |
| 97 ERROR(_T("Failed to create thread\n")); | 96 ERROR(_T("Failed to create thread\n")); |
| 98 } | 97 } |
| 99 #else // UNIX | 98 #else // UNIX |
| 100 #ifdef NO_THREADS | 99 #ifdef NO_THREADS |
| 101 assert(false); | 100 assert(false); |
| 102 #else | 101 #else |
| 103 VTRACE(_T("RunThread():Calling pthread_create()\n")); | |
| 104 pthread_t hThread; | 102 pthread_t hThread; |
| 105 int n=pthread_create(&hThread, NULL, SThreadFunc, pInfo); | 103 int n=pthread_create(&hThread, NULL, SThreadFunc, pInfo); |
| 106 TRACE( _T("RunThread: - non-blocking call (new thread=%x)\n"),hThread); | 104 TRACE( _T("RunThread: - non-blocking call (new thread=%x)\n"),hThread); |
| 107 VTRACE(_T("RunThread(): pthread_create() returned <%d>\n"), n); | |
| 108 if (n != 0) { | 105 if (n != 0) { |
| 109 ERROR(_T("RunThread(): pthread_create failed - %s\n"),strerror(errno)); | 106 ERROR(_T("RunThread(): pthread_create failed - %s\n"),strerror(errno)); |
| 110 } else { | 107 } else { |
| 111 | 108 |
| 112 VTRACE(_T("RunThread(): Calling pthread_detach\n")); | |
| 113 int n = pthread_detach(hThread); | 109 int n = pthread_detach(hThread); |
| 114 | 110 |
| 115 if (0==n) { | 111 if (0==n) { |
| 116 rc=true; | 112 rc=true; |
| 117 } else { | 113 } else { |
| 118 ERROR(_T("RunThread(): pthread_detach failed - %s\n"),strerror(errno)); | 114 ERROR(_T("RunThread(): pthread_detach failed - %s\n"),strerror(errno)); |
| 119 hThread=0; | 115 hThread=0; |
| 120 } | 116 } |
| 121 } | 117 } |
| 122 VTRACE(_T("RunThread(): returned from pthread calls - exiting RunThread()\n")); | |
| 123 #endif | 118 #endif |
| 124 #endif | 119 #endif |
| 125 if(!rc){ | 120 if(!rc){ |
| 126 delete pInfo; | 121 delete pInfo; |
| 127 } | 122 } |
| 147 } | 142 } |
| 148 #endif | 143 #endif |
| 149 | 144 |
| 150 CeCosThreadUtils::THREADFUNC CALLBACK CeCosThreadUtils::SThreadFunc (void *pParam) | 145 CeCosThreadUtils::THREADFUNC CALLBACK CeCosThreadUtils::SThreadFunc (void *pParam) |
| 151 { | 146 { |
| 152 VTRACE(_T("SThreadFunc()\n")); | 147 THREAD_ID id=GetThreadId(); |
| 153 ThreadInfo *pInfo=(ThreadInfo*)pParam; | 148 ThreadInfo *pInfo=(ThreadInfo*)pParam; |
| 149 TRACE(_T("Thread %x [%s] created\n"),id,(LPCTSTR)pInfo->strName); | |
| 154 #ifdef _WIN32 | 150 #ifdef _WIN32 |
| 155 __try { | 151 __try { |
| 156 // Call what we are instructed to (e.g. LocalThreadFunc): | 152 // Call what we are instructed to (e.g. LocalThreadFunc): |
| 157 pInfo->pThreadFunc(pInfo->pThreadParam); | 153 pInfo->pThreadFunc(pInfo->pThreadParam); |
| 158 } | 154 } |
| 169 TRACE(_T("Exception caught in SThreadFunc!!!\n")); | 165 TRACE(_T("Exception caught in SThreadFunc!!!\n")); |
| 170 } | 166 } |
| 171 #endif | 167 #endif |
| 172 | 168 |
| 173 // Call the Callback: | 169 // Call the Callback: |
| 174 TRACE(_T("SThreadFunc - invoking callback\n")); | |
| 175 if(pInfo->pCompletionFunc){ | 170 if(pInfo->pCompletionFunc){ |
| 176 pInfo->pCompletionFunc (pInfo->pCompletionParam); | 171 pInfo->pCompletionFunc (pInfo->pCompletionParam); |
| 177 } else if (pInfo->pCompletionParam) { | 172 } else if (pInfo->pCompletionParam) { |
| 178 // No function - just a flag: | 173 // No function - just a flag: |
| 179 *(bool *)pInfo->pCompletionParam=true; | 174 *(bool *)pInfo->pCompletionParam=true; |
| 180 } | 175 } |
| 181 // No more references to pInfo->pTest from now on... | 176 // No more references to pInfo->pTest from now on... |
| 182 VTRACE(_T("SThreadFunc(): deleting (ThreadInfo)pInfo\n")); | 177 TRACE(_T("Thread %x [%s] terminated\n"),id,(LPCTSTR)pInfo->strName); |
| 183 delete pInfo; | 178 delete pInfo; |
| 184 TRACE(_T("SThreadFunc exiting\n")); | |
| 185 return 0; | 179 return 0; |
| 186 } | 180 } |
| 187 | 181 |
| 188 int CeCosThreadUtils::CS::AtomicIncrement (int &n) | 182 bool CeCosThreadUtils::CS::InCriticalSection() |
| 183 { | |
| 184 return GetThreadId()==nCSOwner; | |
| 185 } | |
| 186 | |
| 187 int CeCosThreadUtils::AtomicIncrement (int &n) | |
| 189 { | 188 { |
| 190 int rc; | 189 int rc; |
| 191 ENTERCRITICAL; | 190 ENTERCRITICAL; |
| 192 rc=n++; | 191 rc=n++; |
| 193 LEAVECRITICAL; | 192 LEAVECRITICAL; |
| 194 return rc; | 193 return rc; |
| 195 } | 194 } |
| 196 | 195 |
| 197 int CeCosThreadUtils::CS::AtomicDecrement (int &n) | 196 int CeCosThreadUtils::AtomicDecrement (int &n) |
| 198 { | 197 { |
| 199 int rc; | 198 int rc; |
| 200 ENTERCRITICAL; | 199 ENTERCRITICAL; |
| 201 rc=n--; | 200 rc=n--; |
| 202 LEAVECRITICAL; | 201 LEAVECRITICAL; |
| 205 | 204 |
| 206 CeCosThreadUtils::CS::CS() | 205 CeCosThreadUtils::CS::CS() |
| 207 { | 206 { |
| 208 // Get mutex lock; block until available unless current | 207 // Get mutex lock; block until available unless current |
| 209 // thread already owns the mutex. | 208 // thread already owns the mutex. |
| 210 if(GetThreadId()!=nCSOwner){ | 209 if(!InCriticalSection()){ |
| 211 VTRACE(_T("%x try CS\n"),GetThreadId()); | |
| 212 #ifdef _WIN32 | 210 #ifdef _WIN32 |
| 213 if(!bCSInitialized){ | 211 if(!bCSInitialized){ |
| 214 InitializeCriticalSection(&cs); | 212 InitializeCriticalSection(&cs); |
| 215 bCSInitialized=true; | 213 bCSInitialized=true; |
| 216 } | 214 } |
| 218 #else // UNIX | 216 #else // UNIX |
| 219 #ifndef NO_THREADS | 217 #ifndef NO_THREADS |
| 220 pthread_mutex_lock(&cs); | 218 pthread_mutex_lock(&cs); |
| 221 #endif | 219 #endif |
| 222 #endif | 220 #endif |
| 221 // As we now own the CS it is safe to perform the following assignment: | |
| 223 nCSOwner=GetThreadId(); | 222 nCSOwner=GetThreadId(); |
| 224 VTRACE(_T("%x has CS count=%d\n"),GetThreadId(),m_nCriticalSectionLock);//sdf | 223 } |
| 225 } | 224 // As we now own the CS it is safe to perform the following increment: |
| 226 m_nCriticalSectionLock++; | 225 m_nCriticalSectionLock++; |
| 227 } | 226 } |
| 228 | 227 |
| 229 CeCosThreadUtils::CS::~CS() | 228 CeCosThreadUtils::CS::~CS() |
| 230 { | 229 { |
| 230 assert(InCriticalSection()); | |
| 231 // As we own the CS we can safely manipulate variables: | |
| 231 m_nCriticalSectionLock--; | 232 m_nCriticalSectionLock--; |
| 232 assert(m_nCriticalSectionLock>=0); | 233 assert(m_nCriticalSectionLock>=0); |
| 233 if(0==m_nCriticalSectionLock){ | 234 if(0==m_nCriticalSectionLock){ |
| 235 // Last lock is being released - let go of the mutex | |
| 234 nCSOwner=(THREAD_ID)-1; | 236 nCSOwner=(THREAD_ID)-1; |
| 235 VTRACE(_T("%x leaves CS count=%d\n"),GetThreadId(),m_nCriticalSectionLock); | |
| 236 | 237 |
| 237 // Release mutex lock. | 238 // Release mutex lock. |
| 238 #ifdef _WIN32 | 239 #ifdef _WIN32 |
| 239 ::LeaveCriticalSection(&cs); | 240 ::LeaveCriticalSection(&cs); |
| 240 #else // UNIX | 241 #else // UNIX |
| 243 #endif | 244 #endif |
| 244 #endif | 245 #endif |
| 245 } | 246 } |
| 246 } | 247 } |
| 247 | 248 |
| 249 void CeCosThreadUtils::Sleep(int nMsec) | |
| 250 { | |
| 251 #ifdef _WIN32 | |
| 252 ::Sleep(nMsec); | |
| 253 #else | |
| 254 sched_yield(); | |
| 255 usleep((int)nMsec * 1000); | |
| 256 #endif | |
| 257 } |
