/******************************************************************************/ /* */ /* X r d S y s T i m e r . c c */ /* */ /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */ /* Produced by Andrew Hanushevsky for Stanford University under contract */ /* DE-AC02-76-SFO0515 with the Department of Energy */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ #ifndef WIN32 #include #else #include "XrdSys/XrdWin32.hh" #endif #include #include #include #include "XrdSys/XrdSysTimer.hh" #include /******************************************************************************/ /* D e l t a _ T i m e */ /******************************************************************************/ struct timeval *XrdSysTimer::Delta_Time(struct timeval &tbeg) { gettimeofday(&LastReport, 0); LastReport.tv_sec = LastReport.tv_sec - tbeg.tv_sec; LastReport.tv_usec = LastReport.tv_usec - tbeg.tv_usec; if (LastReport.tv_usec < 0) {LastReport.tv_sec--; LastReport.tv_usec += 1000000;} return &LastReport; } /******************************************************************************/ /* M i d n i g h t */ /******************************************************************************/ time_t XrdSysTimer::Midnight(time_t tnow) { struct tm midtime; time_t add_time; // Compute time at midnight // if (tnow == 0 || tnow == 1) {add_time = tnow; tnow = time(0);} else add_time = 0; localtime_r((const time_t *) &tnow, &midtime); if (add_time) {midtime.tm_hour = 23; midtime.tm_min = midtime.tm_sec = 59;} else midtime.tm_hour = midtime.tm_min = midtime.tm_sec = 0; return mktime(&midtime) + add_time; } /******************************************************************************/ /* R e p o r t */ /******************************************************************************/ unsigned long XrdSysTimer::Report() { unsigned long current_time; // Get current time of day // gettimeofday(&LastReport, 0); current_time = (unsigned long)LastReport.tv_sec; // Calculate the time interval thus far // LastReport.tv_sec = LastReport.tv_sec - StopWatch.tv_sec; LastReport.tv_usec = LastReport.tv_usec - StopWatch.tv_usec; if (LastReport.tv_usec < 0) {LastReport.tv_sec--; LastReport.tv_usec += 1000000;} // Return the current time // return current_time; } /******************************************************************************/ unsigned long XrdSysTimer::Report(double &Total_Time) { unsigned long report_time = Report(); // Add up the time as a double // Total_Time += static_cast(LastReport.tv_sec) + static_cast(LastReport.tv_usec/1000)/1000.0; // Return time // return report_time; } /******************************************************************************/ unsigned long XrdSysTimer::Report(unsigned long &Total_Time) { unsigned long report_time = Report(); // Add up the time as a 32-bit value to nearest milliseconds (max = 24 days) // Total_Time += (unsigned long)LastReport.tv_sec*1000 + (unsigned long)(LastReport.tv_usec/1000); // Return time // return report_time; } /******************************************************************************/ unsigned long XrdSysTimer::Report(unsigned long long &Total_Time) { unsigned long report_time = Report(); // Add up the time as a 64-bit value to nearest milliseconds // Total_Time += (unsigned long long)LastReport.tv_sec*1000 + (unsigned long long)(LastReport.tv_usec/1000); // Return time // return report_time; } /******************************************************************************/ unsigned long XrdSysTimer::Report(struct timeval &Total_Time) { unsigned long report_time = Report(); // Add the interval to the interval total time so far // Total_Time.tv_sec += LastReport.tv_sec; Total_Time.tv_usec += LastReport.tv_usec; if (Total_Time.tv_usec > 1000000) {Total_Time.tv_sec++; Total_Time.tv_usec -= 1000000;} // Return time // return report_time; } /******************************************************************************/ /* S n o o z e */ /******************************************************************************/ void XrdSysTimer::Snooze(int sec) { #ifndef WIN32 struct timespec naptime, waketime; // Calculate nano sleep time // naptime.tv_sec = sec; naptime.tv_nsec = 0; // Wait for a lsoppy number of seconds // while(nanosleep(&naptime, &waketime) && EINTR == errno) {naptime.tv_sec = waketime.tv_sec; naptime.tv_nsec = waketime.tv_nsec; } #else ::Sleep(sec*1000); #endif } /******************************************************************************/ /* s 2 h m s */ /******************************************************************************/ char *XrdSysTimer::s2hms(int sec, char *buff, int blen) { int hours, minutes; minutes = sec/60; sec = sec%60; hours = minutes/60; minutes = minutes%60; snprintf(buff, blen-1, "%d:%02d:%02d", hours, minutes, sec); buff[blen-1] = '\0'; return buff; } /******************************************************************************/ /* T i m e Z o n e */ /******************************************************************************/ int XrdSysTimer::TimeZone() { time_t currTime = time(0); time_t currTimeGMT = 0; tm ptm; gmtime_r( &currTime, &ptm ); currTimeGMT = mktime( &ptm ); currTime /= 60*60; currTimeGMT /= 60*60; return currTime - currTimeGMT; } /******************************************************************************/ /* W a i t */ /******************************************************************************/ void XrdSysTimer::Wait(int mills) { #ifndef WIN32 struct timespec naptime, waketime; // Calculate nano sleep time // naptime.tv_sec = mills/1000; naptime.tv_nsec = (mills%1000)*1000000; // Wait for exactly x milliseconds // while(nanosleep(&naptime, &waketime) && EINTR == errno) {naptime.tv_sec = waketime.tv_sec; naptime.tv_nsec = waketime.tv_nsec; } #else ::Sleep(mills); #endif } /******************************************************************************/ /* W a i t 4 M i d n i g h t */ /******************************************************************************/ void XrdSysTimer::Wait4Midnight() { // Wait until midnight arrives // #ifndef __APPLE__ timespec Midnite = {Midnight(1), 0}; while(clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&Midnite,0) == EINTR) {} #else timespec tleft, Midnite = {Midnight(1) - time(0), 0}; int ntpWait = 60; do{while(nanosleep(&Midnite, &tleft) && EINTR == errno) {Midnite.tv_sec = tleft.tv_sec; Midnite.tv_nsec = tleft.tv_nsec; } if (Midnight(1) - time(0) >= 60) break; Midnite.tv_sec = 1; Midnite.tv_nsec = 0; } while(ntpWait--); // This avoids multiple wakeups when NTP adjusts clock #endif }