[PATCH] libosmocore[master]: BSSGP: use monotonic clock

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Max gerrit-no-reply at lists.osmocom.org
Wed Jan 3 16:08:13 UTC 2018


Review at  https://gerrit.osmocom.org/5629

BSSGP: use monotonic clock

Use monotonic clock to compute elapsed time to make sure it's not affected
by system clock changes.

Change-Id: If190a634aa8334cae55df8c41877400d2f5603a2
Related: OS#2586
---
M TODO-RELEASE
M include/osmocom/gprs/gprs_bssgp.h
M src/gb/gprs_bssgp.c
M tests/gb/bssgp_fc_test.c
4 files changed, 18 insertions(+), 16 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/29/5629/1

diff --git a/TODO-RELEASE b/TODO-RELEASE
index f7a08e8..8af8f48 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -11,3 +11,4 @@
 coding		gsm0503_rach_ext-encode()	add func to gsm0503_coding.h
 core		osmo_time_elapsed()	add function to estimate elapsed time
 gb		struct gprs_nsvc	add t_start parameter
+gb		struct bssgp_flow_control	add t_last_pdu parameter
diff --git a/include/osmocom/gprs/gprs_bssgp.h b/include/osmocom/gprs/gprs_bssgp.h
index 2dead69..7b3ccec 100644
--- a/include/osmocom/gprs/gprs_bssgp.h
+++ b/include/osmocom/gprs/gprs_bssgp.h
@@ -66,7 +66,8 @@
 	uint32_t bucket_leak_rate; 	/*!< leak rate of the bucket (octets/sec) */
 
 	uint32_t bucket_counter;	/*!< number of tokens in the bucket */
-	struct timeval time_last_pdu;	/*!< timestamp of last PDU sent */
+	struct timeval time_last_pdu;	/*!< deprecated! will be replaced by t_last_pdu eventually */
+	struct timespec t_last_pdu;	/*!< timestamp of last PDU sent */
 
 	/* the built-in queue */
 	uint32_t max_queue_depth;	/*!< how many packets to queue (mgs) */
diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c
index d27a94f..fa5d474 100644
--- a/src/gb/gprs_bssgp.c
+++ b/src/gb/gprs_bssgp.c
@@ -27,6 +27,7 @@
 
 #include <errno.h>
 #include <stdint.h>
+#include <time.h>
 
 #include <osmocom/core/msgb.h>
 #include <osmocom/core/byteswap.h>
@@ -606,7 +607,6 @@
 {
 	struct bssgp_flow_control *fc = data;
 	struct bssgp_fc_queue_element *fcqe;
-	struct timeval time_now;
 
 	/* if the queue is empty, we return without sending something
 	 * and without re-starting the timer */
@@ -631,8 +631,8 @@
 	fc->queue_depth--;
 
 	/* record the time we transmitted this PDU */
-	osmo_gettimeofday(&time_now, NULL);
-	fc->time_last_pdu = time_now;
+	if (clock_gettime(CLOCK_MONOTONIC, &fc->t_last_pdu) != 0)
+		LOGP(DBSSGP, LOGL_ERROR, "Failed to record PDU time: %s\n", strerror(errno));
 
 	/* call the output callback for this FC instance */
 	fc->out_cb(fcqe->priv, fcqe->msg, fcqe->llc_pdu_len, NULL);
@@ -666,7 +666,7 @@
 		 * a sufficient number of bytes from the bucket to transmit
 		 * the first PDU in the queue */
 		msecs = (fcqe->llc_pdu_len * 1000) / fc->bucket_leak_rate;
-		/* FIXME: add that time to fc->time_last_pdu and subtract it from
+		/* FIXME: add that time to fc->t_last_pdu and subtract it from
 		 * current time */
 		osmo_timer_setup(&fc->timer, fc_timer_cb, fc);
 		osmo_timer_schedule(&fc->timer, msecs / 1000, (msecs % 1000) * 1000);
@@ -707,7 +707,6 @@
 /* According to Section 8.2 */
 static int bssgp_fc_needs_queueing(struct bssgp_flow_control *fc, uint32_t pdu_len)
 {
-	struct timeval time_now, time_diff;
 	int64_t bucket_predicted;
 	uint32_t csecs_elapsed, leaked;
 
@@ -715,9 +714,7 @@
 
 	/* compute number of centi-seconds that have elapsed since transmitting
 	 * the last PDU (Tc - Tp) */
-	osmo_gettimeofday(&time_now, NULL);
-	timersub(&time_now, &fc->time_last_pdu, &time_diff);
-	csecs_elapsed = time_diff.tv_sec*100 + time_diff.tv_usec/10000;
+	csecs_elapsed = osmo_time_elapsed(&fc->t_last_pdu, T_CENTIS);
 
 	/* compute number of bytes that have leaked in the elapsed number
 	 * of centi-seconds */
@@ -753,8 +750,6 @@
 int bssgp_fc_in(struct bssgp_flow_control *fc, struct msgb *msg,
 		uint32_t llc_pdu_len, void *priv)
 {
-	struct timeval time_now;
-
 	if (llc_pdu_len > fc->bucket_size_max) {
 		LOGP(DBSSGP, LOGL_NOTICE, "Single PDU (size=%u) is larger "
 		     "than maximum bucket size (%u)!\n", llc_pdu_len,
@@ -771,8 +766,9 @@
 		return rc;
 	} else {
 		/* record the time we transmitted this PDU */
-		osmo_gettimeofday(&time_now, NULL);
-		fc->time_last_pdu = time_now;
+		if (clock_gettime(CLOCK_MONOTONIC, &fc->t_last_pdu) != 0)
+			LOGP(DBSSGP, LOGL_ERROR, "Failed to record PDU time: %s\n", strerror(errno));
+
 		return fc->out_cb(priv, msg, llc_pdu_len, NULL);
 	}
 }
@@ -790,7 +786,9 @@
 	fc->bucket_leak_rate = bucket_leak_rate;
 	fc->max_queue_depth = max_queue_depth;
 	INIT_LLIST_HEAD(&fc->queue);
-	osmo_gettimeofday(&fc->time_last_pdu, NULL);
+
+	if (clock_gettime(CLOCK_MONOTONIC, &fc->t_last_pdu) != 0)
+		LOGP(DBSSGP, LOGL_ERROR, "Failed to start timer: %s\n", strerror(errno));
 }
 
 /* Initialize the Flow Control parameters for a new MS according to
diff --git a/tests/gb/bssgp_fc_test.c b/tests/gb/bssgp_fc_test.c
index ac690a5..9eae9fd 100644
--- a/tests/gb/bssgp_fc_test.c
+++ b/tests/gb/bssgp_fc_test.c
@@ -96,11 +96,13 @@
 
 	while (1) {
 		osmo_gettimeofday_override_add(0, 100000);
-
 		osmo_timers_check();
 		osmo_timers_prepare();
-		osmo_timers_update();
 
+		fc->t_last_pdu.tv_sec = 0;
+		fc->t_last_pdu.tv_nsec += OSMO_USEC2NS(100000);
+
+		osmo_timers_update();
 		if (llist_empty(&fc->queue))
 			break;
 	}

-- 
To view, visit https://gerrit.osmocom.org/5629
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If190a634aa8334cae55df8c41877400d2f5603a2
Gerrit-PatchSet: 1
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>



More information about the gerrit-log mailing list