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 //---------------------------------------------------------------------- 00022 //---------------------------------------------------------------------- 00023 #include "PeriodicThreadImplEmulate.h" 00024 00025 namespace icl_core { 00026 namespace thread { 00027 00028 PeriodicThreadImplEmulate::PeriodicThreadImplEmulate(const icl_core::TimeSpan& period) 00029 : m_period(period) 00030 { 00031 } 00032 00033 PeriodicThreadImplEmulate::~PeriodicThreadImplEmulate() 00034 { 00035 } 00036 00037 bool PeriodicThreadImplEmulate::setPeriod(const icl_core::TimeSpan& period) 00038 { 00039 m_period = period; 00040 return true; 00041 } 00042 00043 void PeriodicThreadImplEmulate::waitPeriod() 00044 { 00045 icl_core::TimeStamp now = ::icl_core::TimeStamp::now(); 00046 icl_core::TimeStamp next_execution_time = m_last_execution_time + m_period; 00047 icl_core::TimeSpan wait_time_left = next_execution_time - now; 00048 00049 // If time has run backwards then set the wait time exactly to 00050 // the period to prevent long waiting times. 00051 if (wait_time_left > m_period) 00052 { 00053 wait_time_left = m_period; 00054 next_execution_time = now + m_period; 00055 } 00056 00057 icl_core::TimeSpan zero_time_span; 00058 struct timespec wait_time; 00059 struct timespec remaining_wait_time; 00060 while (wait_time_left > zero_time_span) 00061 { 00062 wait_time = wait_time_left.timespec(); 00063 icl_core::os::nanosleep(&wait_time, &remaining_wait_time); 00064 wait_time_left = next_execution_time - ::icl_core::TimeStamp::now(); 00065 } 00066 00067 m_last_execution_time = icl_core::TimeStamp::now(); 00068 } 00069 00070 00071 } 00072 }