ThreadImplLxrt38.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of FZIs ic_workspace.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00012 //
00013 // -- END LICENSE BLOCK ------------------------------------------------
00014 
00015 //----------------------------------------------------------------------
00023 //----------------------------------------------------------------------
00024 #include "ThreadImplLxrt38.h"
00025 
00026 #include <icl_core/internal_raw_debug.h>
00027 #include <icl_core/os_lxrt.h>
00028 
00029 #include "Thread.h"
00030 
00031 
00032 namespace icl_core {
00033 namespace logging {
00034 
00035 ThreadImplLxrt38::ThreadImplLxrt38(Thread *thread, icl_core::ThreadPriority priority)
00036   : m_thread_id(0),
00037     m_thread(thread),
00038     m_priority(priority),
00039     m_rt_task(NULL),
00040     m_rt_start_sync(NULL)
00041 {
00042 }
00043 
00044 ThreadImplLxrt38::~ThreadImplLxrt38()
00045 {
00046   // Ensure that the thread is really destroyed.
00047   join();
00048 
00049   if (m_rt_start_sync == NULL)
00050   {
00051     // Nothing to be done here.
00052   }
00053   else
00054   {
00055     rt_sem_delete(m_rt_start_sync);
00056     m_rt_start_sync = NULL;
00057   }
00058 }
00059 
00060 void ThreadImplLxrt38::join()
00061 {
00062   if (m_thread_id == 0)
00063   {
00064     // Nothing to be done here. The thread has already been destroyed.
00065   }
00066   else
00067   {
00068     pthread_join_rt(m_thread_id, NULL);
00069     m_rt_task = NULL;
00070     m_thread_id = 0;
00071   }
00072 }
00073 
00074 bool ThreadImplLxrt38::start()
00075 {
00076   m_rt_start_sync = rt_typed_sem_init(size_t(this), 2, CNT_SEM | PRIO_Q);
00077   if (m_rt_start_sync == NULL)
00078   {
00079     // We cannot proceed if this happens!
00080   }
00081   else
00082   {
00083     if (pthread_create(&m_thread_id, NULL, ThreadImplLxrt38::runThread, this))
00084     {
00085       m_thread_id = 0;
00086       m_rt_task = NULL;
00087 
00088       rt_sem_delete(m_rt_start_sync);
00089       m_rt_start_sync = NULL;
00090     }
00091     else
00092     {
00093       rt_sem_wait_barrier(m_rt_start_sync);
00094     }
00095   }
00096 
00097   return m_thread_id != 0;
00098 }
00099 
00100 void *ThreadImplLxrt38::runThread(void *arg)
00101 {
00102   ThreadImplLxrt38 *self = static_cast<ThreadImplLxrt38*>(arg);
00103 
00104   if (self->m_rt_start_sync == NULL)
00105   {
00106     // Technically, this can never happen because this condition is
00107     // already checked in the Start() function. But who knows!
00108     PRINTF("ERROR: NULL thread start barrier!\n");
00109   }
00110   else
00111   {
00112     self->m_rt_task = rt_task_init(getpid() + pthread_self_rt(), abs(self->m_priority),
00113                                    DEFAULT_STACK_SIZE, 0);
00114     if (self->m_rt_task == NULL)
00115     {
00116       PRINTF("ERROR: Cannot initialize LXRT task %lu!\n", self->m_thread_id);
00117       PRINTF("       Probably another thread with the same name already exists.\n");
00118 
00119       // Let the thread, which started us, continue!
00120       rt_sem_wait_barrier(self->m_rt_start_sync);
00121     }
00122     else
00123     {
00124       if (self->m_priority < 0)
00125       {
00126         rt_make_hard_real_time();
00127         if (!rt_is_hard_real_time(rt_buddy()))
00128         {
00129           PRINTF("ERROR: Setting thread %lu to hard real-time failed!\n", self->m_thread_id);
00130         }
00131         else
00132         {
00133           // Everything worked as expected, so no message here.
00134         }
00135       }
00136       else
00137       {
00138         // This is a soft realtime thread, so nothing additional has
00139         // to be done here.
00140       }
00141 
00142       rt_sem_wait_barrier(self->m_rt_start_sync);
00143 
00144       self->m_thread->runThread();
00145 
00146       // Remark: It does not hurt to call this in a soft realtime
00147       // thread, so just skip the hard realtime test.
00148       rt_make_soft_real_time();
00149     }
00150   }
00151 
00152   return NULL;
00153 }
00154 
00155 }
00156 }


fzi_icl_core
Author(s):
autogenerated on Thu Jun 6 2019 20:22:24