icl_core_thread/ThreadImplLxrt35.cpp
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 // This file is part of FZIs ic_workspace.
5 //
6 // This program is free software licensed under the LGPL
7 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
8 // You can find a copy of this license in LICENSE folder in the top
9 // directory of the source code.
10 //
11 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
12 //
13 // -- END LICENSE BLOCK ------------------------------------------------
14 
15 //----------------------------------------------------------------------
22 //----------------------------------------------------------------------
23 #include "ThreadImplLxrt35.h"
24 
26 #include <icl_core/os_lxrt.h>
27 
28 #include "Thread.h"
29 #include "Logging.h"
30 
31 #define DEFAULT_STACK_SIZE 0x4000
32 
33 namespace icl_core {
34 namespace thread {
35 
37  icl_core::ThreadPriority priority)
38  : m_thread_id(0),
39  m_thread(thread),
40  m_priority(priority),
41  m_description(description),
42  m_rt_task(NULL),
43  m_rt_start_sync(NULL)
44 { }
45 
47 {
48  // Ensure that the thread is really destroyed.
49  join();
50 
51  if (m_rt_start_sync == NULL)
52  {
53  // Nothing to be done here.
54  }
55  else
56  {
57  pthread_barrier_destroy_rt(m_rt_start_sync);
58  delete m_rt_start_sync;
59  m_rt_start_sync = NULL;
60  }
61 }
62 
64 {
65  if (m_thread_id == 0)
66  {
67  // Nothing to be done here. The thread has already been destroyed.
68  }
69  else
70  {
71  pthread_cancel_rt(m_thread_id);
72  pthread_join_rt(m_thread_id, NULL);
73  m_thread_id = 0;
74  m_rt_task = NULL;
75  }
76 }
77 
79 {
80  return m_priority < 0;
81 }
82 
84 {
85  return os::isThisHRT();
86 }
87 
89 {
90  if (m_thread_id == 0)
91  {
92  // Nothing to be done here. The thread has already been destroyed.
93  }
94  else
95  {
96  pthread_join_rt(m_thread_id, NULL);
97  m_thread_id = 0;
98  m_rt_task = NULL;
99  }
100 }
101 
103 {
104  return m_priority;
105 }
106 
107 bool ThreadImplLxrt35::setHardRealtime(bool hard_realtime)
108 {
109  if (hard_realtime && !os::isThisHRT())
110  {
111  rt_make_hard_real_time();
112  return os::isThisHRT();
113  }
114  else if (!hard_realtime && os::isThisHRT())
115  {
116  rt_make_soft_real_time();
117  return !os::isThisHRT();
118  }
119  else
120  {
121  return false;
122  }
123 }
124 
126 {
127  // TODO: Make this work!
128  /*
129  if (m_rt_task != NULL) {
130  int ret = rt_change_prio(m_rt_task, abs(priority));
131  if (ret == 0) {
132  m_priority = priority;
133 
134  if (priority > 0 && IsHardRealtimeThread()) {
135  rt_make_soft_real_time();
136  } else if (priority < 0 && !IsHardRealtimeThread()) {
137  rt_make_hard_real_time();
138  }
139 
140  return true;
141  }
142  }
143  */
144 
145  return false;
146 }
147 
149 {
150  m_rt_start_sync = new (std::nothrow) pthread_barrier_t;
151  if (m_rt_start_sync == NULL)
152  {
153  // We cannot proceed, if this happens!
154  }
155  else
156  {
157  pthread_barrier_init_rt(m_rt_start_sync, NULL, 2);
158 
159  if (pthread_create(&m_thread_id, NULL, ThreadImplLxrt35::runThread, this))
160  {
161  m_thread_id = 0;
162  m_rt_task = NULL;
163 
164  pthread_barrier_destroy_rt(m_rt_start_sync);
165  delete m_rt_start_sync;
166  m_rt_start_sync = NULL;
167  }
168  else
169  {
170  pthread_barrier_wait_rt(m_rt_start_sync);
171  }
172  }
173 
174  return m_thread_id != 0;
175 }
176 
178 {
180 }
181 
183 {
184  ThreadImplLxrt35 *self = static_cast<ThreadImplLxrt35*>(arg);
185 
186  if (self->m_rt_start_sync == NULL)
187  {
188  // Technically, this can never happen because this condition is
189  // already checked in the Start() function. But who knows!
190  PRINTF("ERROR: NULL thread start barrier!\n");
191  }
192  else
193  {
194  self->m_rt_task = rt_task_init(getpid() + pthread_self_rt(), abs(self->m_priority),
195  DEFAULT_STACK_SIZE, 0);
196  if (self->m_rt_task == NULL)
197  {
198  PRINTF("ERROR: Cannot initialize LXRT task %lu!\n", self->m_thread_id);
199  PRINTF(" Probably another thread with the same name already exists.\n");
200 
201  // Let the thread, which started us, continue!
202  pthread_barrier_wait_rt(self->m_rt_start_sync);
203  }
204  else
205  {
206  if (self->m_priority < 0)
207  {
208  rt_make_hard_real_time();
209  if (!rt_is_hard_real_time(rt_buddy()))
210  {
211  PRINTF("ERROR: Setting thread %lu to hard real-time failed!\n", self->m_thread_id);
212  }
213  else
214  {
215  // Everything worked as expected, so no message here.
216  }
217  }
218  else
219  {
220  // This is a soft realtime thread, so nothing additional has
221  // to be done here.
222  }
223 
224  pthread_barrier_wait_rt(self->m_rt_start_sync);
225 
226  self->m_thread->runThread();
227 
228  // Remark: It does not hurt to call this in a soft realtime
229  // thread, so just skip the hard realtime test.
230  rt_make_soft_real_time();
231  }
232  }
233 
234  return NULL;
235 }
236 
237 }
238 }
ICL_CORE_OS_IMPL_NS::ThreadId ThreadId
Definition: os_thread.h:49
virtual bool setPriority(icl_core::ThreadPriority priority)
TimeSpan abs(const TimeSpan &span)
Definition: TimeSpan.h:222
Contains icl_core::thread::ThreadImpl for RTAI/LXRT 3.5.
Contains a system independet PRINTF macro.
Contains logging definitions for the icl_core_thread library.
bool isThisHRT()
Definition: os_lxrt.cpp:159
Contains global LXRT functions.
std::string String
Definition: BaseTypes.h:43
Contains icl_core::thread::Thread.
#define DEFAULT_STACK_SIZE
#define PRINTF
ThreadImplLxrt35(Thread *thread, const icl_core::String &description, icl_core::ThreadPriority priority)
virtual icl_core::ThreadPriority priority() const
int32_t ThreadPriority
Definition: os_thread.h:50
virtual icl_core::ThreadId threadId() const


fzi_icl_core
Author(s):
autogenerated on Mon Jun 10 2019 13:17:58