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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [tools/] [src/] [tools/] [Utils/] [common/] [eCosThreadUtils.cpp] - Blame information for rev 574

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

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

powered by: WebSVN 2.1.0

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