diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj
index e4b8bfebf..657a854f9 100644
--- a/Builds/VisualStudio2012/beast.vcxproj
+++ b/Builds/VisualStudio2012/beast.vcxproj
@@ -84,8 +84,9 @@
-
+
+
@@ -398,7 +399,7 @@
-
+
true
true
true
diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters
index cfc1e9cca..6d8a46ed8 100644
--- a/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -1224,9 +1224,6 @@
beast_asio\http
-
- beast\chrono
-
beast\thread
@@ -1236,6 +1233,12 @@
beast\thread
+
+ beast\chrono
+
+
+ beast\chrono
+
@@ -1775,15 +1778,15 @@
beast_asio\http
-
- beast\chrono\impl
-
beast\thread\impl
beast\thread
+
+ beast\chrono\impl
+
diff --git a/beast/Chrono.h b/beast/Chrono.h
index 728baa1f8..027b1f5f3 100644
--- a/beast/Chrono.h
+++ b/beast/Chrono.h
@@ -20,7 +20,8 @@
#ifndef BEAST_CHRONO_H_INCLUDED
#define BEAST_CHRONO_H_INCLUDED
-#include "chrono/CPUUsage.h"
+#include "chrono/CPUMeter.h"
#include "chrono/RelativeTime.h"
+#include "chrono/ScopedTimeInterval.h"
#endif
diff --git a/beast/chrono/CPUMeter.h b/beast/chrono/CPUMeter.h
new file mode 100644
index 000000000..8a02b591c
--- /dev/null
+++ b/beast/chrono/CPUMeter.h
@@ -0,0 +1,159 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef BEAST_CHRONO_CPUMETER_H_INCLUDED
+#define BEAST_CHRONO_CPUMETER_H_INCLUDED
+
+#include "RelativeTime.h"
+#include "SCopedTimeInterval.h"
+#include "../thread/SharedData.h"
+#include "../Atomic.h"
+
+namespace beast {
+
+/** Measurements of CPU utilization. */
+class CPUMeter
+{
+private:
+ struct MeasureIdle
+ {
+ explicit MeasureIdle (CPUMeter& meter)
+ : m_meter (&meter)
+ { }
+ void operator() (RelativeTime const& interval) const
+ { m_meter->addIdleTime (interval); }
+ CPUMeter* m_meter;
+ };
+
+ struct MeasureActive
+ {
+ explicit MeasureActive (CPUMeter& meter)
+ : m_meter (&meter)
+ { }
+ void operator() (RelativeTime const& interval) const
+ { m_meter->addActiveTime (interval); }
+ CPUMeter* m_meter;
+ };
+
+public:
+ /** The type of container that measures idle time. */
+ typedef ScopedTimeInterval ScopedIdleTime;
+ typedef ScopedTimeInterval ScopedActiveTime;
+
+ /** Returns the fraction of time that the CPU is being used. */
+ double getCpuUsage () const
+ {
+ SharedState::ConstAccess state (m_state);
+ double const seconds (state->usage.seconds());
+ if (seconds > 0)
+ return (state->usage.active.inSeconds() / seconds);
+ return 0;
+ }
+
+private:
+ enum
+ {
+ // The amount of time an aggregate must accrue before a swap
+ secondsPerAggregate = 3
+
+ // The number of aggregates in the rolling history buffer
+ ,numberOfAggregates = 20
+ };
+
+ // Aggregated sample data
+ struct Aggregate
+ {
+ RelativeTime idle;
+ RelativeTime active;
+
+ // Returns the total number of seconds in the aggregate
+ double seconds () const
+ { return idle.inSeconds() + active.inSeconds(); }
+
+ // Reset the accumulated times
+ void clear ()
+ { idle = RelativeTime (0); active = RelativeTime (0); }
+
+ Aggregate& operator+= (Aggregate const& other)
+ { idle += other.idle; active += other.active; return *this; }
+
+ Aggregate& operator-= (Aggregate const& other)
+ { idle -= other.idle; active -= other.active; return *this; }
+ };
+
+ struct State
+ {
+ State () : index (0)
+ {
+ }
+
+ // Returns a reference to the current aggregate
+ Aggregate& front ()
+ {
+ return history [index];
+ }
+
+ // Checks the current aggregate to see if we should advance
+ void update()
+ {
+ if (front().seconds() >= secondsPerAggregate)
+ advance();
+ }
+
+ // Advance the index in the rolling history
+ void advance ()
+ {
+ usage += history [index];
+ index = (++index) % numberOfAggregates;
+ usage -= history [index];
+ history [index].clear ();
+ }
+
+ // Index of the current aggregate we are accumulating
+ int index;
+
+ // Delta summed usage over the entire history buffer
+ Aggregate usage;
+
+ // The rolling history buffer
+ Aggregate history [numberOfAggregates];
+ };
+
+ typedef SharedData SharedState;
+
+ SharedState m_state;
+
+ void addIdleTime (RelativeTime const& interval)
+ {
+ SharedState::Access state (m_state);
+ state->front().idle += interval;
+ state->update();
+ }
+
+ void addActiveTime (RelativeTime const& interval)
+ {
+ SharedState::Access state (m_state);
+ state->front().active += interval;
+ state->update();
+ }
+};
+
+}
+
+#endif
diff --git a/beast/chrono/Chrono.cpp b/beast/chrono/Chrono.cpp
index a3030761f..5ce5772e6 100644
--- a/beast/chrono/Chrono.cpp
+++ b/beast/chrono/Chrono.cpp
@@ -19,5 +19,5 @@
#include "BeastConfig.h"
-#include "impl/CPUUsage.cpp"
+#include "impl/CPUMeter.cpp"
#include "impl/RelativeTime.cpp"
diff --git a/beast/chrono/CPUUsage.h b/beast/chrono/ScopedTimeInterval.h
similarity index 56%
rename from beast/chrono/CPUUsage.h
rename to beast/chrono/ScopedTimeInterval.h
index 049c779ed..af3672870 100644
--- a/beast/chrono/CPUUsage.h
+++ b/beast/chrono/ScopedTimeInterval.h
@@ -17,27 +17,45 @@
*/
//==============================================================================
-#ifndef BEAST_CHRONO_CPUUSAGE_H_INCLUDED
-#define BEAST_CHRONO_CPUUSAGE_H_INCLUDED
+#ifndef BEAST_CHRONO_SCOPEDTIMEINTERVAL_H_INCLUDED
+#define BEAST_CHRONO_SCOPEDTIMEINTERVAL_H_INCLUDED
+#include "../Uncopyable.h"
#include "RelativeTime.h"
namespace beast {
-/** Measurements of CPU utilization. */
-
-#if 0
-/** Scoped lifetime measurement. */
-class ScopedTimeInterval
+/** Time measurement using scoped RAII container.
+ UnaryFunction will be called with this signature:
+ void (RelativeTime const& interval);
+*/
+template
+class ScopedTimeInterval : public Uncopyable
{
public:
- ScopedTimeInterval ();
- ~ScopedTimeInterval ();
+ /** Create the measurement with a default-constructed UnaryFunction. */
+ ScopedTimeInterval ()
+ : m_start (RelativeTime::fromStartup())
+ {
+ }
+
+ /** Create the measurement with UnaryFunction constructed from one argument. */
+ template
+ explicit ScopedTimeInterval (Arg arg)
+ : m_func (arg)
+ , m_start (RelativeTime::fromStartup ())
+ {
+ }
+
+ ~ScopedTimeInterval ()
+ {
+ m_func (RelativeTime::fromStartup() - m_start);
+ }
private:
+ UnaryFunction m_func;
RelativeTime m_start;
};
-#endif
}
diff --git a/beast/chrono/impl/CPUUsage.cpp b/beast/chrono/impl/CPUMeter.cpp
similarity index 97%
rename from beast/chrono/impl/CPUUsage.cpp
rename to beast/chrono/impl/CPUMeter.cpp
index a27bcd4e0..b5a67f4d1 100644
--- a/beast/chrono/impl/CPUUsage.cpp
+++ b/beast/chrono/impl/CPUMeter.cpp
@@ -17,5 +17,5 @@
*/
//==============================================================================
-#include "../CPUUsage.h"
+#include "../CPUMeter.h"