-
Notifications
You must be signed in to change notification settings - Fork 103
/
thread.cpp
125 lines (108 loc) · 2.1 KB
/
thread.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <cvd/config.h>
#include <cvd/thread.h>
#include <time.h>
#ifdef WIN32
#include <windows.h>
#endif
namespace CVD {
//Static variables
bool Thread::ourInitializedFlag = false;
pthread_key_t Thread::ourKey;
unsigned int Thread::ourCount;
/** The constructor performs global initialization of the Thread class if necessary. */
Thread::Thread() : myRunningFlag(false), myStopFlag(false)
{
if (!ourInitializedFlag)
{
init();
ourInitializedFlag = true;
}
}
/** Calls stop() and join() if the thread is alive. */
Thread::~Thread()
{
if (isRunning())
{
stop();
join();
}
}
/** Use PThreads to create a new thread. */
void Thread::start(Runnable* runnable)
{
myRunnable = runnable ? runnable : this;
myStopFlag = false;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
ourCount++;
pthread_create(&myID, &attr, threadproc, this);
}
void Thread::stop()
{
myStopFlag = true;
}
bool Thread::shouldStop() const
{
return myStopFlag;
}
bool Thread::isRunning() const
{
return myRunningFlag;
}
void Thread::join()
{
pthread_join(myID,0);
}
pthread_t Thread::getID()
{
return myID;
}
unsigned int Thread::count()
{
return ourCount;
}
Thread* Thread::getCurrent()
{
return (Thread*)pthread_getspecific(ourKey);
}
/** Uses nanosleep. */
void Thread::sleep(unsigned int milli)
{
#ifdef WIN32
Sleep(milli);
#else
struct timespec ts = { milli/1000, (milli%1000)*1000000 };
nanosleep(&ts, 0);
#endif
}
void Thread::yield()
{
#ifdef CVD_HAVE_PTHREAD_YIELD
pthread_yield();
#elif defined(CVD_HAVE_PTHREAD_YIELD_NP)
pthread_yield_np();
#else
//#warning "Thread::yield() not implemented"
#endif
}
bool Thread::init()
{
ourCount = 0;
pthread_key_create(&ourKey,0);
return true;
}
void* Thread::threadproc(void* param)
{
Thread* thread = (Thread*)param;
pthread_setspecific(ourKey, thread);
thread->myRunningFlag = true;
if (thread->myRunnable)
thread->myRunnable->run();
else
thread->run();
thread->myRunningFlag = false;
ourCount--;
return 0;
}
}