diff options
Diffstat (limited to 'src/gprs_rlcmac_sched.cpp')
-rw-r--r-- | src/gprs_rlcmac_sched.cpp | 41 |
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 */ |