time.cc revision 10531
112605Sgiacomo.travaglini@arm.com/*
213882Sgiacomo.travaglini@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
312605Sgiacomo.travaglini@arm.com * All rights reserved.
412605Sgiacomo.travaglini@arm.com *
512605Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without
612605Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are
712605Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright
812605Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer;
912605Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright
1012605Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the
1112605Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution;
1212605Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its
1312605Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from
1412605Sgiacomo.travaglini@arm.com * this software without specific prior written permission.
1512605Sgiacomo.travaglini@arm.com *
1612605Sgiacomo.travaglini@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712605Sgiacomo.travaglini@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812605Sgiacomo.travaglini@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912605Sgiacomo.travaglini@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012605Sgiacomo.travaglini@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112605Sgiacomo.travaglini@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212605Sgiacomo.travaglini@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312605Sgiacomo.travaglini@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412605Sgiacomo.travaglini@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512605Sgiacomo.travaglini@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612605Sgiacomo.travaglini@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712605Sgiacomo.travaglini@arm.com *
2812605Sgiacomo.travaglini@arm.com * Authors: Nathan Binkert
2912605Sgiacomo.travaglini@arm.com */
3012605Sgiacomo.travaglini@arm.com
3112605Sgiacomo.travaglini@arm.com#include <cstdlib>
3212605Sgiacomo.travaglini@arm.com#include <ctime>
3312605Sgiacomo.travaglini@arm.com#include <iostream>
3412605Sgiacomo.travaglini@arm.com#include <sstream>
3512605Sgiacomo.travaglini@arm.com
3612605Sgiacomo.travaglini@arm.com#include "base/time.hh"
3712605Sgiacomo.travaglini@arm.com#include "config/use_posix_clock.hh"
3812605Sgiacomo.travaglini@arm.com#include "sim/core.hh"
3912605Sgiacomo.travaglini@arm.com#include "sim/serialize.hh"
4012605Sgiacomo.travaglini@arm.com
4112605Sgiacomo.travaglini@arm.comusing namespace std;
4212605Sgiacomo.travaglini@arm.com
4312605Sgiacomo.travaglini@arm.comvoid
4412605Sgiacomo.travaglini@arm.comTime::_set(bool monotonic)
4512605Sgiacomo.travaglini@arm.com{
4612605Sgiacomo.travaglini@arm.com#if USE_POSIX_CLOCK
4712605Sgiacomo.travaglini@arm.com    ::clock_gettime(monotonic ? CLOCK_MONOTONIC : CLOCK_REALTIME, &_time);
4812605Sgiacomo.travaglini@arm.com#else
4912605Sgiacomo.travaglini@arm.com    timeval tv;
5012605Sgiacomo.travaglini@arm.com    ::gettimeofday(&tv, NULL);
5112605Sgiacomo.travaglini@arm.com    operator=(tv);
5212605Sgiacomo.travaglini@arm.com#endif
5312605Sgiacomo.travaglini@arm.com}
5412605Sgiacomo.travaglini@arm.com
5512605Sgiacomo.travaglini@arm.comvoid
5612605Sgiacomo.travaglini@arm.comTime::setTick(Tick ticks)
5712605Sgiacomo.travaglini@arm.com{
5812605Sgiacomo.travaglini@arm.com    uint64_t nsecs = ticks / SimClock::Int::ns;
5912605Sgiacomo.travaglini@arm.com    set(nsecs / NSEC_PER_SEC, nsecs % NSEC_PER_SEC);
6012605Sgiacomo.travaglini@arm.com}
6112605Sgiacomo.travaglini@arm.com
6212605Sgiacomo.travaglini@arm.comTick
6312605Sgiacomo.travaglini@arm.comTime::getTick() const
6412605Sgiacomo.travaglini@arm.com{
6512605Sgiacomo.travaglini@arm.com    return (nsec() + sec() * NSEC_PER_SEC) * SimClock::Int::ns;
6612605Sgiacomo.travaglini@arm.com}
6712605Sgiacomo.travaglini@arm.com
6812605Sgiacomo.travaglini@arm.comstring
6912605Sgiacomo.travaglini@arm.comTime::date(const string &format) const
7012605Sgiacomo.travaglini@arm.com{
7112605Sgiacomo.travaglini@arm.com    time_t sec = this->sec();
7212605Sgiacomo.travaglini@arm.com    char buf[256];
7312605Sgiacomo.travaglini@arm.com
7412605Sgiacomo.travaglini@arm.com    if (format.empty()) {
7512605Sgiacomo.travaglini@arm.com#ifdef __SUNPRO_CC
7612605Sgiacomo.travaglini@arm.com        ctime_r(&sec, buf, sizeof(buf));
7712605Sgiacomo.travaglini@arm.com#else
7812605Sgiacomo.travaglini@arm.com        ctime_r(&sec, buf);
7912605Sgiacomo.travaglini@arm.com#endif
8012605Sgiacomo.travaglini@arm.com        buf[24] = '\0';
8112605Sgiacomo.travaglini@arm.com        return buf;
8212605Sgiacomo.travaglini@arm.com    }
8312605Sgiacomo.travaglini@arm.com
8412605Sgiacomo.travaglini@arm.com    struct tm *tm = localtime(&sec);
8512605Sgiacomo.travaglini@arm.com    strftime(buf, sizeof(buf), format.c_str(), tm);
8612605Sgiacomo.travaglini@arm.com    return buf;
8712605Sgiacomo.travaglini@arm.com}
8812605Sgiacomo.travaglini@arm.com
8912605Sgiacomo.travaglini@arm.comstring
9012605Sgiacomo.travaglini@arm.comTime::time() const
9112605Sgiacomo.travaglini@arm.com{
9212605Sgiacomo.travaglini@arm.com    double time = double(*this);
9312605Sgiacomo.travaglini@arm.com    double secs = fmod(time, 60.0);
9412605Sgiacomo.travaglini@arm.com    double all_mins = floor(time / 60.0);
9512605Sgiacomo.travaglini@arm.com    double mins = fmod(all_mins, 60.0);
9612605Sgiacomo.travaglini@arm.com    double hours = floor(all_mins / 60.0);
9712605Sgiacomo.travaglini@arm.com
9812605Sgiacomo.travaglini@arm.com    stringstream str;
9912605Sgiacomo.travaglini@arm.com
10012605Sgiacomo.travaglini@arm.com    if (hours > 0.0) {
10112605Sgiacomo.travaglini@arm.com        if (hours < 10.0)
10212605Sgiacomo.travaglini@arm.com            str << '0';
10312605Sgiacomo.travaglini@arm.com        str << hours << ':';
10412605Sgiacomo.travaglini@arm.com    }
10512605Sgiacomo.travaglini@arm.com
10612605Sgiacomo.travaglini@arm.com    if (mins > 0.0) {
10712605Sgiacomo.travaglini@arm.com        if (mins < 10.0)
10812605Sgiacomo.travaglini@arm.com            str << '0';
10912605Sgiacomo.travaglini@arm.com        str << mins << ':';
11012605Sgiacomo.travaglini@arm.com    }
11112605Sgiacomo.travaglini@arm.com
11212605Sgiacomo.travaglini@arm.com    if (secs < 10.0 && !str.str().empty())
11312605Sgiacomo.travaglini@arm.com        str << '0';
11412605Sgiacomo.travaglini@arm.com    str << secs;
11512605Sgiacomo.travaglini@arm.com
11612605Sgiacomo.travaglini@arm.com    return str.str();
11712605Sgiacomo.travaglini@arm.com}
11812605Sgiacomo.travaglini@arm.com
11912605Sgiacomo.travaglini@arm.comvoid
12012605Sgiacomo.travaglini@arm.comTime::serialize(const std::string &base, ostream &os)
12112605Sgiacomo.travaglini@arm.com{
12212605Sgiacomo.travaglini@arm.com    paramOut(os, base + ".sec", sec());
12312605Sgiacomo.travaglini@arm.com    paramOut(os, base + ".nsec", nsec());
12412605Sgiacomo.travaglini@arm.com}
12512605Sgiacomo.travaglini@arm.com
12612605Sgiacomo.travaglini@arm.comvoid
12712605Sgiacomo.travaglini@arm.comTime::unserialize(const std::string &base, Checkpoint *cp,
12812605Sgiacomo.travaglini@arm.com                  const string &section)
12912605Sgiacomo.travaglini@arm.com{
13012605Sgiacomo.travaglini@arm.com    time_t secs;
13112605Sgiacomo.travaglini@arm.com    time_t nsecs;
13212605Sgiacomo.travaglini@arm.com    paramIn(cp, section, base + ".sec", secs);
13312605Sgiacomo.travaglini@arm.com    paramIn(cp, section, base + ".nsec", nsecs);
13412605Sgiacomo.travaglini@arm.com    sec(secs);
13512605Sgiacomo.travaglini@arm.com    nsec(nsecs);
13612605Sgiacomo.travaglini@arm.com}
13712605Sgiacomo.travaglini@arm.com
13812605Sgiacomo.travaglini@arm.comvoid
13912605Sgiacomo.travaglini@arm.comsleep(const Time &time)
14012605Sgiacomo.travaglini@arm.com{
14112605Sgiacomo.travaglini@arm.com    timespec ts = time;
14212605Sgiacomo.travaglini@arm.com
14312605Sgiacomo.travaglini@arm.com#if USE_POSIX_CLOCK
14412605Sgiacomo.travaglini@arm.com    clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
14512605Sgiacomo.travaglini@arm.com#else
14612605Sgiacomo.travaglini@arm.com    nanosleep(&ts, NULL);
14712605Sgiacomo.travaglini@arm.com#endif
14812605Sgiacomo.travaglini@arm.com}
14912605Sgiacomo.travaglini@arm.com
15012605Sgiacomo.travaglini@arm.comtime_t
15112605Sgiacomo.travaglini@arm.commkutctime(struct tm *time)
15212605Sgiacomo.travaglini@arm.com{
15312605Sgiacomo.travaglini@arm.com    // get the current timezone
15412605Sgiacomo.travaglini@arm.com    char *tz = getenv("TZ");
15512605Sgiacomo.travaglini@arm.com
15612605Sgiacomo.travaglini@arm.com    // copy the string as the pointer gets invalidated when updating
15712605Sgiacomo.travaglini@arm.com    // the environment
15812605Sgiacomo.travaglini@arm.com    if (tz) {
15912605Sgiacomo.travaglini@arm.com        tz = strdup(tz);
16012605Sgiacomo.travaglini@arm.com        if (!tz) {
16112605Sgiacomo.travaglini@arm.com            fatal("Failed to reserve memory for UTC time conversion\n");
16212605Sgiacomo.travaglini@arm.com        }
16312605Sgiacomo.travaglini@arm.com    }
16412605Sgiacomo.travaglini@arm.com
16512605Sgiacomo.travaglini@arm.com    // change to UTC and get the time
16612605Sgiacomo.travaglini@arm.com    setenv("TZ", "", 1);
16712605Sgiacomo.travaglini@arm.com    tzset();
16812605Sgiacomo.travaglini@arm.com    time_t ret = mktime(time);
16912605Sgiacomo.travaglini@arm.com
17012605Sgiacomo.travaglini@arm.com    // restore the timezone again
17112605Sgiacomo.travaglini@arm.com    if (tz) {
17213882Sgiacomo.travaglini@arm.com        setenv("TZ", tz, 1);
17313882Sgiacomo.travaglini@arm.com        free(tz);
17412605Sgiacomo.travaglini@arm.com    } else {
17512605Sgiacomo.travaglini@arm.com        unsetenv("TZ");
17612605Sgiacomo.travaglini@arm.com    }
17712605Sgiacomo.travaglini@arm.com    tzset();
17812605Sgiacomo.travaglini@arm.com
17912605Sgiacomo.travaglini@arm.com    return ret;
18012605Sgiacomo.travaglini@arm.com}
18112605Sgiacomo.travaglini@arm.com
18212605Sgiacomo.travaglini@arm.com