Cleanup FN scheduling

* replace magic number with defined constant
* move copy-pasted code to inline functions
* remove unused code

Change-Id: I6fee0714453d0c3c3f3f875f88daea2d9c477331
Related: OS#1524
This commit is contained in:
Max 2017-05-16 16:10:45 +02:00
parent 356ac618f1
commit 9dabfa2c2b
8 changed files with 48 additions and 53 deletions

View File

@ -238,6 +238,11 @@ void BTS::set_current_frame_number(int fn)
m_pollController.expireTimedout(m_cur_fn, max_delay); m_pollController.expireTimedout(m_cur_fn, max_delay);
} }
static inline int delta_fn(int fn, int to)
{
return (fn + GSM_MAX_FN * 3 / 2 - to) % GSM_MAX_FN - GSM_MAX_FN/2;
}
void BTS::set_current_block_frame_number(int fn, unsigned max_delay) void BTS::set_current_block_frame_number(int fn, unsigned max_delay)
{ {
int delay = 0; int delay = 0;
@ -248,15 +253,14 @@ void BTS::set_current_block_frame_number(int fn, unsigned max_delay)
/* frame numbers in the received blocks are assumed to be strongly /* frame numbers in the received blocks are assumed to be strongly
* monotonic. */ * monotonic. */
if (m_cur_blk_fn >= 0) { if (m_cur_blk_fn >= 0) {
int delta = (fn + 2715648 * 3 / 2 - m_cur_blk_fn) % 2715648 - 2715648/2; int delta = delta_fn(fn, m_cur_blk_fn);
if (delta <= 0) if (delta <= 0)
return; return;
} }
/* Check block delay vs. the current frame number */ /* Check block delay vs. the current frame number */
if (current_frame_number() != 0) if (current_frame_number() != 0)
delay = (fn + 2715648 * 3 / 2 - current_frame_number()) % 2715648 delay = delta_fn(fn, current_frame_number());
- 2715648/2;
if (delay <= -late_block_delay_thresh) { if (delay <= -late_block_delay_thresh) {
LOGP(DRLCMAC, LOGL_NOTICE, LOGP(DRLCMAC, LOGL_NOTICE,
"Late RLC block, FN delta: %d FN: %d curFN: %d\n", "Late RLC block, FN delta: %d FN: %d curFN: %d\n",
@ -814,7 +818,7 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi)
tbf->trx->trx_no, tbf->trx->arfcn, tbf->trx->trx_no, tbf->trx->arfcn,
ts, tbf->ta(), poll ? tbf->poll_fn : -1); ts, tbf->ta(), poll ? tbf->poll_fn : -1);
plen = Encoding::write_immediate_assignment(tbf, immediate_assignment, 1, 125, plen = Encoding::write_immediate_assignment(tbf, immediate_assignment, 1, 125,
(tbf->pdch[ts]->last_rts_fn + 21216) % 2715648, tbf->ta(), (tbf->pdch[ts]->last_rts_fn + 21216) % GSM_MAX_FN, tbf->ta(),
tbf->trx->arfcn, ts, tbf->tsc(), 7, poll, tbf->trx->arfcn, ts, tbf->tsc(), 7, poll,
tbf->poll_fn, m_bts.alpha, m_bts.gamma, -1); tbf->poll_fn, m_bts.alpha, m_bts.gamma, -1);
if (plen >= 0) { if (plen >= 0) {

View File

@ -41,7 +41,7 @@ static uint32_t sched_poll(BTS *bts,
poll_fn = fn + 4; poll_fn = fn + 4;
if ((block_nr % 3) == 2) if ((block_nr % 3) == 2)
poll_fn ++; poll_fn ++;
poll_fn = poll_fn % 2715648; poll_fn = poll_fn % GSM_MAX_FN;
llist_for_each(pos, &bts->ul_tbfs()) { llist_for_each(pos, &bts->ul_tbfs()) {
ul_tbf = as_ul_tbf(pos->entry()); ul_tbf = as_ul_tbf(pos->entry());
OSMO_ASSERT(ul_tbf); OSMO_ASSERT(ul_tbf);

View File

@ -20,6 +20,11 @@ inline int msecs_to_frames(int msecs) {
return (msecs * (1024 * 1000 / 4615)) / 1024; return (msecs * (1024 * 1000 / 4615)) / 1024;
} }
inline uint32_t next_fn(uint32_t fn, uint32_t offset)
{
return (fn + offset) % GSM_MAX_FN;
}
inline void csecs_to_timeval(unsigned csecs, struct timeval *tv) { inline void csecs_to_timeval(unsigned csecs, struct timeval *tv) {
tv->tv_sec = csecs / 100; tv->tv_sec = csecs / 100;
tv->tv_usec = (csecs % 100) * 10000; tv->tv_usec = (csecs % 100) * 10000;

View File

@ -28,35 +28,39 @@ PollController::PollController(BTS& bts)
: m_bts(bts) : m_bts(bts)
{} {}
static inline bool elapsed_fn_check(unsigned max_delay, int frame_number, uint32_t from)
{
uint32_t elapsed = (frame_number + GSM_MAX_FN - from) % GSM_MAX_FN;
if (elapsed > max_delay && elapsed < 2715400)
return true;
return false;
}
void PollController::expireTimedout(int frame_number, unsigned max_delay) void PollController::expireTimedout(int frame_number, unsigned max_delay)
{ {
struct gprs_rlcmac_dl_tbf *dl_tbf; struct gprs_rlcmac_dl_tbf *dl_tbf;
struct gprs_rlcmac_ul_tbf *ul_tbf; struct gprs_rlcmac_ul_tbf *ul_tbf;
struct gprs_rlcmac_sba *sba, *sba2; struct gprs_rlcmac_sba *sba, *sba2;
LListHead<gprs_rlcmac_tbf> *pos; LListHead<gprs_rlcmac_tbf> *pos;
uint32_t elapsed;
llist_for_each(pos, &m_bts.ul_tbfs()) { llist_for_each(pos, &m_bts.ul_tbfs()) {
ul_tbf = as_ul_tbf(pos->entry()); ul_tbf = as_ul_tbf(pos->entry());
if (ul_tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) { if (ul_tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) {
elapsed = (frame_number + 2715648 - ul_tbf->poll_fn) if (elapsed_fn_check(max_delay, frame_number, ul_tbf->poll_fn))
% 2715648;
if (elapsed > max_delay && elapsed < 2715400)
ul_tbf->poll_timeout(); ul_tbf->poll_timeout();
} }
} }
llist_for_each(pos, &m_bts.dl_tbfs()) { llist_for_each(pos, &m_bts.dl_tbfs()) {
dl_tbf = as_dl_tbf(pos->entry()); dl_tbf = as_dl_tbf(pos->entry());
if (dl_tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) { if (dl_tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) {
elapsed = (frame_number + 2715648 - dl_tbf->poll_fn) if (elapsed_fn_check(max_delay, frame_number, dl_tbf->poll_fn))
% 2715648;
if (elapsed > max_delay && elapsed < 2715400)
dl_tbf->poll_timeout(); dl_tbf->poll_timeout();
} }
} }
llist_for_each_entry_safe(sba, sba2, &m_bts.sba()->m_sbas, list) { llist_for_each_entry_safe(sba, sba2, &m_bts.sba()->m_sbas, list) {
elapsed = (frame_number + 2715648 - sba->fn) % 2715648; if (elapsed_fn_check(max_delay, frame_number, sba->fn)) {
if (elapsed > max_delay && elapsed < 2715400) {
/* sba will be freed here */ /* sba will be freed here */
m_bts.sba()->timeout(sba); m_bts.sba()->timeout(sba);
} }

View File

@ -23,6 +23,7 @@
#include <gprs_rlcmac.h> #include <gprs_rlcmac.h>
#include <gprs_debug.h> #include <gprs_debug.h>
#include <bts.h> #include <bts.h>
#include <pcu_utils.h>
extern "C" { extern "C" {
#include <osmocom/core/talloc.h> #include <osmocom/core/talloc.h>
@ -75,7 +76,7 @@ int SBAController::alloc(
return -EINVAL; return -EINVAL;
} }
fn = (pdch->last_rts_fn + AGCH_START_OFFSET) % 2715648; fn = next_fn(pdch->last_rts_fn, AGCH_START_OFFSET);
sba->trx_no = trx; sba->trx_no = trx;
sba->ts_no = ts; sba->ts_no = ts;
@ -110,14 +111,13 @@ gprs_rlcmac_sba *SBAController::find(const gprs_rlcmac_pdch *pdch, uint32_t fn)
uint32_t SBAController::sched(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr) uint32_t SBAController::sched(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr)
{ {
uint32_t sba_fn; uint32_t sba_fn = fn + 4;
struct gprs_rlcmac_sba *sba; struct gprs_rlcmac_sba *sba;
/* check special TBF for events */ /* check special TBF for events */
sba_fn = fn + 4;
if ((block_nr % 3) == 2) if ((block_nr % 3) == 2)
sba_fn ++; sba_fn++;
sba_fn = sba_fn % 2715648; sba_fn = sba_fn % GSM_MAX_FN;
sba = find(trx, ts, sba_fn); sba = find(trx, ts, sba_fn);
if (sba) if (sba)
return sba_fn; return sba_fn;

View File

@ -566,8 +566,7 @@ void gprs_rlcmac_tbf::stop_timer()
int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts, int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts,
uint32_t *poll_fn_, unsigned int *rrbp_) uint32_t *poll_fn_, unsigned int *rrbp_)
{ {
uint32_t fn_offs = 13; uint32_t new_poll_fn = next_fn(fn, 13);
uint32_t new_poll_fn = (fn + fn_offs) % 2715648;
if (!is_control_ts(ts)) { if (!is_control_ts(ts)) {
LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be " LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be "
@ -581,7 +580,7 @@ int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts,
name()); name());
return -EBUSY; return -EBUSY;
} }
if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) { if (bts->sba()->find(trx->trx_no, ts, next_fn(fn, 13))) {
LOGP(DRLCMAC, LOGL_DEBUG, "%s: Polling is already scheduled " LOGP(DRLCMAC, LOGL_DEBUG, "%s: Polling is already scheduled "
"for single block allocation at FN %d TS %d ...\n", "for single block allocation at FN %d TS %d ...\n",
name(), new_poll_fn, ts); name(), new_poll_fn, ts);

View File

@ -1170,30 +1170,27 @@ bool gprs_rlcmac_dl_tbf::have_data() const
(llc_queue_size() > 0); (llc_queue_size() > 0);
} }
int gprs_rlcmac_dl_tbf::frames_since_last_poll(unsigned fn) const static inline int frames_since_last(int32_t last, unsigned fn)
{ {
unsigned wrapped; unsigned wrapped = (fn + GSM_MAX_FN - last) % GSM_MAX_FN;
if (m_last_dl_poll_fn < 0)
if (last < 0)
return -1; return -1;
wrapped = (fn + 2715648 - m_last_dl_poll_fn) % 2715648; if (wrapped < GSM_MAX_FN/2)
if (wrapped < 2715648/2)
return wrapped; return wrapped;
else
return wrapped - 2715648; return wrapped - GSM_MAX_FN;
}
int gprs_rlcmac_dl_tbf::frames_since_last_poll(unsigned fn) const
{
return frames_since_last(m_last_dl_poll_fn, fn);
} }
int gprs_rlcmac_dl_tbf::frames_since_last_drain(unsigned fn) const int gprs_rlcmac_dl_tbf::frames_since_last_drain(unsigned fn) const
{ {
unsigned wrapped; return frames_since_last(m_last_dl_drained_fn, fn);
if (m_last_dl_drained_fn < 0)
return -1;
wrapped = (fn + 2715648 - m_last_dl_drained_fn) % 2715648;
if (wrapped < 2715648/2)
return wrapped;
else
return wrapped - 2715648;
} }
bool gprs_rlcmac_dl_tbf::keep_open(unsigned fn) const bool gprs_rlcmac_dl_tbf::keep_open(unsigned fn) const

View File

@ -56,20 +56,6 @@ static void check_tbf(gprs_rlcmac_tbf *tbf)
OSMO_ASSERT(tbf->T != 0); OSMO_ASSERT(tbf->T != 0);
} }
/*
static unsigned inc_fn(fn)
{
unsigned next_fn;
next_fn = fn + 4;
if ((block_nr % 3) == 2)
next_fn ++;
next_fn = next_fn % 2715648;
return next_fn;
}
*/
static void test_tbf_base() static void test_tbf_base()
{ {
@ -209,7 +195,7 @@ static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
unsigned bn = fn2bn(fn) + blocks; unsigned bn = fn2bn(fn) + blocks;
fn = fn - (fn % 52); fn = fn - (fn % 52);
fn += bn * 4 + bn / 3; fn += bn * 4 + bn / 3;
return fn % 2715648; return fn % GSM_MAX_FN;
} }
static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts, static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,