- /* Update exponentially weighted moving average. With these parameters, a
- * given value decays to 1% of its value in about 100 time steps. */
- if (n_samples++) {
- mean_interval = (mean_interval * 122 + interval * 6 + 64) / 128;
- } else {
- mean_interval = interval;
+/* Returns an estimate of this process's CPU usage, as a percentage, over the
+ * past few seconds of wall-clock time. Returns -1 if no estimate is available
+ * (which will happen if the process has not been running long enough to have
+ * an estimate, and can happen for other reasons as well). */
+int
+get_cpu_usage(void)
+{
+ return get_cpu_tracker()->cpu_usage;
+}
+\f
+/* Unixctl interface. */
+
+/* "time/stop" stops the monotonic time returned by e.g. time_msec() from
+ * advancing, except due to later calls to "time/warp". */
+static void
+timeval_stop_cb(struct unixctl_conn *conn,
+ int argc OVS_UNUSED, const char *argv[] OVS_UNUSED,
+ void *aux OVS_UNUSED)
+{
+ ovs_rwlock_wrlock(&monotonic_clock.rwlock);
+ monotonic_clock.stopped = true;
+ ovs_rwlock_unlock(&monotonic_clock.rwlock);
+
+ unixctl_command_reply(conn, NULL);
+}
+
+/* "time/warp MSECS" advances the current monotonic time by the specified
+ * number of milliseconds. Unless "time/stop" has also been executed, the
+ * monotonic clock continues to tick forward at the normal rate afterward.
+ *
+ * Does not affect wall clock readings. */
+static void
+timeval_warp_cb(struct unixctl_conn *conn,
+ int argc OVS_UNUSED, const char *argv[], void *aux OVS_UNUSED)
+{
+ struct timespec ts;
+ int msecs;
+
+ msecs = atoi(argv[1]);
+ if (msecs <= 0) {
+ unixctl_command_reply_error(conn, "invalid MSECS");
+ return;