Add 'Time' as a parameter type that can accept various
authorNathan Binkert <binkertn@umich.edu>
Wed, 3 Jan 2007 18:12:55 +0000 (10:12 -0800)
committerNathan Binkert <binkertn@umich.edu>
Wed, 3 Jan 2007 18:12:55 +0000 (10:12 -0800)
formats for time (strings, datetime objects, etc.)
Advance system time to 1/1/2009
Clean up time management code a little bit

--HG--
extra : convert_revision : 28ebecc7ea6b12f4345c77a9a6b4bdf2e752c4f8

src/dev/alpha/tsunami_io.cc
src/dev/alpha/tsunami_io.hh
src/python/m5/objects/Tsunami.py
src/python/m5/params.py

index 8430856ef6fb1a1d6e441729265ae02f66087821..38986b77e6146fb23849176ef2d0c7b12b8301db 100644 (file)
@@ -57,17 +57,13 @@ using namespace std;
 //Should this be AlphaISA?
 using namespace TheISA;
 
-TsunamiIO::RTC::RTC(const string &name, Tsunami* t, Tick i)
-    : _name(name), event(t, i), addr(0)
+TsunamiIO::RTC::RTC(const string &n, Tsunami* tsunami, time_t t, Tick i)
+    : _name(n), event(tsunami, i), addr(0)
 {
     memset(clock_data, 0, sizeof(clock_data));
     stat_regA = RTCA_32768HZ | RTCA_1024HZ;
     stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR;
-}
 
-void
-TsunamiIO::RTC::set_time(time_t t)
-{
     struct tm tm;
     gmtime_r(&t, &tm);
 
@@ -428,7 +424,7 @@ TsunamiIO::PITimer::Counter::CounterEvent::description()
 
 TsunamiIO::TsunamiIO(Params *p)
     : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"),
-      rtc(p->name + ".rtc", p->tsunami, p->frequency)
+      rtc(p->name + ".rtc", p->tsunami, p->init_time, p->frequency)
 {
     pioSize = 0x100;
 
@@ -436,7 +432,6 @@ TsunamiIO::TsunamiIO(Params *p)
     tsunami->io = this;
 
     timerData = 0;
-    rtc.set_time(p->init_time == 0 ? time(NULL) : p->init_time);
     picr = 0;
     picInterrupting = false;
 }
index 54acefc25b32f999996c99f38f2aa0c6914419d5..b0c368eb8f806cf8aaf0a74d296e31db300085d3 100644 (file)
@@ -110,10 +110,7 @@ class TsunamiIO : public BasicPioDevice
         uint8_t stat_regB;
 
       public:
-        RTC(const std::string &name, Tsunami* t, Tick i);
-
-        /** Set the initial RTC time/date */
-        void set_time(time_t t);
+        RTC(const std::string &name, Tsunami* tsunami, time_t t, Tick i);
 
         /** RTC address port: write address of RTC RAM data to access */
         void writeAddr(const uint8_t data);
index ac9020b47b0f97cc1680e87c5c6d6db1aee49acb..18a776a7ff1a47570842d4727be7286045ece426 100644 (file)
@@ -13,8 +13,8 @@ class TsunamiCChip(BasicPioDevice):
 
 class TsunamiIO(BasicPioDevice):
     type = 'TsunamiIO'
-    time = Param.UInt64(1136073600,
-        "System time to use (0 for actual time, default is 1/1/06)")
+    time = Param.Time('01/01/2009',
+        "System time to use ('Now' for actual time)")
     tsunami = Param.Tsunami(Parent.any, "Tsunami")
     frequency = Param.Frequency('1024Hz', "frequency of interrupts")
 
index d83d5f73fb13c9295b036ff830fbb15a26693611..d570804d8d916798ac2b7e8fc44770be49b1acbf 100644 (file)
 #
 #####################################################################
 
-import sys, inspect, copy
+import copy
+import datetime
+import inspect
+import sys
+import time
+
 import convert
 from util import *
 
@@ -513,6 +518,50 @@ class EthernetAddr(ParamValue):
         else:
             return self.value
 
+def parse_time(value):
+    strings = [ "%a %b %d %H:%M:%S %Z %Y",
+                "%a %b %d %H:%M:%S %Z %Y",
+                "%Y/%m/%d %H:%M:%S",
+                "%Y/%m/%d %H:%M",
+                "%Y/%m/%d",
+                "%m/%d/%Y %H:%M:%S",
+                "%m/%d/%Y %H:%M",
+                "%m/%d/%Y",
+                "%m/%d/%y %H:%M:%S",
+                "%m/%d/%y %H:%M",
+                "%m/%d/%y"]
+
+    for string in strings:
+        try:
+            return time.strptime(value, string)
+        except ValueError:
+            pass
+
+    raise ValueError, "Could not parse '%s' as a time" % value
+
+class Time(ParamValue):
+    cxx_type = 'time_t'
+    def __init__(self, value):
+        if isinstance(value, time.struct_time):
+            self.value = time.mktime(value)
+        elif isinstance(value, int):
+            self.value = value
+        elif isinstance(value, str):
+            if value in ('Now', 'Today'):
+                self.value = time.time()
+            else:
+                self.value = time.mktime(parse_time(value))
+        elif isinstance(value, (datetime.datetime, datetime.date)):
+            self.value = time.mktime(value.timetuple())
+        else:
+            raise ValueError, "Could not parse '%s' as a time" % value
+
+    def __str__(self):
+        return str(int(self.value))
+
+    def ini_str(self):
+        return str(int(self.value))
+
 # Enumerated types are a little more complex.  The user specifies the
 # type as Enum(foo) where foo is either a list or dictionary of
 # alternatives (typically strings, but not necessarily so).  (In the
@@ -973,6 +1022,7 @@ __all__ = ['Param', 'VectorParam',
            'NetworkBandwidth', 'MemoryBandwidth',
            'Range', 'AddrRange', 'TickRange',
            'MaxAddr', 'MaxTick', 'AllMemory',
+           'Time',
            'NextEthernetAddr', 'NULL',
            'Port', 'VectorPort']