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

DCDT_Time.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 dEVICE cOMMUNITIES dEVELOPMENT tOOLKIT 
00003 
00004 DCDT_Time.h
00005 
00006 COPYRIGHT (C) 2002  Paolo Meriggi (meriggi@ing.unibs.it)
00007           (C) 2003  Cristian Giussani ( cgiussani@fastflow.it )
00008 
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 #ifndef DCDT_TIME_H
00027 #define DCDT_TIME_H
00028 
00029 #include <sys/time.h>
00030 #include <errno.h>
00031 #include <time.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <pthread.h>
00035 #include <DCDT_Defs.h>
00036 
00038 inline void Delay( DCDT_TIME delay_time) {
00039  struct timespec timeout;
00040   
00041   timeout.tv_sec = (delay_time / 1000000);
00042   timeout.tv_nsec = ((long)delay_time % 1000000) * 1000;
00043   
00044   while( nanosleep( &timeout, &timeout )) {
00045     if (errno != EINTR )
00046       break;
00047   };
00048   
00049 };
00050 
00051 inline int DeltaSeconds( struct timeval last, struct timeval now)
00052 {
00053     return (now.tv_sec - last.tv_sec);
00054 };
00055 
00056 inline int DeltaSeconds( struct timespec last, struct timespec now)
00057 {
00058     return (now.tv_sec - last.tv_sec);
00059 };
00060 
00061 inline int DeltaSeconds( DCDT_TIME last, DCDT_TIME now)
00062 {
00063     return (now/1000000 - last/1000000);
00064 };
00065 
00066 
00067 
00068 
00069 inline DCDT_TIME GetTime() {
00070  struct timeval tv;
00071   //  struct timezone tz;
00072   
00073   // impostato a NULL il secondo termine per
00074   // velocizzare la routine
00075   
00076   gettimeofday(&tv, NULL);
00077   //  gettimeofday(&tv, &tz);
00078   
00079   return (tv.tv_sec * 1000000 + tv.tv_usec);
00080 
00081 };
00082 
00083 inline DCDT_TIME tv2DCDT_TIME( struct timeval tv) {
00084 
00085   return ((DCDT_TIME)(tv.tv_sec * 1000000 + tv.tv_usec));
00086 
00087 };
00088 
00089 
00090 inline bool operator < ( struct timeval t1, struct timeval t2 )
00091 {
00092   return t1.tv_sec < t2.tv_sec ||
00093          (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec);
00094 }
00095 
00096 inline bool operator > ( struct timeval t1, struct timeval t2 )
00097 {
00098   return t1.tv_sec > t2.tv_sec ||
00099          (t1.tv_sec == t2.tv_sec && t1.tv_usec > t2.tv_usec);
00100 }
00101 
00102 inline bool operator >= ( struct timeval t1, struct timeval t2) {
00103   return ( (t1.tv_sec > t2.tv_sec ) ||
00104          ( (t1.tv_sec == t2.tv_sec) && (t1.tv_usec >= t2.tv_usec)));
00105 };
00106 
00107 inline bool operator == ( struct timeval t1, struct timeval t2 )
00108 {
00109   return (t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec);
00110 }
00111 
00112 inline timeval operator + ( struct timeval t1, struct timeval t2 )
00113 {
00114   struct timeval tmp;
00115   tmp.tv_sec = t1.tv_sec + t2.tv_sec;
00116   if ( (tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000 ) {
00117     ++tmp.tv_sec;
00118     tmp.tv_usec -= 1000000;
00119   }
00120   return tmp;
00121 }
00122 
00123 inline struct timeval operator + ( struct timeval t1, long t2 )
00124 {
00125   struct timeval tmp;
00126   tmp.tv_sec = t1.tv_sec;
00127   if ( (tmp.tv_usec = t1.tv_usec + t2) >= 1000000 ) {
00128     ++tmp.tv_sec;
00129     tmp.tv_usec -= 1000000;
00130   }
00131   return tmp;
00132 }
00133 
00134 inline struct timeval operator + ( struct timeval t1, DCDT_TIME t2 )
00135 {
00136   struct timeval tmp;
00137   tmp.tv_sec = t1.tv_sec;
00138   if ( (tmp.tv_usec = t1.tv_usec + t2) >= 1000000 ) {
00139     ++tmp.tv_sec;
00140     tmp.tv_usec -= 1000000;
00141   }
00142   return tmp;
00143 };
00144 
00145 inline struct timespec operator + ( struct timespec t1, unsigned int t2 )
00146 {
00147   struct timespec tmp;
00148   tmp.tv_sec = t1.tv_sec;
00149   if ( (tmp.tv_nsec = t1.tv_nsec + t2) >= 1000000000 ) {
00150     ++tmp.tv_sec;
00151     tmp.tv_nsec -= 1000000000;
00152   }
00153   return tmp;
00154 };
00155 
00156 inline struct timeval& operator += ( struct timeval &t1, struct timeval t2 )
00157 {
00158   t1.tv_sec += t2.tv_sec;
00159   if ( (t1.tv_usec += t2.tv_usec) >= 1000000 ) {
00160     ++t1.tv_sec;
00161     t1.tv_usec -= 1000000;
00162   }
00163   return t1;
00164 }
00165 
00166 
00167 
00168 //-----------------------------------------------------------------------------//
00169 /*
00170 inline struct timeval operator - ( struct timeval t1, struct timeval t2 )
00171 {
00172   struct timeval tmp;
00173   tmp.tv_sec = t1.tv_sec - t2.tv_sec;
00174   if ( (tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0 ) {
00175     --tmp.tv_sec;
00176     tmp.tv_usec += 1000000;
00177   }
00178   return tmp;
00179 }
00180 */
00181 
00182 inline long int operator - ( struct timeval t1, struct timeval t2 )
00183 {
00184   struct timeval tmp;
00185   tmp.tv_sec = t1.tv_sec - t2.tv_sec;
00186   if ( (tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0 ){
00187     --tmp.tv_sec;
00188     tmp.tv_usec += 1000000;
00189   }
00190 
00191   printf("diff = %ld sec, %ld usec\n", tmp.tv_sec, tmp.tv_usec);
00192   fflush (stdout);
00193 
00194   return (tmp.tv_usec + (1000000 * tmp.tv_sec));
00195 }
00196 
00197 //-----------------------------------------------------------------------------//
00198 
00199 inline struct timeval& operator -= ( struct timeval t1, struct timeval t2 )
00200 {
00201   t1.tv_sec -= t2.tv_sec;
00202   if ( (t1.tv_usec -= t2.tv_usec) < 0 ) {
00203     --t1.tv_sec;
00204     t1.tv_usec += 1000000;
00205   }
00206   return t1;
00207 }
00208 
00209 /*
00210   bool operator > (struct timeval t1, struct timeval t2);
00211   bool operator < (struct timeval t1, struct timeval t2);
00212   bool operator <= (struct timeval t1, struct timeval t2);
00213   bool operator >= (struct timeval t1, struct timeval t2);
00214   struct timeval operator + (struct timeval t1, struct timeval t2);
00215   struct timeval operator + (struct timeval t1, long );
00216   //struct timeval operator - (struct timeval t1, struct timeval t2 );
00217   long int operator - (struct timeval t1, struct timeval t2 );
00218 */
00219 
00224  class SequencerElem  {
00225   public:
00226   SequencerElem(struct timeval new_deadline) {
00227     deadline = new_deadline;
00228     next = NULL;
00229     pthread_cond_init( &condition, NULL);
00230     pthread_mutex_init( &mutex, NULL );
00231   };
00232 
00233   ~SequencerElem() {
00234     next = NULL;
00235     pthread_mutex_destroy( &mutex );
00236     pthread_cond_destroy( &condition );
00237   };
00238 
00239   struct timeval deadline;
00240   pthread_cond_t condition;
00241   pthread_mutex_t mutex;
00242   SequencerElem *next;
00243 };
00244 
00249 class DCDT_Sequencer {
00250   friend class DCDT_MsgManager;
00251   friend class DCDT_Agora;
00252   friend class DCDT_Member;
00253   public:
00254     DCDT_Sequencer() { Head = NULL; Tail = NULL; NumOfDeadlines = 0;};
00255     ~DCDT_Sequencer() {
00256         SequencerElem *tmpElem;
00257         while( Head ) {
00258           tmpElem = Head;
00259           delete(Head);
00260           Head = tmpElem->next;
00261         }
00262      };
00263 
00264     inline void Wait( DCDT_TIME sleep_time);
00265     inline void Wait( struct timeval deadline );
00266     inline void CheckNextDeadline();
00267 
00268     inline void InsertElem( SequencerElem *newElem);
00269 
00270   private:
00271 
00272     int NumOfDeadlines;
00273 
00274     pthread_mutex_t SequencerMutex;
00275     SequencerElem *Head, *Tail;  //Start and end of the event list
00276 };
00277 
00280 inline void DCDT_Sequencer::InsertElem( SequencerElem * newElem ) {
00281 
00282   SequencerElem *nextElem, *lastElem;
00283 
00284   pthread_mutex_lock( &SequencerMutex );
00285 
00286   if( Head ) {
00287     // there is at least yet one element
00288 
00289     if ( newElem->deadline > Head->deadline ) {
00290       // the element is not the first
00291       // dbg_printf("Sequencer: not the first\n");
00292 
00293       lastElem = Head;
00294       nextElem = Head->next;
00295 
00296       // let's find the right place
00297       while( nextElem && (newElem->deadline > lastElem->deadline)) {
00298           lastElem = nextElem;
00299           nextElem = nextElem->next;
00300       };
00301 
00302       // dbg_printf("Sequencer: among the elements\n");
00303 
00304       lastElem->next = newElem;
00305       newElem->next = nextElem;
00306     }
00307     else {
00308       // we have to insert the new element on the top of the list
00309       // dbg_printf("Sequencer: first of a crowded list\n");
00310 
00311       newElem->next = Head;
00312       Head = newElem;
00313     }
00314   }
00315   else {
00316     // List is empty
00317     // dbg_printf("Sequencer: first of an empty list\n");
00318     Head = newElem;
00319 
00320   };
00321 
00322   NumOfDeadlines++;
00323 
00324 /*
00325   printf("Insert               Sequencer = %d\n", NumOfDeadlines);
00326   fflush(stdout);
00327 */
00328   pthread_mutex_unlock( &SequencerMutex );
00329 }
00330 
00335 inline void DCDT_Sequencer::Wait( DCDT_TIME sleep_time ) {
00336   struct timeval now, deadline;
00337 
00338   gettimeofday( &now, NULL);
00339 
00340   deadline = now + sleep_time;
00341   SequencerElem * newElem = new SequencerElem( deadline );
00342 
00343   InsertElem( newElem );
00344   // now we wait for someone to wake us up
00345 
00346   pthread_mutex_lock( &(newElem->mutex) );
00347   pthread_cond_wait( &(newElem->condition), &(newElem->mutex) );
00348 
00349   pthread_mutex_unlock( &(newElem->mutex) );
00350 
00351   // we are again awake. let's remove the element
00352 
00353   delete( newElem );
00354 
00355 //  NumOfDeadlines--;
00356 
00357 /*
00358   printf("Del               Sequencer = %d\n", NumOfDeadlines);
00359   fflush(stdout);
00360 */
00361 
00362 };
00363 
00368 inline void DCDT_Sequencer::Wait( struct timeval deadline ) {
00369 
00370   struct timeval now;
00371   SequencerElem * newElem;
00372 
00373   gettimeofday( &now, NULL );
00374 
00375   if (deadline > now ) {
00376     newElem = new SequencerElem( deadline );
00377 
00378     InsertElem( newElem );
00379     // now we wait for someone to wake us up
00380 
00381     pthread_mutex_lock( &(newElem->mutex) );
00382     pthread_cond_wait( &(newElem->condition), &(newElem->mutex) );
00383 
00384     // unlock was automatically done by cond_wait
00385     // pthread_mutex_unlock( &(newElem->mutex) );
00386 
00387     // we are again awake. let's remove the element
00388 
00389     delete( newElem );
00390 
00391     //  NumOfDeadlines--;
00392     /*
00393     printf("Del               Sequencer = %d\n", NumOfDeadlines);
00394       fflush(stdout);
00395     */
00396   }
00397   else {
00398   //  dbg_printf("**** Missed deadline. No more delay. returning *****\n");
00399 
00400   }
00401 };
00402 
00407 inline void DCDT_Sequencer::CheckNextDeadline() {
00408   struct timeval now;
00409   SequencerElem * tmpElem;
00410 
00411 
00412   pthread_mutex_lock( &SequencerMutex );
00413 
00414   /*
00415   tmpElem = Head;
00416 
00417   int i = 1;
00418   while( tmpElem ) {
00419     printf("-|%d|-", i++);
00420     tmpElem = tmpElem->next;
00421     }
00422   printf("\n");
00423   fflush(stdout);
00424 
00425   */
00426   tmpElem = Head;
00427 
00428   if( tmpElem ) {
00429 
00430      gettimeofday(&now, NULL);
00431 
00432      if( now >= tmpElem->deadline ) {
00433       // time is elapsed: let's signal it
00434 
00435       Head = tmpElem->next;
00436       pthread_cond_signal( &(tmpElem->condition) );
00437 
00438       // and now let's remove the Synchro elem from
00439       // the list. We actually not delete it.
00440       // it's up to the thread who requested the service to
00441       // do it
00442 
00443       NumOfDeadlines--;
00444     }
00445   }
00446   pthread_mutex_unlock( &SequencerMutex );
00447 
00448 };
00449 
00450 
00451 #endif
00452  

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