00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00072
00073
00074
00075
00076 gettimeofday(&tv, NULL);
00077
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
00171
00172
00173
00174
00175
00176
00177
00178
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
00211
00212
00213
00214
00215
00216
00217
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;
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
00288
00289 if ( newElem->deadline > Head->deadline ) {
00290
00291
00292
00293 lastElem = Head;
00294 nextElem = Head->next;
00295
00296
00297 while( nextElem && (newElem->deadline > lastElem->deadline)) {
00298 lastElem = nextElem;
00299 nextElem = nextElem->next;
00300 };
00301
00302
00303
00304 lastElem->next = newElem;
00305 newElem->next = nextElem;
00306 }
00307 else {
00308
00309
00310
00311 newElem->next = Head;
00312 Head = newElem;
00313 }
00314 }
00315 else {
00316
00317
00318 Head = newElem;
00319
00320 };
00321
00322 NumOfDeadlines++;
00323
00324
00325
00326
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
00345
00346 pthread_mutex_lock( &(newElem->mutex) );
00347 pthread_cond_wait( &(newElem->condition), &(newElem->mutex) );
00348
00349 pthread_mutex_unlock( &(newElem->mutex) );
00350
00351
00352
00353 delete( newElem );
00354
00355
00356
00357
00358
00359
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
00380
00381 pthread_mutex_lock( &(newElem->mutex) );
00382 pthread_cond_wait( &(newElem->condition), &(newElem->mutex) );
00383
00384
00385
00386
00387
00388
00389 delete( newElem );
00390
00391
00392
00393
00394
00395
00396 }
00397 else {
00398
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
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 tmpElem = Head;
00427
00428 if( tmpElem ) {
00429
00430 gettimeofday(&now, NULL);
00431
00432 if( now >= tmpElem->deadline ) {
00433
00434
00435 Head = tmpElem->next;
00436 pthread_cond_signal( &(tmpElem->condition) );
00437
00438
00439
00440
00441
00442
00443 NumOfDeadlines--;
00444 }
00445 }
00446 pthread_mutex_unlock( &SequencerMutex );
00447
00448 };
00449
00450
00451 #endif
00452