12SN/A/*
21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
292SN/A */
302SN/A
3111793Sbrandon.potter@amd.com#include "base/time.hh"
3211793Sbrandon.potter@amd.com
338869SAli.Saidi@ARM.com#include <cstdlib>
348869SAli.Saidi@ARM.com#include <ctime>
352SN/A#include <iostream>
367840Snate@binkert.org#include <sstream>
372SN/A
3812334Sgabeblack@google.com#include "base/logging.hh"
397840Snate@binkert.org#include "config/use_posix_clock.hh"
407862Sgblack@eecs.umich.edu#include "sim/core.hh"
417870Sgblack@eecs.umich.edu#include "sim/serialize.hh"
422SN/A
432SN/Ausing namespace std;
442SN/A
457840Snate@binkert.orgvoid
467840Snate@binkert.orgTime::_set(bool monotonic)
472SN/A{
487840Snate@binkert.org#if USE_POSIX_CLOCK
497840Snate@binkert.org    ::clock_gettime(monotonic ? CLOCK_MONOTONIC : CLOCK_REALTIME, &_time);
507840Snate@binkert.org#else
51400SN/A    timeval tv;
527840Snate@binkert.org    ::gettimeofday(&tv, NULL);
537840Snate@binkert.org    operator=(tv);
547840Snate@binkert.org#endif
55400SN/A}
56400SN/A
577862Sgblack@eecs.umich.eduvoid
587862Sgblack@eecs.umich.eduTime::setTick(Tick ticks)
597862Sgblack@eecs.umich.edu{
6012981Sgabeblack@google.com    uint64_t secs = ticks / SimClock::Frequency;
6112981Sgabeblack@google.com    ticks -= secs * SimClock::Frequency;
6212981Sgabeblack@google.com    uint64_t nsecs = static_cast<uint64_t>(ticks * SimClock::Float::GHz);
6312981Sgabeblack@google.com    set(secs, nsecs);
647862Sgblack@eecs.umich.edu}
657862Sgblack@eecs.umich.edu
667862Sgblack@eecs.umich.eduTick
677862Sgblack@eecs.umich.eduTime::getTick() const
687862Sgblack@eecs.umich.edu{
6912981Sgabeblack@google.com    return sec() * SimClock::Frequency +
7012981Sgabeblack@google.com        static_cast<uint64_t>(nsec() * SimClock::Float::ns);
717862Sgblack@eecs.umich.edu}
727862Sgblack@eecs.umich.edu
73400SN/Astring
747840Snate@binkert.orgTime::date(const string &format) const
75400SN/A{
767840Snate@binkert.org    time_t sec = this->sec();
77400SN/A    char buf[256];
78400SN/A
79400SN/A    if (format.empty()) {
803918Ssaidi@eecs.umich.edu#ifdef __SUNPRO_CC
817840Snate@binkert.org        ctime_r(&sec, buf, sizeof(buf));
823918Ssaidi@eecs.umich.edu#else
83400SN/A        ctime_r(&sec, buf);
843918Ssaidi@eecs.umich.edu#endif
85400SN/A        buf[24] = '\0';
86400SN/A        return buf;
872SN/A    }
882SN/A
89400SN/A    struct tm *tm = localtime(&sec);
90400SN/A    strftime(buf, sizeof(buf), format.c_str(), tm);
91400SN/A    return buf;
92400SN/A}
932SN/A
947840Snate@binkert.orgstring
957840Snate@binkert.orgTime::time() const
96400SN/A{
977840Snate@binkert.org    double time = double(*this);
987840Snate@binkert.org    double secs = fmod(time, 60.0);
997840Snate@binkert.org    double all_mins = floor(time / 60.0);
1007840Snate@binkert.org    double mins = fmod(all_mins, 60.0);
1017840Snate@binkert.org    double hours = floor(all_mins / 60.0);
1027840Snate@binkert.org
1037840Snate@binkert.org    stringstream str;
1047840Snate@binkert.org
1057840Snate@binkert.org    if (hours > 0.0) {
1067840Snate@binkert.org        if (hours < 10.0)
1077840Snate@binkert.org            str << '0';
1087840Snate@binkert.org        str << hours << ':';
1097840Snate@binkert.org    }
1107840Snate@binkert.org
1117840Snate@binkert.org    if (mins > 0.0) {
1127840Snate@binkert.org        if (mins < 10.0)
1137840Snate@binkert.org            str << '0';
1147840Snate@binkert.org        str << mins << ':';
1157840Snate@binkert.org    }
1167840Snate@binkert.org
1177840Snate@binkert.org    if (secs < 10.0 && !str.str().empty())
1187840Snate@binkert.org        str << '0';
1197840Snate@binkert.org    str << secs;
1207840Snate@binkert.org
1217840Snate@binkert.org    return str.str();
122400SN/A}
1232SN/A
1247840Snate@binkert.orgvoid
12510905Sandreas.sandberg@arm.comTime::serialize(const std::string &base, CheckpointOut &cp) const
1267870Sgblack@eecs.umich.edu{
12710905Sandreas.sandberg@arm.com    paramOut(cp, base + ".sec", sec());
12810905Sandreas.sandberg@arm.com    paramOut(cp, base + ".nsec", nsec());
1297870Sgblack@eecs.umich.edu}
1307870Sgblack@eecs.umich.edu
1317870Sgblack@eecs.umich.eduvoid
13210905Sandreas.sandberg@arm.comTime::unserialize(const std::string &base, CheckpointIn &cp)
1337870Sgblack@eecs.umich.edu{
1347870Sgblack@eecs.umich.edu    time_t secs;
1357870Sgblack@eecs.umich.edu    time_t nsecs;
13610905Sandreas.sandberg@arm.com    paramIn(cp, base + ".sec", secs);
13710905Sandreas.sandberg@arm.com    paramIn(cp, base + ".nsec", nsecs);
1387870Sgblack@eecs.umich.edu    sec(secs);
1397870Sgblack@eecs.umich.edu    nsec(nsecs);
1407870Sgblack@eecs.umich.edu}
1417870Sgblack@eecs.umich.edu
1427870Sgblack@eecs.umich.eduvoid
1437840Snate@binkert.orgsleep(const Time &time)
144400SN/A{
1457840Snate@binkert.org    timespec ts = time;
1467840Snate@binkert.org
1477840Snate@binkert.org#if USE_POSIX_CLOCK
1487840Snate@binkert.org    clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
1497840Snate@binkert.org#else
1507840Snate@binkert.org    nanosleep(&ts, NULL);
1517840Snate@binkert.org#endif
152400SN/A}
1538869SAli.Saidi@ARM.com
1548869SAli.Saidi@ARM.comtime_t
1558869SAli.Saidi@ARM.commkutctime(struct tm *time)
1568869SAli.Saidi@ARM.com{
15710531Sandreas.hansson@arm.com    // get the current timezone
15810531Sandreas.hansson@arm.com    char *tz = getenv("TZ");
15910531Sandreas.hansson@arm.com
16010531Sandreas.hansson@arm.com    // copy the string as the pointer gets invalidated when updating
16110531Sandreas.hansson@arm.com    // the environment
16210531Sandreas.hansson@arm.com    if (tz) {
16310531Sandreas.hansson@arm.com        tz = strdup(tz);
16410531Sandreas.hansson@arm.com        if (!tz) {
16510531Sandreas.hansson@arm.com            fatal("Failed to reserve memory for UTC time conversion\n");
16610531Sandreas.hansson@arm.com        }
16710531Sandreas.hansson@arm.com    }
16810531Sandreas.hansson@arm.com
16910531Sandreas.hansson@arm.com    // change to UTC and get the time
17010531Sandreas.hansson@arm.com    setenv("TZ", "", 1);
17110531Sandreas.hansson@arm.com    tzset();
17210531Sandreas.hansson@arm.com    time_t ret = mktime(time);
17310531Sandreas.hansson@arm.com
17410531Sandreas.hansson@arm.com    // restore the timezone again
17510531Sandreas.hansson@arm.com    if (tz) {
17610531Sandreas.hansson@arm.com        setenv("TZ", tz, 1);
17710531Sandreas.hansson@arm.com        free(tz);
17810531Sandreas.hansson@arm.com    } else {
17910531Sandreas.hansson@arm.com        unsetenv("TZ");
18010531Sandreas.hansson@arm.com    }
18110531Sandreas.hansson@arm.com    tzset();
18210531Sandreas.hansson@arm.com
18310531Sandreas.hansson@arm.com    return ret;
1848869SAli.Saidi@ARM.com}
1858869SAli.Saidi@ARM.com
186