LCOV - code coverage report
Current view: top level - common - realtime.h (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core c2b6f1024d3a Lines: 14 20 70.0 %
Date: 2019-05-16 09:13:18 Functions: 4 5 80.0 %
Branches: 4 14 28.6 %

           Branch data     Line data    Source code
       1                 :            : /** @file realtime.h
       2                 :            :  *  @brief Functions for handling a time or time interval in a double.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2010,2011,2013,2014,2015 Olly Betts
       5                 :            :  *
       6                 :            :  * This program is free software; you can redistribute it and/or modify
       7                 :            :  * it under the terms of the GNU General Public License as published by
       8                 :            :  * the Free Software Foundation; either version 2 of the License, or
       9                 :            :  * (at your option) any later version.
      10                 :            :  *
      11                 :            :  * This program is distributed in the hope that it will be useful,
      12                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :            :  * GNU General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU General Public License
      17                 :            :  * along with this program; if not, write to the Free Software
      18                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
      19                 :            :  */
      20                 :            : 
      21                 :            : #ifndef XAPIAN_INCLUDED_REALTIME_H
      22                 :            : #define XAPIAN_INCLUDED_REALTIME_H
      23                 :            : 
      24                 :            : #ifndef PACKAGE
      25                 :            : # error config.h must be included first in each C++ source file
      26                 :            : #endif
      27                 :            : 
      28                 :            : #include <cerrno>
      29                 :            : #include <cmath>
      30                 :            : #include <ctime>
      31                 :            : 
      32                 :            : #ifndef __WIN32__
      33                 :            : # ifdef HAVE_FTIME
      34                 :            : #  include <sys/timeb.h>
      35                 :            : # endif
      36                 :            : # ifdef HAVE_GETTIMEOFDAY
      37                 :            : #  include <sys/time.h>
      38                 :            : # endif
      39                 :            : # include "safesysselect.h"
      40                 :            : #else
      41                 :            : # include <sys/types.h>
      42                 :            : # include <sys/timeb.h>
      43                 :            : extern void xapian_sleep_milliseconds(unsigned int millisecs);
      44                 :            : #endif
      45                 :            : 
      46                 :            : namespace RealTime {
      47                 :            : 
      48                 :            : /// Return the current time.
      49                 :    8283841 : inline double now() {
      50                 :            : #ifndef __WIN32__
      51                 :            :     // We prefer clock_gettime() over gettimeofday() over ftime().  This order
      52                 :            :     // favours functions which can return the time with a higher precision.
      53                 :            :     //
      54                 :            :     // Also, POSIX.1-2008 stopped specifying ftime(), and marked gettimeofday()
      55                 :            :     // as obsolete, recommending clock_gettime() instead.
      56                 :            : # if defined HAVE_CLOCK_GETTIME
      57                 :            :     struct timespec ts;
      58         [ +  - ]:    8283841 :     if (usual(clock_gettime(CLOCK_REALTIME, &ts) == 0))
      59                 :    8283841 :         return ts.tv_sec + (ts.tv_nsec * 1e-9);
      60                 :    8283841 :     return double(std::time(NULL));
      61                 :            : # elif defined HAVE_GETTIMEOFDAY
      62                 :            :     struct timeval tv;
      63                 :            :     if (usual(gettimeofday(&tv, NULL) == 0))
      64                 :            :         return tv.tv_sec + (tv.tv_usec * 1e-6);
      65                 :            :     return double(std::time(NULL));
      66                 :            : # elif defined HAVE_FTIME
      67                 :            :     struct timeb tp;
      68                 :            : #  ifdef FTIME_RETURNS_VOID
      69                 :            :     ftime(&tp);
      70                 :            : #  else
      71                 :            :     if (rare(ftime(&tp) != 0))
      72                 :            :         return double(std::time(NULL));
      73                 :            : #  endif
      74                 :            :     return tp.time + (tp.millitm * 1e-3);
      75                 :            : # else
      76                 :            :     return double(std::time(NULL));
      77                 :            : # endif
      78                 :            : #else
      79                 :            :     struct __timeb64 tp;
      80                 :            :     _ftime64(&tp);
      81                 :            :     return tp.time + tp.millitm * 1e-3;
      82                 :            : #endif
      83                 :            : }
      84                 :            : 
      85                 :            : /** Return the end time for a timeout in @a timeout seconds.
      86                 :            :  *
      87                 :            :  *  If @a timeout is 0, that means "no timeout", so 0 is returned.  Otherwise
      88                 :            :  *  the current time plus @a timeout seconds is returned.
      89                 :            :  */
      90                 :    5249070 : inline double end_time(double timeout) {
      91         [ +  + ]:    5249070 :     return (timeout == 0.0 ? timeout : timeout + now());
      92                 :            : }
      93                 :            : 
      94                 :            : #ifndef __WIN32__
      95                 :            : # if defined HAVE_NANOSLEEP || defined HAVE_TIMER_CREATE
      96                 :            : /// Fill in struct timespec from number of seconds in a double.
      97                 :          3 : inline void to_timespec(double t, struct timespec *ts) {
      98                 :            :     double secs;
      99                 :          3 :     ts->tv_nsec = long(std::modf(t, &secs) * 1e9);
     100                 :          3 :     ts->tv_sec = long(secs);
     101                 :          3 : }
     102                 :            : # endif
     103                 :            : 
     104                 :            : /// Fill in struct timeval from number of seconds in a double.
     105                 :          0 : inline void to_timeval(double t, struct timeval *tv) {
     106                 :            :     double secs;
     107                 :          0 :     tv->tv_usec = long(std::modf(t, &secs) * 1e6);
     108                 :          0 :     tv->tv_sec = long(secs);
     109                 :          0 : }
     110                 :            : #else
     111                 :            : // Use a macro to avoid having to pull in winsock2.h just for struct timeval.
     112                 :            : #define to_timeval(T, TV) to_timeval_((T), (TV)->tv_sec, (TV)->tv_usec)
     113                 :            : inline void to_timeval_(double t, long & tv_sec, long & tv_usec) {
     114                 :            :     double secs;
     115                 :            :     tv_usec = long(std::modf(t, &secs) * 1e6);
     116                 :            :     tv_sec = long(secs);
     117                 :            : }
     118                 :            : #endif
     119                 :            : 
     120                 :            : /// Sleep until the time represented by this object.
     121                 :          9 : inline void sleep(double t) {
     122                 :            : #ifndef __WIN32__
     123                 :            : # ifdef HAVE_NANOSLEEP
     124                 :          9 :     double delta = t - RealTime::now();
     125         [ +  - ]:          9 :     if (delta <= 0.0)
     126                 :          9 :         return;
     127                 :            :     struct timespec ts;
     128                 :          0 :     to_timespec(delta, &ts);
     129 [ #  # ][ #  # ]:          0 :     while (nanosleep(&ts, &ts) < 0 && errno == EINTR) { }
         [ #  # ][ #  # ]
     130                 :            : # else
     131                 :            :     double delta;
     132                 :            :     struct timeval tv;
     133                 :            :     do {
     134                 :            :         delta = t - RealTime::now();
     135                 :            :         if (delta <= 0.0)
     136                 :            :             return;
     137                 :            :         to_timeval(delta, &tv);
     138                 :            :     } while (select(0, NULL, NULL, NULL, &tv) < 0 &&
     139                 :            :              (errno == EINTR || errno == EAGAIN));
     140                 :            : # endif
     141                 :            : #else
     142                 :            :     double delta = t - RealTime::now();
     143                 :            :     if (delta <= 0.0)
     144                 :            :         return;
     145                 :            :     while (rare(delta > 4294967.0)) {
     146                 :            :         xapian_sleep_milliseconds(4294967000u);
     147                 :            :         delta -= 4294967.0;
     148                 :            :     }
     149                 :            :     xapian_sleep_milliseconds(unsigned(delta * 1000.0));
     150                 :            : #endif
     151                 :            : }
     152                 :            : 
     153                 :            : }
     154                 :            : 
     155                 :            : #endif // XAPIAN_INCLUDED_REALTIME_H

Generated by: LCOV version 1.11