LCOV - code coverage report
Current view: directory - src/shared/platform/win - time.h (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 31 4 12.9 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2011 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : // Time represents an absolute point in time, internally represented as
       8                 : // microseconds (s/1,000,000) since a platform-dependent epoch.  Each
       9                 : // platform's epoch, along with other system-dependent clock interface
      10                 : // routines, is defined in time_PLATFORM.cc.
      11                 : //
      12                 : // TimeDelta represents a duration of time, internally represented in
      13                 : // microseconds.
      14                 : //
      15                 : // TimeTicks represents an abstract time that is always incrementing for use
      16                 : // in measuring time durations. It is internally represented in microseconds.
      17                 : // It can not be converted to a human-readable time, but is guaranteed not to
      18                 : // decrease (if the user changes the computer clock, Time::Now() may actually
      19                 : // decrease or jump).
      20                 : //
      21                 : // These classes are represented as only a 64-bit value, so they can be
      22                 : // efficiently passed by value.
      23                 : 
      24                 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_TIME_H__
      25                 : #define NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_TIME_H__
      26                 : 
      27                 : namespace NaCl {
      28                 : 
      29                 : class Time;
      30                 : class TimeTicks;
      31                 : 
      32                 : // This unit test does a lot of manual time manipulation.
      33                 : class PageLoadTrackerUnitTest;
      34                 : 
      35                 : // TimeDelta ------------------------------------------------------------------
      36                 : 
      37                 : class TimeDelta {
      38                 :  public:
      39                 :   TimeDelta() : delta_(0) {
      40                 :   }
      41                 : 
      42                 :   // Converts units of time to TimeDeltas.
      43                 :   static TimeDelta FromDays(int64_t days);
      44                 :   static TimeDelta FromHours(int64_t hours);
      45                 :   static TimeDelta FromMinutes(int64_t minutes);
      46                 :   static TimeDelta FromSeconds(int64_t secs);
      47                 :   static TimeDelta FromMilliseconds(int64_t ms);
      48                 :   static TimeDelta FromMicroseconds(int64_t us);
      49                 : 
      50                 :   // Returns the internal numeric value of the TimeDelta object. Please don't
      51                 :   // use this and do arithmetic on it, as it is more error prone than using the
      52                 :   // provided operators.
      53                 :   int64_t ToInternalValue() const {
      54                 :     return delta_;
      55                 :   }
      56                 : 
      57                 :   // Returns the time delta in some unit. The F versions return a floating
      58                 :   // point value, the "regular" versions return a rounded-down value.
      59                 :   int InDays() const;
      60                 :   double InSecondsF() const;
      61                 :   int64_t InSeconds() const;
      62                 :   double InMillisecondsF() const;
      63                 :   int64_t InMilliseconds() const;
      64                 :   int64_t InMicroseconds() const;
      65                 : 
      66               0 :   TimeDelta& operator=(TimeDelta other) {
      67               0 :     delta_ = other.delta_;
      68               0 :     return *this;
      69               0 :   }
      70                 : 
      71                 :   // Computations with other deltas.
      72                 :   TimeDelta operator+(TimeDelta other) const {
      73                 :     return TimeDelta(delta_ + other.delta_);
      74                 :   }
      75                 :   TimeDelta operator-(TimeDelta other) const {
      76                 :     return TimeDelta(delta_ - other.delta_);
      77                 :   }
      78                 : 
      79                 :   TimeDelta& operator+=(TimeDelta other) {
      80                 :     delta_ += other.delta_;
      81                 :     return *this;
      82                 :   }
      83                 :   TimeDelta& operator-=(TimeDelta other) {
      84                 :     delta_ -= other.delta_;
      85                 :     return *this;
      86                 :   }
      87                 :   TimeDelta operator-() const {
      88                 :     return TimeDelta(-delta_);
      89                 :   }
      90                 : 
      91                 :   // Computations with ints, note that we only allow multiplicative operations
      92                 :   // with ints, and additive operations with other deltas.
      93                 :   TimeDelta operator*(int64_t a) const {
      94                 :     return TimeDelta(delta_ * a);
      95                 :   }
      96                 :   TimeDelta operator/(int64_t a) const {
      97                 :     return TimeDelta(delta_ / a);
      98                 :   }
      99                 :   TimeDelta& operator*=(int64_t a) {
     100                 :     delta_ *= a;
     101                 :     return *this;
     102                 :   }
     103                 :   TimeDelta& operator/=(int64_t a) {
     104                 :     delta_ /= a;
     105                 :     return *this;
     106                 :   }
     107                 :   int64_t operator/(TimeDelta a) const {
     108                 :     return delta_ / a.delta_;
     109                 :   }
     110                 : 
     111                 :   // Defined below because it depends on the definition of the other classes.
     112                 :   Time operator+(Time t) const;
     113                 :   TimeTicks operator+(TimeTicks t) const;
     114                 : 
     115                 :   // Comparison operators.
     116                 :   bool operator==(TimeDelta other) const {
     117                 :     return delta_ == other.delta_;
     118                 :   }
     119                 :   bool operator!=(TimeDelta other) const {
     120                 :     return delta_ != other.delta_;
     121                 :   }
     122                 :   bool operator<(TimeDelta other) const {
     123                 :     return delta_ < other.delta_;
     124                 :   }
     125                 :   bool operator<=(TimeDelta other) const {
     126                 :     return delta_ <= other.delta_;
     127                 :   }
     128                 :   bool operator>(TimeDelta other) const {
     129                 :     return delta_ > other.delta_;
     130                 :   }
     131                 :   bool operator>=(TimeDelta other) const {
     132                 :     return delta_ >= other.delta_;
     133                 :   }
     134                 : 
     135                 :  private:
     136                 :   friend class Time;
     137                 :   friend class TimeTicks;
     138                 :   friend TimeDelta operator*(int64_t a, TimeDelta td);
     139                 : 
     140                 :   // Constructs a delta given the duration in microseconds. This is private
     141                 :   // to avoid confusion by callers with an integer constructor. Use
     142                 :   // FromSeconds, FromMilliseconds, etc. instead.
     143               2 :   explicit TimeDelta(int64_t delta_us) : delta_(delta_us) {
     144               2 :   }
     145                 : 
     146                 :   // Delta in microseconds.
     147                 :   int64_t delta_;
     148                 : };
     149                 : 
     150                 : inline TimeDelta operator*(int64_t a, TimeDelta td) {
     151                 :   return TimeDelta(a * td.delta_);
     152                 : }
     153                 : 
     154                 : // Time -----------------------------------------------------------------------
     155                 : 
     156                 : // Represents a wall clock time.
     157                 : class Time {
     158                 :  public:
     159                 :   static const int64_t kMillisecondsPerSecond = 1000;
     160                 :   static const int64_t kMicrosecondsPerMillisecond = 1000;
     161                 :   static const int64_t kNanosecondsPerMicrosecond = 1000;
     162                 :   static const int64_t kMicrosecondsPerSecond = kMicrosecondsPerMillisecond *
     163                 :                                                 kMillisecondsPerSecond;
     164                 :   static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
     165                 :   static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
     166                 :   static const int64_t kMicrosecondsPerDay = kMicrosecondsPerHour * 24;
     167                 :   static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
     168                 : 
     169                 :   // Represents an exploded time that can be formatted nicely. This is kind of
     170                 :   // like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few
     171                 :   // additions and changes to prevent errors.
     172                 :   struct Exploded {
     173                 :     int year;          // Four digit year "2007"
     174                 :     int month;         // 1-based month (values 1 = January, etc.)
     175                 :     int day_of_week;   // 0-based day of week (0 = Sunday, etc.)
     176                 :     int day_of_month;  // 1-based day of month (1-31)
     177                 :     int hour;          // Hour within the current day (0-23)
     178                 :     int minute;        // Minute within the current hour (0-59)
     179                 :     int second;        // Second within the current minute (0-59 plus leap
     180                 :                        //   seconds which may take it up to 60).
     181                 :     int millisecond;   // Milliseconds within the current second (0-999)
     182                 :   };
     183                 : 
     184                 :   // Contains the NULL time. Use Time::Now() to get the current time.
     185               0 :   explicit Time() : us_(0) {
     186               0 :   }
     187                 : 
     188                 :   // Returns true if the time object has not been initialized.
     189                 :   bool is_null() const {
     190                 :     return us_ == 0;
     191                 :   }
     192                 : 
     193                 :   // Returns the current time. Watch out, the system might adjust its clock
     194                 :   // in which case time will actually go backwards. We don't guarantee that
     195                 :   // times are increasing, or that two calls to Now() won't be the same.
     196                 :   static Time Now();
     197                 : 
     198                 :   // Converts to/from time_t in UTC and a Time class.
     199                 :   // TODO(brettw) this should be removed once everybody starts using the |Time|
     200                 :   // class.
     201                 :   static Time FromTimeT(time_t tt);
     202                 :   time_t ToTimeT() const;
     203                 : 
     204                 :   // Converts time to a double which is the number of seconds since epoch
     205                 :   // (Jan 1, 1970).  Webkit uses this format to represent time.
     206                 :   double ToDoubleT() const;
     207                 : 
     208                 : #if NACL_WINDOWS
     209                 :   static Time FromFileTime(FILETIME ft);
     210                 :   FILETIME ToFileTime() const;
     211                 : #endif
     212                 : 
     213                 :   // Converts an exploded structure representing either the local time or UTC
     214                 :   // into a Time class.
     215                 :   static Time FromUTCExploded(const Exploded& exploded) {
     216                 :     return FromExploded(false, exploded);
     217                 :   }
     218               0 :   static Time FromLocalExploded(const Exploded& exploded) {
     219               0 :     return FromExploded(true, exploded);
     220               0 :   }
     221                 : 
     222                 :   // Converts an integer value representing Time to a class. This is used
     223                 :   // when deserializing a |Time| structure, using a value known to be
     224                 :   // compatible. It is not provided as a constructor because the integer type
     225                 :   // may be unclear from the perspective of a caller.
     226                 :   static Time FromInternalValue(int64_t us) {
     227                 :     return Time(us);
     228                 :   }
     229                 : 
     230                 :   // Converts a string representation of time to a Time object.
     231                 :   // An example of a time string which is converted is as below:-
     232                 :   // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified
     233                 :   // in the input string, we assume local time.
     234                 :   // TODO(iyengar) Move the FromString/FromTimeT/ToTimeT/FromFileTime to
     235                 :   // a new time converter class.
     236                 :   // NOTE(gregoryd) - removed to avoid the need in string suppport
     237                 :   // static bool FromString(const wchar_t* time_string, Time* parsed_time);
     238                 : 
     239                 :   // For serializing, use FromInternalValue to reconstitute. Please don't use
     240                 :   // this and do arithmetic on it, as it is more error prone than using the
     241                 :   // provided operators.
     242                 :   int64_t ToInternalValue() const {
     243                 :     return us_;
     244                 :   }
     245                 : 
     246                 :   // Fills the given exploded structure with either the local time or UTC from
     247                 :   // this time structure (containing UTC).
     248                 :   void UTCExplode(Exploded* exploded) const {
     249                 :     return Explode(false, exploded);
     250                 :   }
     251               0 :   void LocalExplode(Exploded* exploded) const {
     252               0 :     return Explode(true, exploded);
     253               0 :   }
     254                 : 
     255                 :   // Rounds this time down to the nearest day in local time. It will represent
     256                 :   // midnight on that day.
     257                 :   Time LocalMidnight() const;
     258                 : 
     259                 :   Time& operator=(Time other) {
     260                 :     us_ = other.us_;
     261                 :     return *this;
     262                 :   }
     263                 : 
     264                 :   // Compute the difference between two times.
     265                 :   TimeDelta operator-(Time other) const {
     266                 :     return TimeDelta(us_ - other.us_);
     267                 :   }
     268                 : 
     269                 :   // Modify by some time delta.
     270                 :   Time& operator+=(TimeDelta delta) {
     271                 :     us_ += delta.delta_;
     272                 :     return *this;
     273                 :   }
     274                 :   Time& operator-=(TimeDelta delta) {
     275                 :     us_ -= delta.delta_;
     276                 :     return *this;
     277                 :   }
     278                 : 
     279                 :   // Return a new time modified by some delta.
     280                 :   Time operator+(TimeDelta delta) const {
     281                 :     return Time(us_ + delta.delta_);
     282                 :   }
     283                 :   Time operator-(TimeDelta delta) const {
     284                 :     return Time(us_ - delta.delta_);
     285                 :   }
     286                 : 
     287                 :   // Comparison operators
     288                 :   bool operator==(Time other) const {
     289                 :     return us_ == other.us_;
     290                 :   }
     291                 :   bool operator!=(Time other) const {
     292                 :     return us_ != other.us_;
     293                 :   }
     294                 :   bool operator<(Time other) const {
     295                 :     return us_ < other.us_;
     296                 :   }
     297                 :   bool operator<=(Time other) const {
     298                 :     return us_ <= other.us_;
     299                 :   }
     300                 :   bool operator>(Time other) const {
     301                 :     return us_ > other.us_;
     302                 :   }
     303                 :   bool operator>=(Time other) const {
     304                 :     return us_ >= other.us_;
     305                 :   }
     306                 : 
     307                 :  private:
     308                 :   friend class TimeDelta;
     309                 : 
     310                 :   // Platform-dependent wall clock interface
     311                 :   static int64_t CurrentWallclockMicroseconds();
     312                 : 
     313                 :   // Initialize or resynchronize the clock.
     314                 :   static void InitializeClock();
     315                 : 
     316                 :   // Explodes the given time to either local time |is_local = true| or UTC
     317                 :   // |is_local = false|.
     318                 :   void Explode(bool is_local, Exploded* exploded) const;
     319                 : 
     320                 :   // Unexplodes a given time assuming the source is either local time
     321                 :   // |is_local = true| or UTC |is_local = false|.
     322                 :   static Time FromExploded(bool is_local, const Exploded& exploded);
     323                 : 
     324               0 :   explicit Time(int64_t us) : us_(us) {
     325               0 :   }
     326                 : 
     327                 :   // The representation of Jan 1, 1970 UTC in microseconds since the
     328                 :   // platform-dependent epoch.
     329                 :   static const int64_t kTimeTToMicrosecondsOffset;
     330                 : 
     331                 :   // Time in microseconds in UTC.
     332                 :   int64_t us_;
     333                 : 
     334                 :   // The initial time sampled via this API.
     335                 :   static int64_t initial_time_;
     336                 : 
     337                 :   // The initial clock counter sampled via this API.
     338                 :   static TimeTicks initial_ticks_;
     339                 : };
     340                 : 
     341               0 : inline Time TimeDelta::operator+(Time t) const {
     342               0 :   return Time(t.us_ + delta_);
     343               0 : }
     344                 : 
     345                 : // TimeTicks ------------------------------------------------------------------
     346                 : 
     347                 : class TimeTicks {
     348                 :  public:
     349              36 :   TimeTicks() : ticks_(0) {
     350              36 :   }
     351                 : 
     352                 :   // TODO(gregoryd): made this constructor public, but might undo this change
     353                 :   // when we cleanup the time-handling code.
     354               0 :   explicit TimeTicks(int64_t ticks) : ticks_(ticks) {
     355               0 :   }
     356                 : 
     357                 :   // Platform-dependent tick count representing "right now."
     358                 :   // The resolution of this clock is ~1-5ms.  Resolution varies depending
     359                 :   // on hardware/operating system configuration.
     360                 :   static TimeTicks Now();
     361                 : 
     362                 :   // Returns a platform-dependent high-resolution tick count. IT IS BROKEN ON
     363                 :   // SOME HARDWARE and is designed to be used for profiling and perf testing
     364                 :   // only (see the impl for more information).
     365                 :   static TimeTicks UnreliableHighResNow();
     366                 : 
     367                 : 
     368                 :   // Returns true if this object has not been initialized.
     369                 :   bool is_null() const {
     370                 :     return ticks_ == 0;
     371                 :   }
     372                 : 
     373               0 :   TimeTicks& operator=(TimeTicks other) {
     374               0 :     ticks_ = other.ticks_;
     375               0 :     return *this;
     376               0 :   }
     377                 : 
     378                 :   // Compute the difference between two times.
     379               0 :   TimeDelta operator-(TimeTicks other) const {
     380               0 :     return TimeDelta(ticks_ - other.ticks_);
     381               0 :   }
     382                 : 
     383                 :   // Modify by some time delta.
     384                 :   TimeTicks& operator+=(TimeDelta delta) {
     385                 :     ticks_ += delta.delta_;
     386                 :     return *this;
     387                 :   }
     388                 :   TimeTicks& operator-=(TimeDelta delta) {
     389                 :     ticks_ -= delta.delta_;
     390                 :     return *this;
     391                 :   }
     392                 : 
     393                 :   // Return a new TimeTicks modified by some delta.
     394                 :   TimeTicks operator+(TimeDelta delta) const {
     395                 :     return TimeTicks(ticks_ + delta.delta_);
     396                 :   }
     397                 :   TimeTicks operator-(TimeDelta delta) const {
     398                 :     return TimeTicks(ticks_ - delta.delta_);
     399                 :   }
     400                 : 
     401                 :   // Comparison operators
     402                 :   bool operator==(TimeTicks other) const {
     403                 :     return ticks_ == other.ticks_;
     404                 :   }
     405                 :   bool operator!=(TimeTicks other) const {
     406                 :     return ticks_ != other.ticks_;
     407                 :   }
     408                 :   bool operator<(TimeTicks other) const {
     409                 :     return ticks_ < other.ticks_;
     410                 :   }
     411                 :   bool operator<=(TimeTicks other) const {
     412                 :     return ticks_ <= other.ticks_;
     413                 :   }
     414                 :   bool operator>(TimeTicks other) const {
     415                 :     return ticks_ > other.ticks_;
     416                 :   }
     417                 :   bool operator>=(TimeTicks other) const {
     418                 :     return ticks_ >= other.ticks_;
     419                 :   }
     420                 : #if NACL_LINUX || NACL_OSX || defined(__native_client__)
     421                 :   void InitTimespec(struct timespec *ts) const;
     422                 : #endif
     423               0 :   int64_t ticks_for_testing() const { return ticks_; }
     424                 :  protected:
     425                 :   friend class TimeDelta;
     426                 :   friend class PageLoadTrackerUnitTest;
     427                 : 
     428                 : 
     429                 :   // Tick count in microseconds.
     430                 :   int64_t ticks_;
     431                 : 
     432                 : #if NACL_WINDOWS
     433                 :   // The function to use for counting ticks.
     434                 :   typedef int (__stdcall *TickFunction)(void);
     435                 :   static TickFunction tick_function_;
     436                 : #endif
     437                 : };
     438                 : 
     439                 : inline TimeTicks TimeDelta::operator+(TimeTicks t) const {
     440                 :   return TimeTicks(t.ticks_ + delta_);
     441                 : }
     442                 : 
     443                 : }  // namespace NaCl
     444                 : 
     445                 : #endif  /* NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_TIME_H__ */

Generated by: LCOV version 1.7