aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Willmann <dwillmann@sysmocom.de>2013-12-04 18:11:47 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-12-25 14:55:04 +0100
commit9c623892f5bb2bcc058a43c4d18aa2ce3bff2383 (patch)
tree7ae3832b24d8cb6181d72d65b7f3fd444057078c
parenta42b2ad5ed6b71457c87651e24b01ba6dfb92d22 (diff)
llc: Calculate the average queuing delay of the LLC queues
Use a formula like it is used with TCP. This can help to make decisions about if frames should be dropped or not at the time we enqueue them. This code will store two timeval structs in fron the of the actual data and compute the average at the time of the dequeue.
-rw-r--r--src/llc.cpp26
-rw-r--r--src/llc.h1
-rw-r--r--src/tbf.cpp5
3 files changed, 28 insertions, 4 deletions
diff --git a/src/llc.cpp b/src/llc.cpp
index c557584..2d295f8 100644
--- a/src/llc.cpp
+++ b/src/llc.cpp
@@ -78,14 +78,34 @@ void gprs_llc::init()
{
INIT_LLIST_HEAD(&queue);
m_queue_size = 0;
+ m_avg_queue_delay = 0;
reset();
}
+#define ALPHA 0.5f
+
struct msgb *gprs_llc::dequeue()
{
- if (m_queue_size > 0)
- m_queue_size -= 1;
- return msgb_dequeue(&queue);
+ struct msgb *msg;
+ struct timeval *tv, tv_now, tv_result;
+ uint32_t lifetime;
+
+
+ msg = msgb_dequeue(&queue);
+ if (!msg)
+ return NULL;
+
+ m_queue_size -= 1;
+
+ /* take the second time */
+ gettimeofday(&tv_now, NULL);
+ tv = (struct timeval *)&msg->data[sizeof(*tv)];
+ timersub(&tv_now, tv, &tv_result);
+
+ lifetime = tv_result.tv_sec*1000 + tv_result.tv_usec/1000;
+ m_avg_queue_delay = m_avg_queue_delay * ALPHA + lifetime * (1-ALPHA);
+
+ return msg;
}
diff --git a/src/llc.h b/src/llc.h
index f29c929..1f0c114 100644
--- a/src/llc.h
+++ b/src/llc.h
@@ -55,6 +55,7 @@ struct gprs_llc {
uint16_t m_length; /* len of current DL LLC_frame, 0 == no frame */
struct llist_head queue; /* queued LLC DL data */
+ uint32_t m_avg_queue_delay; /* Average delay of data going through the queue */
size_t m_queue_size;
};
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 4c0e845..5d7e4ef 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -100,12 +100,14 @@ int gprs_rlcmac_tbf::append_data(const uint8_t ms_class,
/* the TBF exists, so we must write it in the queue
* we prepend lifetime in front of PDU */
struct timeval *tv;
- struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv),
+ struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv) * 2,
"llc_pdu_queue");
if (!llc_msg)
return -ENOMEM;
tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv));
gprs_llc::calc_pdu_lifetime(bts, pdu_delay_csec, tv);
+ tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv));
+ gettimeofday(tv, NULL);
memcpy(msgb_put(llc_msg, len), data, len);
m_llc.enqueue(llc_msg);
tbf_update_ms_class(this, ms_class);
@@ -633,6 +635,7 @@ struct msgb *gprs_rlcmac_tbf::llc_dequeue(bssgp_bvc_ctx *bctx)
while ((msg = m_llc.dequeue())) {
tv = (struct timeval *)msg->data;
msgb_pull(msg, sizeof(*tv));
+ msgb_pull(msg, sizeof(*tv));
if (gprs_llc::is_frame_expired(&tv_now, tv)) {
LOGP(DRLCMACDL, LOGL_NOTICE, "%s Discarding LLC PDU "