Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

DCDT_Member.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 dEVICE cOMMUNITIES dEVELOPMENT tOOLKIT 
00003 
00004 DCDT_Member.cpp
00005 
00006 COPYRIGHT (C) 2002  Paolo Meriggi (meriggi@ing.unibs.it)
00007                     Alessandro Mazzini (mazzini@airlab.elet.polimi.it)
00008                     Cristian Giussani (cgiussani@fastflow.it)
00009 
00010 This library is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU Lesser General Public
00012 License as published by the Free Software Foundation; either
00013 version 2 of the License, or (at your option) any later version.
00014 
00015 This library is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 Lesser General Public License for more details.
00019 
00020 You should have received a copy of the GNU Lesser General Public
00021 License along with this library; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
00023 
00024 ****************************************************************************/
00025 
00026 
00027 #ifndef DCDT_MEMBER_CPP
00028 #define DCDT_MEMBER_CPP
00029 
00030 #include <DCDT_Member.h>
00031 #include <DCDT_Agora.h>
00032 #include <DCDT_Finder.h>
00033 
00034 extern "C" void *ThreadStartRoutine( void * arg)
00035 {
00036   DCDT_Member* M = (DCDT_Member *) arg;
00037   TRC_PRINT( DCDT_TRC_MEMBER, TRC1, ("ThreadStartRoutine Invoked for Member %d", M->ReadID()));
00038 
00039   // Hook to the method that manages DCDT_Member
00040   // Needed to access DCDT_Member protected part
00041   // TODO: review
00042   return M->LifeCycle();
00043 };
00044 
00045 DCDT_Member::DCDT_Member(DCDT_Agora *agora, DCDT_TIME period ) {
00046   myAgora = agora;
00047 
00048   myAgora->ReadIPStrAddr(myIPAddr);
00049   ExecTime = 0;
00050   Period = period;
00051 
00052 };
00053 
00054 DCDT_Member::DCDT_Member(DCDT_Agora *agora) {
00055   myAgora = agora;
00056   
00057   myAgora->ReadIPStrAddr(myIPAddr);
00058   ExecTime = 0;
00059   Period = 0;
00060 };
00061 
00062 DCDT_Member::~DCDT_Member()
00063 {
00064 };
00065 
00068 int DCDT_Member::Activate( const char *thd_name ) {
00069   
00070   int ret_crea;
00071   struct sched_param sparam;
00072   
00073   if ( thd_name == NULL )
00074     thd_name = typeid(*this).name();
00075 
00076   ret_crea = pthread_create( &myThread, NULL, \
00077                              ThreadStartRoutine, (void *) this );
00078   
00079   if ( ret_crea ) {
00080     TRC_ERROR ( DCDT_TRC_MEMBER, ( "Cannot create DCDT_Member thread %d '%s'", myID, thd_name ) );
00081     return FAILURE;
00082   }
00083   else {
00084     TRC_PRINT ( DCDT_TRC_MEMBER, TRC0, ( "Member thread %d '%s' created", myID, thd_name ));
00085   };
00086 
00087   TRC_ADD_THREAD ( thd_name, myThread );
00088 
00089   // Set maximum priority for the new thread
00090   sparam.sched_priority = sched_get_priority_max(SCHED_RR);
00091   
00092   // Set scheduling policy to realtime - round robin 
00093   pthread_setschedparam( myThread, SCHED_RR,  &sparam);
00094   
00095   // ??? Use detach or pthread_join
00096   //pthread_detach( myThread );
00097   
00098   return SUCCESS;
00099 };
00100 
00110 inline void * DCDT_Member::LifeCycle() {
00111  
00112   StartTime = GetTime();
00113 
00114   myAgora->SetActive( myID );
00115 
00116   // Member initialization
00117   Status = INITIALIZING;
00118   Init();
00119   
00120   // Now we are ready
00121   Status = READY;
00122   
00123   // When the Agora is working we can start
00124   while( myAgora->GetStatus() != (int) DCDT_LETSWORK )
00125     Delay(20000);
00126 
00127   Status = RUNNING;
00128 
00129   // Execute our job
00130   Run();
00131   
00132   Close();
00133   
00134   myAgora->SetInactive( myID);
00135 
00136   // Terminate our thread
00137   pthread_exit(NULL);
00138 
00139   return SUCCESS;
00140 };
00141 
00142 inline void DCDT_Member::Suspend() {
00143 
00144 };
00145 
00148 inline void DCDT_Member::Run() {
00149 
00150   DCDT_TIME start, last;
00151 
00152 #ifdef NANOSLEEP_VERSION
00153 
00154   DCDT_TIME before_delay,  delta;
00155   TRC_PRINT( DCDT_TRC_MEMBER, TRC1, ("Member %d now running", myID));
00156 
00157   int oldtype;
00158   pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, &oldtype);
00159 
00160   last = StartTime;
00161   while( (Status == RUNNING) && (myAgora->GetStatus() == DCDT_LETSWORK) )   {
00162     start = GetTime();
00163     CycleTime = start-last;
00164     last = start;
00165 
00166     DoYourJob();
00167 
00168     pthread_testcancel();
00169 
00170     before_delay = GetTime();
00171     ExecTime = before_delay - start;
00172 
00173     // If this member is periodic we have to wait the next period
00174     if( Period && (ExecTime < Period) ) {
00175 
00176       delta = Period - ExecTime - NANOBIAS;
00177       if (delta > 0)
00178         Wait( delta);
00179 
00180     }
00181 
00182     //TRC_PRINT( DCDT_TRC_MEMBER, TRC1, ("Member %d\t period=%d, ExecTime=%d", myID , CycleTime, ExecTime));
00183   }
00184 #endif
00185 
00186 #ifdef SEQUENCER_VERSION
00187 
00188   DCDT_TIME before_delay, actual_delay, delta;
00189 
00190   TRC_PRINT( DCDT_TRC_MEMBER, TRC1, ("Member %d now running", myID));
00191 
00192   gettimeofday(&deadline, NULL);
00193   StartTime = tv2DCDT_TIME( deadline );
00194 
00195   // if this is a periodic member
00196   if (Period) {
00197     deadline = deadline + Period;
00198     Wait( deadline );
00199   }
00200 
00201   last = StartTime;
00202   while( (Status == RUNNING) && (myAgora->GetStatus() == DCDT_LETSWORK) )   {
00203     gettimeofday(&deadline, NULL);
00204 
00205     start = tv2DCDT_TIME( deadline);
00206     CycleTime = start-last;
00207     last = start;
00208 
00209     DoYourJob();
00210 
00211     pthread_testcancel();
00212 
00213     before_delay = GetTime();
00214     ExecTime = before_delay - start;
00215 
00216     if( Period ) {
00217       deadline = deadline + Period;
00218       Wait( deadline );
00219     }
00220 
00221     //TRC_PRINT( DCDT_TRC_MEMBER, TRC1, ("Member %d\t period=%d, ExecTime=%d", myID , CycleTime, ExecTime));
00222   }
00223 #endif
00224 
00225   TRC_PRINT( DCDT_TRC_MEMBER, TRC1, ("DCDT_Member::Run()- exit -  Member %d", myID ));
00226 };
00227 
00228 #ifndef SEQUENCER_VERSION
00229 inline void DCDT_Member::Wait( DCDT_TIME sleep_time) {
00230 
00231   Delay( sleep_time );
00232 
00233 };
00234 
00235 inline void DCDT_Member::Wait( struct timeval deadline ) {
00236   struct timeval now;
00237   DCDT_TIME delay_time;
00238   gettimeofday(&now, NULL);
00239 
00240   delay_time = deadline - now;
00241   if (delay_time > 0)
00242     Delay( delay_time);
00243 };
00244 
00245 #else
00246 inline void DCDT_Member::Wait( DCDT_TIME sleep_time) {
00247   mySequencer->Wait( sleep_time );
00248 };
00249 
00250 inline void DCDT_Member::Wait( struct timeval deadline ) {
00251   mySequencer->Wait( deadline );
00252 };
00253 #endif
00254 
00255 #endif

Generated on Sun Jun 19 10:35:50 2005 for dcdt by  doxygen 1.3.9.1