aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bts.h2
-rw-r--r--src/gprs_rlcmac_ts_alloc.cpp46
2 files changed, 45 insertions, 3 deletions
diff --git a/src/bts.h b/src/bts.h
index f2b992bd..1a6d259a 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -182,6 +182,8 @@ struct gprs_rlcmac_bts {
/* list of downlink TBFs */
struct llist_head dl_tbfs;
+ /* State for dynamic algorithm selection */
+ int multislot_disabled;
/**
* Point back to the C++ object. This is used during the transition
diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp
index e2c2a0f4..3714b30c 100644
--- a/src/gprs_rlcmac_ts_alloc.cpp
+++ b/src/gprs_rlcmac_ts_alloc.cpp
@@ -28,6 +28,9 @@
#include <errno.h>
#include <values.h>
+/* Consider a PDCH as idle if has at most this number of TBFs assigned to it */
+#define PDCH_IDLE_TBF_THRESH 1
+
/* 3GPP TS 05.02 Annex B.1 */
#define MS_NA 255 /* N/A */
@@ -363,6 +366,30 @@ static int find_trx(BTS *bts, const GprsMs *ms, int use_trx)
return -EBUSY;
}
+static struct gprs_rlcmac_pdch * find_idle_pdch(BTS *bts)
+{
+ unsigned trx_no;
+ unsigned ts;
+ struct gprs_rlcmac_bts *bts_data = bts->bts_data();
+
+ /* Find the first PDCH with an unused DL TS */
+ for (trx_no = 0; trx_no < ARRAY_SIZE(bts_data->trx); trx_no += 1) {
+ struct gprs_rlcmac_trx *trx = &bts_data->trx[trx_no];
+ for (ts = 0; ts < ARRAY_SIZE(trx->pdch); ts++) {
+ struct gprs_rlcmac_pdch *pdch = &trx->pdch[ts];
+ if (!pdch->is_enabled())
+ continue;
+
+ if (pdch->num_tbfs(GPRS_RLCMAC_DL_TBF) > PDCH_IDLE_TBF_THRESH)
+ continue;
+
+ return pdch;
+ }
+ }
+
+ return NULL;
+}
+
static int tfi_find_free(BTS *bts, const GprsMs *ms,
enum gprs_rlcmac_tbf_direction dir, int use_trx, int *trx_no_)
{
@@ -1030,9 +1057,22 @@ int alloc_algorithm_dynamic(struct gprs_rlcmac_bts *bts,
{
int rc;
- rc = alloc_algorithm_b(bts, ms_, tbf_, cust, single, use_trx);
- if (rc >= 0)
- return rc;
+ /* Reset load_is_high if there is at least one idle PDCH */
+ if (bts->multislot_disabled) {
+ bts->multislot_disabled = find_idle_pdch(bts->bts) == NULL;
+ if (!bts->multislot_disabled)
+ LOGP(DRLCMAC, LOGL_DEBUG, "Enabling algorithm B\n");
+ }
+
+ if (!bts->multislot_disabled) {
+ rc = alloc_algorithm_b(bts, ms_, tbf_, cust, single, use_trx);
+ if (rc >= 0)
+ return rc;
+
+ if (!bts->multislot_disabled)
+ LOGP(DRLCMAC, LOGL_DEBUG, "Disabling algorithm B\n");
+ bts->multislot_disabled = 1;
+ }
rc = alloc_algorithm_a(bts, ms_, tbf_, cust, single, use_trx);
return rc;