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 
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 
34  state_(kSIdle),
35  priority_(priority),
36  handle_(0),
37  threadId_(0),
38  cpuAffinity_(-1)
39 {}
40 
42 {
43 #if PRINT_DEBUG
44  ULOGGER_DEBUG("");
45 #endif
46 }
47 
49 {
50 #if PRINT_DEBUG
51  ULOGGER_DEBUG("");
52 #endif
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  }
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
98 #else
99 #if PRINT_DEBUG
100  UDEBUG("Thread %d joining %d", UThreadC<void>::Self(), handle_);
101 #endif
103 #endif
104  {
105  UERROR("Thread cannot join itself");
106  return;
107  }
108 
109  if(killFirst)
110  {
111  this->kill();
112  }
113 
116 
117 #if PRINT_DEBUG
118  UDEBUG("Join ended for %d", UThreadC<void>::Self());
119 #endif
120 }
121 
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
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
157 {
158  priority_ = priority;
159 }
160 
161 //TODO : Support pThread
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
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 
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 
265 {
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 
297 #if PRINT_DEBUG
298  ULOGGER_DEBUG("Exiting thread loop");
299 #endif
300 }
301 
void start()
Definition: UThread.cpp:122
void applyPriority()
Definition: UThread.cpp:162
int lock() const
Definition: UMutex.h:87
virtual void mainLoop()=0
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)
void kill()
Definition: UThread.cpp:48
bool isRunning() const
Definition: UThread.cpp:245
int cpuAffinity_
Definition: UThread.h:265
Priority priority_
Definition: UThread.h:262
bool isCreating() const
Definition: UThread.cpp:240
UThread(Priority priority=kPNormal)
Definition: UThread.cpp:33
UMutex runningMutex_
Definition: UThread.h:267
State state_
Definition: UThread.h:261
UMutex killSafelyMutex_
Definition: UThread.h:266
void setAffinity(int cpu=0)
Definition: UThread.cpp:198
#define ULOGGER_DEBUG(...)
Definition: ULogger.h:53
void ThreadMain()
Definition: UThread.cpp:264
virtual void mainLoopBegin()
Definition: UThread.h:183
bool isKilled() const
Definition: UThread.cpp:255
virtual void mainLoopKill()
Definition: UThread.h:203
void setPriority(Priority priority)
Definition: UThread.cpp:156
virtual void mainLoopEnd()
Definition: UThread.h:211
Priority
Definition: UThread.h:92
void uSleep(unsigned int ms)
#define UDEBUG(...)
int unlock() const
Definition: UMutex.h:113
#define UERROR(...)
ULogger class and convenient macros.
virtual ~UThread()
Definition: UThread.cpp:41
Handle handle_
Definition: UThread.h:263
bool isIdle() const
Definition: UThread.cpp:250
unsigned long threadId_
Definition: UThread.h:264
void applyAffinity()
Definition: UThread.cpp:208
void join(bool killFirst=false)
Definition: UThread.cpp:85


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Dec 14 2020 03:37:06