]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
include linked list and worker stats into time tracking.
authorAlan T. DeKok <aland@freeradius.org>
Tue, 15 Nov 2016 19:10:25 +0000 (14:10 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 15 Nov 2016 19:10:25 +0000 (14:10 -0500)
So we have one API call to track time && yielded list,
instead of two.

src/util/time.c
src/util/time.h

index fe75756dae95e7da31b9bb1c14dae781fba6fec5..5527b1cbb7f9ac29736a7325eb7755765ac8fa70 100644 (file)
@@ -22,6 +22,7 @@
 RCSID("$Id$")
 
 #include <freeradius-devel/autoconf.h>
+#include <freeradius-devel/rad_assert.h>
 #include <freeradius-devel/util/time.h>
 
 /*
@@ -153,38 +154,80 @@ void fr_time_to_timeval(struct timeval *tv, fr_time_t when)
  */
 void fr_time_tracking_start(fr_time_tracking_t *tt, fr_time_t when)
 {
+       fr_dlist_t *l = &(tt->list);
+
+       memset(tt, 0, sizeof(*tt));
+
        tt->when = when;
        tt->start = when;
        tt->resumed = when;
+
+       l->prev = l;
+       l->next = l;
 }
 
+
+#define IALPHA (8)
+#define RTT(_old, _new) ((_old + ((IALPHA - 1) * _new)) / IALPHA)
+
 /** End time tracking for this request.
  *
  * After this call, all request processing should be finished.
  *
  * @param[in] tt the time tracking structure.
  * @param[in] when the event happened
+ * @param[out] worker time tracking for the worker thread
  */
-void fr_time_tracking_end(fr_time_tracking_t *tt, fr_time_t when)
+void fr_time_tracking_end(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracking_t *worker)
 {
        tt->when = when;
        tt->end = when;
        tt->running += (tt->end - tt->resumed);
+
+       /*
+        *      This request cannot be in any list.
+        */
+       rad_assert(tt->list.prev = &tt->list);
+       rad_assert(tt->list.next = &tt->list);
+
+       /*
+        *      Update the time that the worker spent processing the request.
+        */
+       worker->running += tt->running;
+       worker->waiting += tt->waiting;
+       worker->predicted = RTT(worker->predicted, tt->running);
 }
 
+
 /** Track that a request yielded.
  *
  * @param[in] tt the time tracking structure.
  * @param[in] when the event happened
+ * @param[out] worker time tracking for the worker thread
  */
-void fr_time_tracking_yield(fr_time_tracking_t *tt, fr_time_t when)
+void fr_time_tracking_yield(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracking_t *worker)
 {
+       fr_dlist_t *l = &(tt->list);
+       fr_dlist_t *head = &(worker->list);
+
        tt->when = when;
        tt->yielded = when;
 
+       rad_assert(tt->resumed <= tt->yielded);
        tt->running += (tt->yielded - tt->resumed);
+
+       /*
+        *      Insert this request into the workers list of waiting
+        *      requests.
+        */
+       l->next = head->next;
+       l->prev = head;
+
+       head->next->prev = l;
+       head->next = l;
 }
 
+
 /** Track that a request resumed.
  *
  * @param[in] tt the time tracking structure.
@@ -192,8 +235,22 @@ void fr_time_tracking_yield(fr_time_tracking_t *tt, fr_time_t when)
  */
 void fr_time_tracking_resume(fr_time_tracking_t *tt, fr_time_t when)
 {
+       fr_dlist_t *l = &(tt->list);
+
        tt->when = when;
        tt->resumed = when;
 
+       rad_assert(tt->resumed <= tt->yielded);
+
        tt->waiting += (tt->resumed - tt->yielded);
+
+       /*
+        *      Remove this request into the workers list of waiting
+        *      requests.
+        */
+       l->prev->next = l->next;
+       l->next->prev = l->prev;
+
+       l->prev = l;
+       l->next = l;
 }
index a9576f221af42a6eebe228003e95cf170e5801b1..0ee8c7ad6da34a4185afa5480288fc14766b3a08 100644 (file)
@@ -41,6 +41,14 @@ extern "C" {
  */
 typedef uint64_t fr_time_t;
 
+/**
+ *  A doubly linked list.
+ */
+typedef struct fr_dlist_t {
+       struct fr_dlist_t *prev;
+       struct fr_dlist_t *next;
+} fr_dlist_t;
+
 /**
  *  A structure to track the time spent processing a request.
  *
@@ -62,6 +70,8 @@ typedef struct fr_time_tracking_t {
        fr_time_t       resumed;                //!< time this request last resumed;
        fr_time_t       running;                //!< total time spent running
        fr_time_t       waiting;                //!< total time spent waiting
+
+       fr_dlist_t      list;                   //!< for linking a request to various lists
 } fr_time_tracking_t;
 
 #define NANOSEC (1000000000)
@@ -72,8 +82,8 @@ fr_time_t fr_time(void);
 void fr_time_to_timeval(struct timeval *tv, fr_time_t when) CC_HINT(nonnull);
 
 void fr_time_tracking_start(fr_time_tracking_t *tt, fr_time_t when) CC_HINT(nonnull);
-void fr_time_tracking_end(fr_time_tracking_t *tt, fr_time_t when) CC_HINT(nonnull);
-void fr_time_tracking_yield(fr_time_tracking_t *tt, fr_time_t when) CC_HINT(nonnull);
+void fr_time_tracking_end(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracking_t *worker) CC_HINT(nonnull);
+void fr_time_tracking_yield(fr_time_tracking_t *tt, fr_time_t when, fr_time_tracking_t *worker) CC_HINT(nonnull);
 void fr_time_tracking_resume(fr_time_tracking_t *tt, fr_time_t when) CC_HINT(nonnull);
 
 #ifdef __cplusplus