icl_core_thread/ThreadImplLxrt38.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 "ThreadImplLxrt38.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  rt_sem_delete(m_rt_start_sync);
58  m_rt_start_sync = NULL;
59  }
60 }
61 
63 {
64  if (m_thread_id == 0)
65  {
66  // Nothing to be done here. The thread has already been destroyed.
67  }
68  else
69  {
70  pthread_cancel_rt(m_thread_id);
71  pthread_join_rt(m_thread_id, NULL);
72  m_thread_id = 0;
73  m_rt_task = NULL;
74  }
75 }
76 
78 {
79  return m_priority < 0;
80 }
81 
83 {
84  return os::isThisHRT();
85 }
86 
88 {
89  if (m_thread_id == 0)
90  {
91  // Nothing to be done here. The thread has already been destroyed.
92  }
93  else
94  {
95  pthread_join_rt(m_thread_id, NULL);
96  m_thread_id = 0;
97  m_rt_task = NULL;
98  }
99 }
100 
102 {
103  return m_priority;
104 }
105 
106 bool ThreadImplLxrt38::setHardRealtime(bool hard_realtime)
107 {
108  if (hard_realtime && !os::isThisHRT())
109  {
110  rt_make_hard_real_time();
111  return os::isThisHRT();
112  }
113  else if (!hard_realtime && os::isThisHRT())
114  {
115  rt_make_soft_real_time();
116  return !os::isThisHRT();
117  }
118  else
119  {
120  return false;
121  }
122 }
123 
125 {
126  // TODO: Make this work!
127  /*
128  if (m_rt_task != NULL) {
129  int ret = rt_change_prio(m_rt_task, abs(priority));
130  if (ret == 0) {
131  m_priority = priority;
132 
133  if (priority > 0 && IsHardRealtimeThread()) {
134  rt_make_soft_real_time();
135  } else if (priority < 0 && !IsHardRealtimeThread()) {
136  rt_make_hard_real_time();
137  }
138 
139  return true;
140  }
141  }
142  */
143 
144  return false;
145 }
146 
148 {
149  m_rt_start_sync = rt_typed_sem_init(size_t(this), 2, CNT_SEM | PRIO_Q);
150  if (m_rt_start_sync == NULL)
151  {
152  // We cannot proceed, if this happens!
153  }
154  else
155  {
156  if (pthread_create(&m_thread_id, NULL, ThreadImplLxrt38::runThread, this))
157  {
158  m_thread_id = 0;
159  m_rt_task = NULL;
160 
161  rt_sem_delete(m_rt_start_sync);
162  m_rt_start_sync = NULL;
163  }
164  else
165  {
166  rt_sem_wait_barrier(m_rt_start_sync);
167  }
168  }
169 
170  return m_thread_id != 0;
171 }
172 
174 {
176 }
177 
179 {
180  ThreadImplLxrt38 *self = static_cast<ThreadImplLxrt38*>(arg);
181 
182  if (self->m_rt_start_sync == NULL)
183  {
184  // Technically, this can never happen because this condition is
185  // already checked in the Start() function. But who knows!
186  PRINTF("ERROR: NULL thread start barrier!\n");
187  }
188  else
189  {
190  self->m_rt_task = rt_task_init(getpid() + pthread_self_rt(), abs(self->m_priority),
191  DEFAULT_STACK_SIZE, 0);
192  if (self->m_rt_task == NULL)
193  {
194  PRINTF("ERROR: Cannot initialize LXRT task %lu!\n", self->m_thread_id);
195  PRINTF(" Probably another thread with the same name already exists.\n");
196 
197  // Let the thread, which started us, continue!
198  rt_sem_wait_barrier(self->m_rt_start_sync);
199  }
200  else
201  {
202  if (self->m_priority < 0)
203  {
204  rt_make_hard_real_time();
205  if (!rt_is_hard_real_time(rt_buddy()))
206  {
207  PRINTF("ERROR: Setting thread %lu to hard real-time failed!\n", self->m_thread_id);
208  }
209  else
210  {
211  // Everything worked as expected, so no message here.
212  }
213  }
214  else
215  {
216  // This is a soft realtime thread, so nothing additional has
217  // to be done here.
218  }
219 
220  rt_sem_wait_barrier(self->m_rt_start_sync);
221 
222  self->m_thread->runThread();
223 
224  // Remark: It does not hurt to call this in a soft realtime
225  // thread, so just skip the hard realtime test.
226  rt_make_soft_real_time();
227  }
228  }
229 
230  return NULL;
231 }
232 
233 }
234 }
ICL_CORE_OS_IMPL_NS::ThreadId ThreadId
Definition: os_thread.h:49
TimeSpan abs(const TimeSpan &span)
Definition: TimeSpan.h:222
virtual icl_core::ThreadPriority priority() const
virtual icl_core::ThreadId threadId() const
Contains a system independet PRINTF macro.
#define DEFAULT_STACK_SIZE
Contains logging definitions for the icl_core_thread library.
ThreadImplLxrt38(Thread *thread, const icl_core::String &description, icl_core::ThreadPriority priority)
bool isThisHRT()
Definition: os_lxrt.cpp:159
Contains global LXRT functions.
virtual bool setPriority(icl_core::ThreadPriority priority)
std::string String
Definition: BaseTypes.h:43
Contains icl_core::thread::Thread.
#define PRINTF
int32_t ThreadPriority
Definition: os_thread.h:50
Contains icl_core::thread::ThreadImpl for RTAI/LXRT 3.8.


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