/* * This Software is the original work of Daniel TUNG * This Software is submitted in partial fulfillment of the * requirements for the degree of BCSE. * Dept. Computer Science, Monash University 2000 * * Copyright (c) 2000 beetung@cs.monash.edu.au * beetung@geocities.com */ #ifndef TIMER_H #define TIMER_H #include extern "C" { #include #include #include }; //// //// Timer class, allows both "Count Down", and "Start-Stop Watch" //// behavior. How to change the behaviour of a Timer object: //// //////////////////////////////////////// class Timer { //////////////////////////////////////// //// //// "Count Down" - initialize with a value, ie Timer a(1.2), will //// cause a.isZero() to return after 1.2s. //// refer to end of this file for more info //// //// "Start-Stop Watch" - initialize with no value, ie Timer t(). then //// t.start() will begin timing, ie: stores the //// current time, and t.stop() will end the timer //// cout << t; will show the total elisped time //// private: bool started; // timer started? const bool revCount; // are we counting down?? double _timer; // timer double sec2wait; // second to wait struct timeval tv; // public: Timer() : started(false),revCount(false) {;} Timer(double t) : started(false),revCount(true), sec2wait(t) {;} Timer(int t) : started(false),revCount(true), sec2wait(static_cast(t)){;} Timer(float t) : started(false),revCount(true), sec2wait(static_cast(t)){;} private: /// /// mark the current exact time /// //------------------------ double readClock() { //------------------------ if( gettimeofday(&tv, (struct timezone *)NULL) == -1) { cerr << " ERROR : gettimeofday(...) ...inside Timer::readClock()" << endl; exit(-1); } return (tv.tv_sec + (tv.tv_usec *.000001 )); } /// /// various Timer/Clock related routines... /// //----------------------------- inline void startTimer() { _timer = readClock(); } inline void endTimer() { _timer = readClock() - _timer; } //----------------------------- public: //------------------------ inline void start() { started = true; startTimer(); } inline void stop() { started =false; endTimer(); } inline void reset() { started =false; _timer = -1; } //------------------------ //----------------------------- operator float (void) { //----------------------------- return (readClock() -_timer); /* if (revCount) return (readClock() -_timer); else return (_timer); */ } //----------------------------- friend ostream& operator << (ostream& os, Timer &t) { //----------------------------- return os << t.readClock() -t._timer; /* if (t.revCount) return os << t.readClock() -t._timer; else return os << t._timer; */ } private: /// /// has enuff time indicated by sec2wait elisped already ? /// //----------------------------- inline bool isExpired() { //----------------------------- cerr << "."; return (bool)( (readClock()- _timer) > sec2wait); } /// /// Too much CPU time to waste?, spin check! /// //----------------------------- inline bool isZero_SpinLock() { //----------------------------- if (!started) start(); while( !isExpired() ) ; // spin return true; } /// /// This one would _block_ until sec2wait Seconds has passed /// then return, invoked by this->isZero() normally.. //----------------------------- inline bool isZero_blocking() { //----------------------------- if (!started) start(); int sleepTimeInSec = static_cast( sec2wait ) ; double sleepTimeInUsec = sec2wait - sleepTimeInSec; // cout << "sleepTimeInSec ("<< sleepTimeInSec << ") " << endl; // cout << "sleepTimeInUsec ("<< sleepTimeInUsec << ") " << endl; struct timespec nanoTime; nanoTime.tv_sec = (time_t)sleepTimeInSec; nanoTime.tv_nsec= (long)(sleepTimeInUsec*1000000000); cout << "Sec ("<< nanoTime.tv_sec << ") - " << "nSec ("<< nanoTime.tv_nsec << ") - " ; //<< endl; int itmp; /// /// Finally, invoke nanosleep() to block till enuff time 2 elispe /// while ((itmp=nanosleep(&nanoTime,&nanoTime)) != 0) { cout << "nanosleep(...) returned a value! --> " << itmp << endl << "Sleep Interupted : " << *this << endl; } cout << " InterThread Sleep complete : " << *this << endl; return true; } public: //------------------------ bool block() { return isZero_blocking(); } bool isZero() { //------------------------ if (sec2wait > 10) // Very long Warning cerr << " WARNING : waiting for longer than 10 seconds!!! " << endl; else if (sec2wait > 1000 ) cerr << " WARNING : waiting for longer than 100 seconds!!!" << endl << " mod on usleep(...) not implemented yet!"<< endl; return isZero_blocking(); } }; #endif