time.cc revision 8869
1720SN/A/*
21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
3720SN/A * All rights reserved.
4720SN/A *
5720SN/A * Redistribution and use in source and binary forms, with or without
6720SN/A * modification, are permitted provided that the following conditions are
7720SN/A * met: redistributions of source code must retain the above copyright
8720SN/A * notice, this list of conditions and the following disclaimer;
9720SN/A * redistributions in binary form must reproduce the above copyright
10720SN/A * notice, this list of conditions and the following disclaimer in the
11720SN/A * documentation and/or other materials provided with the distribution;
12720SN/A * neither the name of the copyright holders nor the names of its
13720SN/A * contributors may be used to endorse or promote products derived from
14720SN/A * this software without specific prior written permission.
15720SN/A *
16720SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17720SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18720SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19720SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20720SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21720SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22720SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23720SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24720SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25720SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26720SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
292665Ssaidi@eecs.umich.edu */
30720SN/A
31720SN/A#include <cstdlib>
322518SN/A#include <ctime>
332683Sktlim@umich.edu#include <iostream>
341070SN/A#include <sstream>
352518SN/A
362518SN/A#include "base/time.hh"
37720SN/A#include "config/use_posix_clock.hh"
382107SN/A#include "sim/core.hh"
392107SN/A#include "sim/serialize.hh"
40720SN/A
412680Sktlim@umich.eduusing namespace std;
42720SN/A
432680Sktlim@umich.eduvoid
44720SN/ATime::_set(bool monotonic)
45720SN/A{
462680Sktlim@umich.edu#if USE_POSIX_CLOCK
47720SN/A    ::clock_gettime(monotonic ? CLOCK_MONOTONIC : CLOCK_REALTIME, &_time);
482680Sktlim@umich.edu#else
492680Sktlim@umich.edu    timeval tv;
502518SN/A    ::gettimeofday(&tv, NULL);
512680Sktlim@umich.edu    operator=(tv);
52720SN/A#endif
532680Sktlim@umich.edu}
54720SN/A
552518SN/Avoid
56720SN/ATime::setTick(Tick ticks)
57720SN/A{
58720SN/A    uint64_t nsecs = ticks / SimClock::Int::ns;
591885SN/A    set(nsecs / NSEC_PER_SEC, nsecs % NSEC_PER_SEC);
601885SN/A}
611885SN/A
62720SN/ATick
63720SN/ATime::getTick() const
64720SN/A{
65720SN/A    return (nsec() + sec() * NSEC_PER_SEC) * SimClock::Int::ns;
662680Sktlim@umich.edu}
67720SN/A
682680Sktlim@umich.edustring
69720SN/ATime::date(const string &format) const
70720SN/A{
712680Sktlim@umich.edu    time_t sec = this->sec();
721070SN/A    char buf[256];
73720SN/A
741070SN/A    if (format.empty()) {
752680Sktlim@umich.edu#ifdef __SUNPRO_CC
761070SN/A        ctime_r(&sec, buf, sizeof(buf));
772680Sktlim@umich.edu#else
782680Sktlim@umich.edu        ctime_r(&sec, buf);
792680Sktlim@umich.edu#endif
801096SN/A        buf[24] = '\0';
81720SN/A        return buf;
821082SN/A    }
831082SN/A
842680Sktlim@umich.edu    struct tm *tm = localtime(&sec);
851082SN/A    strftime(buf, sizeof(buf), format.c_str(), tm);
862680Sktlim@umich.edu    return buf;
872680Sktlim@umich.edu}
881082SN/A
891082SN/Astring
901082SN/ATime::time() const
912680Sktlim@umich.edu{
921082SN/A    double time = double(*this);
931082SN/A    double secs = fmod(time, 60.0);
941082SN/A    double all_mins = floor(time / 60.0);
952680Sktlim@umich.edu    double mins = fmod(all_mins, 60.0);
962680Sktlim@umich.edu    double hours = floor(all_mins / 60.0);
971082SN/A
98    stringstream str;
99
100    if (hours > 0.0) {
101        if (hours < 10.0)
102            str << '0';
103        str << hours << ':';
104    }
105
106    if (mins > 0.0) {
107        if (mins < 10.0)
108            str << '0';
109        str << mins << ':';
110    }
111
112    if (secs < 10.0 && !str.str().empty())
113        str << '0';
114    str << secs;
115
116    return str.str();
117}
118
119void
120Time::serialize(const std::string &base, ostream &os)
121{
122    paramOut(os, base + ".sec", sec());
123    paramOut(os, base + ".nsec", nsec());
124}
125
126void
127Time::unserialize(const std::string &base, Checkpoint *cp,
128                  const string &section)
129{
130    time_t secs;
131    time_t nsecs;
132    paramIn(cp, section, base + ".sec", secs);
133    paramIn(cp, section, base + ".nsec", nsecs);
134    sec(secs);
135    nsec(nsecs);
136}
137
138void
139sleep(const Time &time)
140{
141    timespec ts = time;
142
143#if USE_POSIX_CLOCK
144    clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
145#else
146    nanosleep(&ts, NULL);
147#endif
148}
149
150time_t
151mkutctime(struct tm *time)
152{
153    time_t ret;
154    char *tz;
155
156    tz = getenv("TZ");
157    setenv("TZ", "", 1);
158    tzset();
159    ret = mktime(time);
160    if (tz)
161        setenv("TZ", tz, 1);
162    else
163        unsetenv("TZ");
164    tzset();
165    return ret;
166}
167
168