make SIGUSR2 dump and reset stats
Make resetting time work
base/statistics.cc:
    Fix statistics reset so that it works again, and correctly
    reset bins as well.  (The old code wouldn't reset if you didn't
    have any bins, and then would actually only reset the first
    bin)
cpu/simple_cpu/simple_cpu.cc:
cpu/simple_cpu/simple_cpu.hh:
    convert idleCycles/idleFraction into a single Average stat
    to make reset work more simply
sim/main.cc:
    handle SIGUSR2 to dump and reset stats
    (SIGUSR1 only dumps them)
sim/sim_time.cc:
sim/sim_time.hh:
    Add support for resetting the time
--HG--
extra : convert_revision : 
ea43e03c50c0a4bb826dc0842a8c4fa1a9289e0a
 void
 Database::reset()
 {
-    list<GenBin *>::iterator bi = bins.begin();
-    list<GenBin *>::iterator be = bins.end();
     list_t::iterator i = allStats.begin();
     list_t::iterator end = allStats.end();
-
-   while (bi != be) {
-       (*bi)->activate();
-
-       while (i != end) {
-        (*i)->reset();
+    while (i != end) {
+        Stat *stat = *i;
+        stat->reset();
         ++i;
-       }
-       ++bi;
+    }
+
+    list<GenBin *>::iterator bi = bins.begin();
+    list<GenBin *>::iterator be = bins.end();
+    while (bi != be) {
+        GenBin *bin = *bi;
+        bin->activate();
+
+        i = allStats.begin();
+        while (i != end) {
+            Stat *stat = *i;
+            stat->reset();
+            ++i;
+        }
+        ++bi;
     }
 }
 
                         _pdf = vec[i] / _total;
                         _cdf += _pdf;
                     } else {
-                        _pdf = _cdf = 0.0;
+                        _pdf = _cdf = NAN;
                     }
                     if (!(myflags & cdf)) {
                         PrintOne(stream, vec[i], subname, subdesc, myprecision,
                         _pdf = vec[i] / _total;
                         _cdf += _pdf;
                     } else {
-                        _pdf = _cdf = 0.0;
+                        _pdf = _cdf = NAN;
                     }
-                    _pdf = vec[i] / _total;
-                    _cdf += _pdf;
                     PrintOne(stream, vec[i], name, mydesc, myprecision,
                              myflags, _pdf, _cdf);
                 }
 
 
     numInst = 0;
     numLoad = 0;
-    last_idle = 0;
     lastIcacheStall = 0;
     lastDcacheStall = 0;
 
 {
 }
 
-
 void
 SimpleCPU::switchOut()
 {
         .desc("Number of memory references")
         ;
 
-    idleCycles
-        .name(name() + ".idle_cycles")
-        .desc("Number of idle cycles")
-        ;
-
     idleFraction
         .name(name() + ".idle_fraction")
         .desc("Percentage of idle cycles")
         .prereq(dcacheStallCycles)
         ;
 
-    idleFraction = idleCycles / simTicks;
-
     numInsts = Statistics::scalar(numInst);
     simInsts += numInsts;
 }
 
 
           case Idle:
             assert(old_status == Running);
-            last_idle = curTick;
+            idleFraction++;
             if (tickEvent.scheduled())
                 tickEvent.squash();
             break;
                    old_status == DcacheMissStall ||
                    old_status == IcacheMissComplete);
             if (old_status == Idle && curTick != 0)
-                idleCycles += curTick - last_idle;
+                idleFraction--;
 
             if (tickEvent.squashed())
                 tickEvent.reschedule(curTick + 1);
     Counter numLoad;
 
     // number of idle cycles
-    Statistics::Scalar<> idleCycles;
-    Statistics::Formula idleFraction;
-    Counter last_idle;
+    Statistics::Average<> idleFraction;
 
     // number of cycles stalled for I-cache misses
     Statistics::Scalar<> icacheStallCycles;
 
 // See async.h.
 volatile bool async_event = false;
 volatile bool async_dump = false;
+volatile bool async_dumpreset = false;
 volatile bool async_exit = false;
 volatile bool async_io = false;
 volatile bool async_alarm = false;
     async_dump = true;
 }
 
+void
+dumprstStatsHandler(int sigtype)
+{
+    async_event = true;
+    async_dumpreset = true;
+}
+
 /// Exit signal handler.
 void
 exitNowHandler(int sigtype)
     signal(SIGFPE, SIG_IGN);           // may occur on misspeculated paths
     signal(SIGPIPE, SIG_IGN);
     signal(SIGTRAP, SIG_IGN);
-    signal(SIGUSR1, dumpStatsHandler); // dump intermediate stats
-    signal(SIGINT, exitNowHandler);    // dump final stats and exit
+    signal(SIGUSR1, dumpStatsHandler);         // dump intermediate stats
+    signal(SIGUSR2, dumprstStatsHandler);      // dump and reset stats
+    signal(SIGINT, exitNowHandler);            // dump final stats and exit
 
     sayHello(cerr);
 
                 SetupEvent(Dump, curTick);
             }
 
+            if (async_dumpreset) {
+                async_dumpreset = false;
+
+                using namespace Statistics;
+                SetupEvent(Dump | Reset, curTick);
+            }
+
             if (async_exit) {
                 async_exit = false;
                 new SimExitEvent("User requested STOP");
 
         return start->tv;
     }
 
+    void
+    Start::reset()
+    {
+        ::gettimeofday(&start->tv, NULL);
+    }
+
     double
     Start::operator()() const
     {
         if (!elapsed)
             elapsed = new _timeval;
 
-        timersub(&now.get(), &start.get(), &elapsed->tv);
+        timersub(&_now.get(), &_start.get(), &elapsed->tv);
         return elapsed->tv;
     }
 
+    void
+    Elapsed::reset()
+    {
+        _start.reset();
+    }
+
     double
     Elapsed::operator()() const
     {
 
         ~Start();
 
         const timeval &get() const;
+        void reset();
         double operator()() const;
     };
 
     {
       private:
         mutable _timeval *elapsed;
+        Start _start;
+        Now _now;
 
       public:
         Elapsed();
         ~Elapsed();
 
         const timeval &get() const;
+        void reset();
         double operator()() const;
     };