aboutsummaryrefslogtreecommitdiffstats
path: root/src/gprs_rlcmac_sched.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gprs_rlcmac_sched.cpp')
-rw-r--r--src/gprs_rlcmac_sched.cpp41
1 files changed, 34 insertions, 7 deletions
diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp
index c8977e41..dedea269 100644
--- a/src/gprs_rlcmac_sched.cpp
+++ b/src/gprs_rlcmac_sched.cpp
@@ -23,6 +23,8 @@
#include <bts.h>
#include <tbf.h>
+#include "pcu_utils.h"
+
static uint32_t sched_poll(struct gprs_rlcmac_bts *bts,
uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr,
struct gprs_rlcmac_tbf **poll_tbf,
@@ -168,8 +170,21 @@ static struct msgb *sched_select_downlink(struct gprs_rlcmac_bts *bts,
{
struct msgb *msg = NULL;
struct gprs_rlcmac_dl_tbf *tbf, *prio_tbf = NULL;
- int prio, max_prio = -1;
+ enum {
+ DL_PRIO_NONE,
+ DL_PRIO_SENT_DATA, /* the data has been sent and not (yet) nacked */
+ DL_PRIO_LOW_AGE, /* the age has reached the first threshold */
+ DL_PRIO_NEW_DATA, /* the data has not been sent yet or nacked */
+ DL_PRIO_HIGH_AGE, /* the age has reached the second threshold */
+ DL_PRIO_CONTROL, /* a control block needs to be sent */
+ } prio, max_prio = DL_PRIO_NONE;
+
uint8_t i, tfi, prio_tfi;
+ int age;
+ const int age_thresh1 = msecs_to_frames(200);
+ const int high_prio_msecs =
+ OSMO_MIN(BTS::TIMER_T3190_MSEC/2, bts->dl_tbf_idle_msec);
+ const int age_thresh2 = msecs_to_frames(high_prio_msecs);
/* select downlink resource */
for (i = 0, tfi = pdch->next_dl_tfi; i < 32;
@@ -190,13 +205,24 @@ static struct msgb *sched_select_downlink(struct gprs_rlcmac_bts *bts,
if (tbf->m_wait_confirm)
continue;
+ age = tbf->frames_since_last_poll(fn);
+
/* compute priority */
- if (tbf->state_is(GPRS_RLCMAC_FINISHED) &&
- tbf->m_window.resend_needed() < 0)
- /* would re-retransmit blocks */
- prio = 1;
+ if (tbf->is_control_ts(ts) && tbf->need_control_ts())
+ prio = DL_PRIO_CONTROL;
+ else if (tbf->is_control_ts(ts) &&
+ age > age_thresh2 && age_thresh2 > 0)
+ prio = DL_PRIO_HIGH_AGE;
+ else if ((tbf->state_is(GPRS_RLCMAC_FLOW) && tbf->have_data()) ||
+ tbf->m_window.resend_needed() >= 0)
+ prio = DL_PRIO_NEW_DATA;
+ else if (tbf->is_control_ts(ts) &&
+ age > age_thresh1 && tbf->keep_open(fn))
+ prio = DL_PRIO_LOW_AGE;
+ else if (!tbf->m_window.window_empty())
+ prio = DL_PRIO_SENT_DATA;
else
- prio = 2;
+ continue;
/* get the TBF with the highest priority */
if (prio > max_prio) {
@@ -208,7 +234,8 @@ static struct msgb *sched_select_downlink(struct gprs_rlcmac_bts *bts,
if (prio_tbf) {
LOGP(DRLCMACSCHED, LOGL_DEBUG, "Scheduling data message at "
- "RTS for DL TFI=%d (TRX=%d, TS=%d)\n", prio_tfi, trx, ts);
+ "RTS for DL TFI=%d (TRX=%d, TS=%d) prio=%d\n",
+ prio_tfi, trx, ts, max_prio);
/* next TBF to handle resource is the next one */
pdch->next_dl_tfi = (prio_tfi + 1) & 31;
/* generate DL data block */