OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [tools/] [Utils/] [common/] [eCosThreadUtils.cpp] - Blame information for rev 790

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
// ####ECOSHOSTGPLCOPYRIGHTBEGIN####                                        
2
// -------------------------------------------                              
3
// This file is part of the eCos host tools.                                
4
// Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.            
5
//
6
// This program is free software; you can redistribute it and/or modify     
7
// it under the terms of the GNU General Public License as published by     
8
// the Free Software Foundation; either version 2 or (at your option) any   
9
// later version.                                                           
10
//
11
// This program is distributed in the hope that it will be useful, but      
12
// WITHOUT ANY WARRANTY; without even the implied warranty of               
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        
14
// General Public License for more details.                                 
15
//
16
// You should have received a copy of the GNU General Public License        
17
// along with this program; if not, write to the                            
18
// Free Software Foundation, Inc., 51 Franklin Street,                      
19
// Fifth Floor, Boston, MA  02110-1301, USA.                                
20
// -------------------------------------------                              
21
// ####ECOSHOSTGPLCOPYRIGHTEND####                                          
22
#include "eCosThreadUtils.h"
23
#include "eCosTrace.h"
24
 
25
CeCosThreadUtils::THREAD_ID CeCosThreadUtils::CS::nCSOwner=(CeCosThreadUtils::THREAD_ID)-1;
26
int  CeCosThreadUtils::CS::m_nCriticalSectionLock=0;
27
#ifdef _WIN32
28
  CRITICAL_SECTION CeCosThreadUtils::CS::cs;
29
  bool CeCosThreadUtils::CS::bCSInitialized=false;
30
#else // UNIX
31
  // Static recursive mutex for unix critical section
32
  #ifndef NO_THREADS
33
    pthread_mutex_t CeCosThreadUtils::CS::cs = PTHREAD_MUTEX_INITIALIZER;
34
  #endif
35
#endif
36
 
37
 
38
CeCosThreadUtils::THREAD_ID CeCosThreadUtils::GetThreadId()
39
{
40
  return
41
  #ifdef _WIN32
42
    GetCurrentThreadId();
43
  #else // UNIX
44
    #ifdef NO_THREADS
45
    42;
46
    #else
47
    pthread_self();
48
    #endif
49
  #endif
50
}
51
 
52
// Wait for the specified Boolean to turn true or the timeout to occur
53
// The value of the Boolean is returned as result
54
bool CeCosThreadUtils::WaitFor (bool &b, Duration dTimeout)
55
{
56
  Time t=Now();
57
  do {
58
    if(b){
59
      break;
60
    }
61
    Sleep(250);
62
  } while (Now()-t<dTimeout);
63
  return b;
64
}
65
 
66
// This function spawns a thread and causes it to run asynchrously.
67
// The callback may be
68
//      A function, which is called when the thread completes
69
//      A boolean, which is set when the thread completes
70
//      Null, in which case no notification is received of thread completion
71
// pParam is passed to the thread function pThreadFunc on thread initiation.
72
 
73
bool CeCosThreadUtils::RunThread(CallbackProc *pThreadFunc, void *pParam, CallbackProc *pCompletionFunc, void *pCompletionParam, LPCTSTR pszName)
74
{
75
  TRACE(_T("RunThread %s\n"),pszName);
76
  // Do not spawn a thread while in possession of a mutex
77
  //    ENTERCRITICAL;
78
  //        VTRACE(_T("csl=%d\n"),CS::m_nCriticalSectionLock);
79
  //        assert(1==CS::m_nCriticalSectionLock);
80
  //    LEAVECRITICAL;
81
 
82
  ThreadInfo *pInfo=new ThreadInfo(pThreadFunc,pParam,pCompletionFunc,pCompletionParam,pszName); // SThreadFunc will delete
83
  bool rc=false;
84
 
85
#ifdef _WIN32
86
  // FIXME: CreateThread incompatible with C runtime calls?
87
  DWORD dwID;
88
  HANDLE hThread=CreateThread(NULL,0,SThreadFunc, pInfo, 0, &dwID);
89
  if(hThread){
90
    ::CloseHandle(hThread);
91
    rc=true;
92
  } else {
93
    ERROR(_T("Failed to create thread\n"));
94
  }
95
#else // UNIX
96
  #ifdef NO_THREADS
97
  assert(false);
98
  #else
99
  pthread_t hThread;
100
  int n=pthread_create(&hThread, NULL, SThreadFunc, pInfo);
101
  TRACE(  _T("RunThread: - non-blocking call (new thread=%x)\n"),hThread);
102
  if (n != 0) {
103
    ERROR(_T("RunThread(): pthread_create failed - %s\n"),strerror(errno));
104
  } else {
105
 
106
    int n = pthread_detach(hThread);
107
 
108
    if (0==n) {
109
      rc=true;
110
    } else {
111
      ERROR(_T("RunThread(): pthread_detach failed - %s\n"),strerror(errno));
112
      hThread=0;
113
    }
114
  }
115
  #endif
116
#endif
117
  if(!rc){
118
    delete pInfo;
119
  }
120
  return rc;
121
 
122
}
123
 
124
#ifdef _WIN32
125
int CALLBACK CeCosThreadUtils::FilterFunction(EXCEPTION_POINTERS *p)
126
{
127
  EXCEPTION_RECORD *pRec    =p->ExceptionRecord;
128
  TRACE(_T("!!!Exception!!! address=%08x code=%08x\n"),pRec->ExceptionAddress,pRec->ExceptionCode);
129
  /*
130
  CONTEXT          *pContext=p->ContextRecord;
131
  const unsigned char *ESP=(const unsigned char *)pContext->Esp;
132
  for(int i=0;i<16;i++){
133
  TRACE(_T("%08X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n"),ESP,
134
  ESP[0],ESP[1],ESP[2],ESP[3],ESP[4],ESP[5],ESP[6],ESP[7],ESP[8],ESP[9],ESP[10],ESP[11],ESP[12],ESP[13],ESP[14],ESP[15]);
135
  ESP+=16;
136
  }
137
  */
138
  return EXCEPTION_EXECUTE_HANDLER;
139
}
140
#endif
141
 
142
CeCosThreadUtils::THREADFUNC CALLBACK CeCosThreadUtils::SThreadFunc (void *pParam)
143
{
144
  THREAD_ID id=GetThreadId();
145
  ThreadInfo *pInfo=(ThreadInfo*)pParam;
146
  TRACE(_T("Thread %x [%s] created\n"),id,(LPCTSTR)pInfo->strName);
147
#if defined(_WIN32) && !defined(__CYGWIN__)
148
  __try {
149
    // Call what we are instructed to (e.g. LocalThreadFunc):
150
    pInfo->pThreadFunc(pInfo->pThreadParam);
151
  }
152
    __except ( CeCosThreadUtils::FilterFunction(GetExceptionInformation() ))
153
  {
154
    TRACE(_T("Handling exception!!!...\n"));
155
  }
156
#else // UNIX
157
  try {
158
    // Call what we are instructed to (e.g. LocalThreadFunc):
159
    pInfo->pThreadFunc(pInfo->pThreadParam);
160
  }
161
  catch (...){
162
    TRACE(_T("Exception caught in SThreadFunc!!!\n"));
163
  }
164
#endif
165
 
166
  // Call the Callback:
167
  if(pInfo->pCompletionFunc){
168
    pInfo->pCompletionFunc (pInfo->pCompletionParam);
169
  } else if (pInfo->pCompletionParam) {
170
    // No function - just a flag:
171
    *(bool *)pInfo->pCompletionParam=true;
172
  }
173
  // No more references to pInfo->pTest from now on...
174
  TRACE(_T("Thread %x [%s] terminated\n"),id,(LPCTSTR)pInfo->strName);
175
  delete pInfo;
176
  return 0;
177
}
178
 
179
bool CeCosThreadUtils::CS::InCriticalSection()
180
{
181
  return GetThreadId()==nCSOwner;
182
}
183
 
184
int CeCosThreadUtils::AtomicIncrement (int &n)
185
{
186
  int rc;
187
  ENTERCRITICAL;
188
  rc=n++;
189
  LEAVECRITICAL;
190
  return rc;
191
}
192
 
193
int CeCosThreadUtils::AtomicDecrement (int &n)
194
{
195
  int rc;
196
  ENTERCRITICAL;
197
  rc=n--;
198
  LEAVECRITICAL;
199
  return rc;
200
}
201
 
202
CeCosThreadUtils::CS::CS()
203
{
204
  // Get mutex lock; block until available unless current
205
  // thread already owns the mutex.
206
  if(!InCriticalSection()){
207
#ifdef _WIN32
208
    if(!bCSInitialized){
209
                    InitializeCriticalSection(&cs);
210
        bCSInitialized=true;
211
    }
212
    ::EnterCriticalSection(&cs);
213
#else // UNIX
214
    #ifndef NO_THREADS
215
      pthread_mutex_lock(&cs);
216
    #endif
217
#endif
218
    // As we now own the CS it is safe to perform the following assignment:
219
    nCSOwner=GetThreadId();
220
  }
221
  // As we now own the CS it is safe to perform the following increment:
222
  m_nCriticalSectionLock++;
223
}
224
 
225
CeCosThreadUtils::CS::~CS()
226
{
227
  assert(InCriticalSection());
228
  // As we own the CS we can safely manipulate variables:
229
  m_nCriticalSectionLock--;
230
  assert(m_nCriticalSectionLock>=0);
231
  if(0==m_nCriticalSectionLock){
232
    // Last lock is being released - let go of the mutex
233
    nCSOwner=(THREAD_ID)-1;
234
 
235
    // Release mutex lock.  
236
#ifdef _WIN32
237
    ::LeaveCriticalSection(&cs);
238
#else // UNIX
239
    #ifndef NO_THREADS
240
      pthread_mutex_unlock(&cs);
241
    #endif
242
#endif
243
  }
244
}
245
 
246
void CeCosThreadUtils::Sleep(int nMsec)
247
{
248
#ifdef _WIN32
249
  ::Sleep(nMsec);
250
#else
251
  sched_yield();
252
  usleep((int)nMsec * 1000);
253
#endif
254
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.