CLAM-Development  1.3
xtime.hxx
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #ifndef __XTIME__
00023 #define __XTIME__
00024 
00025 #ifdef WIN32
00026 #include "CLAM_windows.h" // for FTIME
00027 #undef GetClassName
00028 #else
00029 #include <sys/time.h> // for GetTimeOfDay
00030 #endif
00031 #include <pthread.h>
00032 
00033 // KLUDGE: C11 defines TIME_UTC as macro in time.h
00034 #ifdef TIME_UTC
00035 #undef TIME_UTC
00036 #endif
00037 
00038 namespace CLAM
00039 {
00040 
00041         enum 
00042         {
00043                 TIME_UTC=1,
00044                 TIME_TAI,
00045                 TIME_MONOTONIC,
00046                 TIME_PROCESS,
00047                 TIME_THREAD,
00048                 TIME_LOCAL,
00049                 TIME_SYNC,
00050                 TIME_RESOLUTION
00051         };
00052 
00053         struct xtime
00054         {
00055                 unsigned int sec;
00056                 unsigned int nsec;
00057         };
00058 
00059         inline int xtime_get( xtime* xtp, int clock_type )
00060         {
00061                 if ( clock_type == TIME_UTC )
00062                         {
00063 #ifdef WIN32
00064                                 FILETIME ft;
00065                                 GetSystemTimeAsFileTime(&ft);
00066                                 const unsigned __int64 TIMESPEC_TO_FILETIME_OFFSET = ((unsigned __int64)27111902UL << 32) + (unsigned __int64)3577643008UL;
00067                                 xtp->sec = (int)((*( __int64*)&ft - TIMESPEC_TO_FILETIME_OFFSET) / 10000000);
00068                                 xtp->nsec = (int)((*( __int64*)&ft - TIMESPEC_TO_FILETIME_OFFSET -
00069                                                                    (( __int64)xtp->sec * ( __int64)10000000)) * 100);
00070                                 return clock_type;
00071 #else
00072                                 struct timeval tv;
00073                                 gettimeofday(&tv, 0);
00074                                 xtp->sec = tv.tv_sec;
00075                                 xtp->nsec = tv.tv_usec * 1000;
00076                                 return clock_type;
00077 #endif                   
00078                         }
00079                 return clock_type;
00080         }
00081 
00082 
00083     const int MILLISECONDS_PER_SECOND = 1000;
00084     const int NANOSECONDS_PER_SECOND = 1000000000;
00085     const int NANOSECONDS_PER_MILLISECOND = 1000000;
00086 
00087     const int MICROSECONDS_PER_SECOND = 1000000;
00088     const int NANOSECONDS_PER_MICROSECOND = 1000;
00089 
00090     inline void to_time(int milliseconds, xtime& xt)
00091     {
00092 
00093         xtime_get(&xt, TIME_UTC);
00094 
00095         xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
00096         xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND);
00097 
00098         if (xt.nsec > static_cast<const int>(NANOSECONDS_PER_SECOND))
00099         {
00100             ++xt.sec;
00101             xt.nsec -= NANOSECONDS_PER_SECOND;
00102                 }
00103                 
00104 
00105         
00106     }
00107 
00108 
00109     inline void to_timespec(const xtime& xt, timespec& ts)
00110     {
00111         ts.tv_sec = static_cast<int>(xt.sec);
00112         ts.tv_nsec = static_cast<int>(xt.nsec);
00113         if(ts.tv_nsec > static_cast<const int>(NANOSECONDS_PER_SECOND))
00114         {
00115             ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
00116             ts.tv_nsec %= NANOSECONDS_PER_SECOND;
00117         }
00118     }
00119 
00120     inline void to_time(int milliseconds, timespec& ts)
00121     {
00122         xtime xt;
00123         to_time(milliseconds, xt);
00124         to_timespec(xt, ts);
00125 
00126 
00127                 
00128     }
00129 
00130     inline void to_timespec_duration(const xtime& xt, timespec& ts)
00131     {
00132         xtime cur;
00133         
00134                 xtime_get(&cur, TIME_UTC);
00135         
00136         if (xt.sec < cur.sec || (xt.sec == cur.sec && xt.nsec < cur.nsec))
00137         {
00138             ts.tv_sec = 0;
00139             ts.tv_nsec = 0;
00140         }
00141         else
00142         {
00143             ts.tv_sec = xt.sec - cur.sec;
00144             ts.tv_nsec = xt.nsec - cur.nsec;
00145 
00146             if( ts.tv_nsec < 0 )
00147             {
00148                 ts.tv_sec -= 1;
00149                 ts.tv_nsec += NANOSECONDS_PER_SECOND;
00150             }
00151            if(ts.tv_nsec > static_cast<const int>(NANOSECONDS_PER_SECOND))
00152            {
00153                ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
00154                ts.tv_nsec %= NANOSECONDS_PER_SECOND;
00155            }
00156         }
00157     }
00158 
00159 
00160 
00161 } // end of namespace CLAM
00162 
00163 #endif // XTime.hxx
00164