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 }