utilite
src
UThread.cpp
Go to the documentation of this file.
1
/*
2
* utilite is a cross-platform library with
3
* useful utilities for fast and small developing.
4
* Copyright (C) 2010 Mathieu Labbe
5
*
6
* utilite is free library: you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* utilite is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#include "
rtabmap/utilite/UThread.h
"
21
#include "
rtabmap/utilite/ULogger.h
"
22
#ifdef __APPLE__
23
#include <mach/thread_policy.h>
24
#include <mach/mach.h>
25
#endif
26
27
#define PRINT_DEBUG 0
28
30
// public:
32
33
UThread::UThread
(
Priority
priority) :
34
state_(kSIdle),
35
priority_(priority),
36
handle_(0),
37
threadId_(0),
38
cpuAffinity_(-1)
39
{}
40
41
UThread::~UThread
()
42
{
43
#if PRINT_DEBUG
44
ULOGGER_DEBUG
(
""
);
45
#endif
46
}
47
48
void
UThread::kill
()
49
{
50
#if PRINT_DEBUG
51
ULOGGER_DEBUG
(
""
);
52
#endif
53
killSafelyMutex_
.
lock
();
54
{
55
if
(this->
isRunning
())
56
{
57
// Thread is creating
58
while
(
state_
==
kSCreating
)
59
{
60
uSleep
(1);
61
}
62
63
if
(
state_
==
kSRunning
)
64
{
65
state_
=
kSKilled
;
66
67
// Call function to do something before wait
68
mainLoopKill
();
69
}
70
else
71
{
72
UERROR
(
"thread (%d) is supposed to be running..."
,
threadId_
);
73
}
74
}
75
else
76
{
77
#if PRINT_DEBUG
78
UDEBUG
(
"thread (%d) is not running..."
,
threadId_
);
79
#endif
80
}
81
}
82
killSafelyMutex_
.
unlock
();
83
}
84
85
void
UThread::join
(
bool
killFirst)
86
{
87
//make sure the thread is created
88
while
(this->
isCreating
())
89
{
90
uSleep
(1);
91
}
92
93
#ifdef _WIN32
94
#if PRINT_DEBUG
95
UDEBUG
(
"Thread %d joining %d"
,
UThreadC<void>::Self
(),
threadId_
);
96
#endif
97
if
(
UThreadC<void>::Self
() ==
threadId_
)
98
#else
99
#if PRINT_DEBUG
100
UDEBUG
(
"Thread %d joining %d"
,
UThreadC<void>::Self
(),
handle_
);
101
#endif
102
if
(
UThreadC<void>::Self
() ==
handle_
)
103
#endif
104
{
105
UERROR
(
"Thread cannot join itself"
);
106
return
;
107
}
108
109
if
(killFirst)
110
{
111
this->
kill
();
112
}
113
114
runningMutex_
.
lock
();
115
runningMutex_
.
unlock
();
116
117
#if PRINT_DEBUG
118
UDEBUG
(
"Join ended for %d"
,
UThreadC<void>::Self
());
119
#endif
120
}
121
122
void
UThread::start
()
123
{
124
#if PRINT_DEBUG
125
ULOGGER_DEBUG
(
""
);
126
#endif
127
128
if
(
state_
==
kSIdle
||
state_
==
kSKilled
)
129
{
130
if
(
state_
==
kSKilled
)
131
{
132
// make sure it is finished
133
runningMutex_
.
lock
();
134
runningMutex_
.
unlock
();
135
}
136
137
state_
=
kSCreating
;
138
int
r =
UThreadC<void>::Create
(
threadId_
, &
handle_
,
true
);
// Create detached
139
if
(r)
140
{
141
UERROR
(
"Failed to create a thread! errno=%d"
, r);
142
threadId_
=0;
143
handle_
=0;
144
state_
=
kSIdle
;
145
}
146
else
147
{
148
#if PRINT_DEBUG
149
ULOGGER_DEBUG
(
"StateThread::startThread() thread id=%d _handle=%d"
,
threadId_
,
handle_
);
150
#endif
151
}
152
}
153
}
154
155
//TODO : Support pThread
156
void
UThread::setPriority
(
Priority
priority)
157
{
158
priority_
= priority;
159
}
160
161
//TODO : Support pThread
162
void
UThread::applyPriority
()
163
{
164
if
(
handle_
)
165
{
166
#ifdef _WIN32
167
int
p
= THREAD_PRIORITY_NORMAL;
168
switch
(
priority_
)
169
{
170
case
kPLow
:
171
p
= THREAD_PRIORITY_LOWEST;
172
break
;
173
174
case
kPBelowNormal
:
175
p
= THREAD_PRIORITY_BELOW_NORMAL;
176
break
;
177
178
case
kPNormal
:
179
p
= THREAD_PRIORITY_NORMAL;
180
break
;
181
182
case
kPAboveNormal
:
183
p
= THREAD_PRIORITY_ABOVE_NORMAL;
184
break
;
185
186
case
kPRealTime
:
187
p
= THREAD_PRIORITY_TIME_CRITICAL;
188
break
;
189
190
default
:
191
break
;
192
}
193
SetThreadPriority(
handle_
,
p
);
194
#endif
195
}
196
}
197
198
void
UThread::setAffinity
(
int
cpu)
199
{
200
cpuAffinity_
= cpu;
201
if
(
cpuAffinity_
<0)
202
{
203
cpuAffinity_
= 0;
204
}
205
}
206
207
//TODO : Support Windows and linux
208
void
UThread::applyAffinity
()
209
{
210
if
(
cpuAffinity_
>0)
211
{
212
#ifdef _WIN32
213
#elif __APPLE__
214
thread_affinity_policy_data_t affPolicy;
215
affPolicy.affinity_tag =
cpuAffinity_
;
216
kern_return_t
ret
= thread_policy_set(
217
mach_thread_self(),
218
THREAD_AFFINITY_POLICY,
219
(integer_t*) &affPolicy,
220
THREAD_AFFINITY_POLICY_COUNT);
221
if
(
ret
!= KERN_SUCCESS)
222
{
223
UERROR
(
"thread_policy_set returned %d"
,
ret
);
224
}
225
#else
226
/*unsigned long mask = cpuAffinity_;
227
228
if (pthread_setaffinity_np(
229
pthread_self(),
230
sizeof(mask),
231
&mask) <0)
232
{
233
UERROR("pthread_setaffinity_np failed");
234
}
235
}*/
236
#endif
237
}
238
}
239
240
bool
UThread::isCreating
()
const
241
{
242
return
state_
==
kSCreating
;
243
}
244
245
bool
UThread::isRunning
()
const
246
{
247
return
state_
==
kSRunning
||
state_
==
kSCreating
;
248
}
249
250
bool
UThread::isIdle
()
const
251
{
252
return
state_
==
kSIdle
;
253
}
254
255
bool
UThread::isKilled
()
const
256
{
257
return
state_
==
kSKilled
;
258
}
259
261
// private:
263
264
void
UThread::ThreadMain
()
265
{
266
runningMutex_
.
lock
();
267
applyPriority
();
268
applyAffinity
();
269
270
#if PRINT_DEBUG
271
ULOGGER_DEBUG
(
"before mainLoopBegin()"
);
272
#endif
273
274
state_
=
kSRunning
;
275
mainLoopBegin
();
276
277
#if PRINT_DEBUG
278
ULOGGER_DEBUG
(
"before mainLoop()"
);
279
#endif
280
281
while
(
state_
==
kSRunning
)
282
{
283
mainLoop
();
284
}
285
286
#if PRINT_DEBUG
287
ULOGGER_DEBUG
(
"before mainLoopEnd()"
);
288
#endif
289
290
mainLoopEnd
();
291
292
handle_
= 0;
293
threadId_
= 0;
294
state_
=
kSIdle
;
295
296
runningMutex_
.
unlock
();
297
#if PRINT_DEBUG
298
ULOGGER_DEBUG
(
"Exiting thread loop"
);
299
#endif
300
}
301
UMutex::lock
int lock() const
Definition:
UMutex.h:87
UThread::kSKilled
@ kSKilled
Definition:
UThread.h:260
UThread::kSCreating
@ kSCreating
Definition:
UThread.h:260
UThread::setPriority
void setPriority(Priority priority)
Definition:
UThread.cpp:156
ret
int ret
UThread::priority_
Priority priority_
Definition:
UThread.h:262
UMutex::unlock
int unlock() const
Definition:
UMutex.h:113
UThread::kPLow
@ kPLow
Definition:
UThread.h:92
UThread::kPBelowNormal
@ kPBelowNormal
Definition:
UThread.h:92
UThread::applyAffinity
void applyAffinity()
Definition:
UThread.cpp:208
UThread::join
void join(bool killFirst=false)
Definition:
UThread.cpp:85
UThread::kPNormal
@ kPNormal
Definition:
UThread.h:92
UThread::applyPriority
void applyPriority()
Definition:
UThread.cpp:162
UThread::state_
State state_
Definition:
UThread.h:261
UThreadC::Create
static int Create(const Handler &Function, Thread_C_R Param, Handle *const &H=0, const bool &CreateDetached=false, const unsigned int &StackSize=0, const bool &CancelEnable=false, const bool &CancelAsync=false)
Definition:
Posix/UThreadC.h:97
UThread::mainLoop
virtual void mainLoop()=0
ULOGGER_DEBUG
#define ULOGGER_DEBUG(...)
Definition:
ULogger.h:53
UThread::Priority
Priority
Definition:
UThread.h:92
UThread::ThreadMain
void ThreadMain()
Definition:
UThread.cpp:264
UThread::kPAboveNormal
@ kPAboveNormal
Definition:
UThread.h:92
UThread::isKilled
bool isKilled() const
Definition:
UThread.cpp:255
UThread::UThread
UThread(Priority priority=kPNormal)
Definition:
UThread.cpp:33
UThread::kSIdle
@ kSIdle
Definition:
UThread.h:260
UThread::kill
void kill()
Definition:
UThread.cpp:48
UThread::mainLoopEnd
virtual void mainLoopEnd()
Definition:
UThread.h:211
UThread::start
void start()
Definition:
UThread.cpp:122
p
Point3_ p(2)
UThread::setAffinity
void setAffinity(int cpu=0)
Definition:
UThread.cpp:198
UThread::isIdle
bool isIdle() const
Definition:
UThread.cpp:250
UThreadC
Definition:
Posix/UThreadC.h:66
ULogger.h
ULogger class and convenient macros.
UThread::mainLoopKill
virtual void mainLoopKill()
Definition:
UThread.h:203
UThread::runningMutex_
UMutex runningMutex_
Definition:
UThread.h:267
UThread::cpuAffinity_
int cpuAffinity_
Definition:
UThread.h:265
UThread::kSRunning
@ kSRunning
Definition:
UThread.h:260
UThread::~UThread
virtual ~UThread()
Definition:
UThread.cpp:41
UThread::handle_
Handle handle_
Definition:
UThread.h:263
UThread.h
UDEBUG
#define UDEBUG(...)
uSleep
void uSleep(unsigned int ms)
Definition:
Posix/UThreadC.h:23
UThread::mainLoopBegin
virtual void mainLoopBegin()
Definition:
UThread.h:183
UThread::kPRealTime
@ kPRealTime
Definition:
UThread.h:92
UThread::isRunning
bool isRunning() const
Definition:
UThread.cpp:245
UThread::isCreating
bool isCreating() const
Definition:
UThread.cpp:240
UERROR
#define UERROR(...)
UThread::killSafelyMutex_
UMutex killSafelyMutex_
Definition:
UThread.h:266
UThread::threadId_
unsigned long threadId_
Definition:
UThread.h:264
rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jul 25 2024 02:50:23