aboutsummaryrefslogtreecommitdiffstats
path: root/tests/alloc/AllocTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/alloc/AllocTest.cpp')
-rw-r--r--tests/alloc/AllocTest.cpp199
1 files changed, 199 insertions, 0 deletions
diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp
index ebd57c58..95a6cb6e 100644
--- a/tests/alloc/AllocTest.cpp
+++ b/tests/alloc/AllocTest.cpp
@@ -390,6 +390,204 @@ static void test_alloc_b()
test_all_alloc_b();
}
+typedef int (*algo_t)(struct gprs_rlcmac_bts *bts,
+ struct GprsMs *ms,
+ struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single);
+
+static char get_dir_char(uint8_t mask, uint8_t tx, uint8_t rx)
+{
+ return (mask & tx & rx) ? 'C' :
+ (mask & tx) ? 'U' :
+ (mask & rx) ? 'D' :
+ '.';
+}
+
+enum test_mode {
+ TEST_MODE_UL_ONLY,
+ TEST_MODE_DL_ONLY,
+ TEST_MODE_UL_AND_DL,
+ TEST_MODE_DL_AND_UL,
+ TEST_MODE_DL_AFTER_UL,
+ TEST_MODE_UL_AFTER_DL,
+};
+
+static GprsMs *alloc_tbfs(BTS *the_bts, GprsMs *ms, unsigned ms_class,
+ enum test_mode mode)
+{
+ struct gprs_rlcmac_bts *bts;
+ int tfi;
+ uint8_t trx_no;
+
+ bts = the_bts->bts_data();
+
+ gprs_rlcmac_tbf *tbf = NULL;
+
+ /* Allocate what is needed first */
+ switch (mode) {
+ case TEST_MODE_UL_ONLY:
+ case TEST_MODE_DL_AFTER_UL:
+ case TEST_MODE_UL_AND_DL:
+ tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+ if (tfi < 0)
+ return NULL;
+ tbf = tbf_alloc_ul_tbf(bts, ms, tfi, trx_no, ms_class, 0);
+ if (tbf == NULL)
+ return NULL;
+ break;
+ case TEST_MODE_DL_ONLY:
+ case TEST_MODE_UL_AFTER_DL:
+ case TEST_MODE_DL_AND_UL:
+ tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
+ tbf = tbf_alloc_dl_tbf(bts, ms, tfi, trx_no, ms_class, 0);
+ if (tbf == NULL)
+ return NULL;
+ }
+
+ OSMO_ASSERT(tbf);
+ OSMO_ASSERT(tbf->ms());
+ OSMO_ASSERT(ms == NULL || ms == tbf->ms());
+ ms = tbf->ms();
+
+ GprsMs::Guard guard(ms);
+
+ /* Optionally delete the TBF */
+ switch (mode) {
+ case TEST_MODE_DL_AFTER_UL:
+ case TEST_MODE_UL_AFTER_DL:
+ tbf_free(tbf);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Continue with what is needed next */
+ switch (mode) {
+ case TEST_MODE_UL_ONLY:
+ case TEST_MODE_DL_ONLY:
+ /* We are done */
+ return ms;
+
+ case TEST_MODE_DL_AFTER_UL:
+ case TEST_MODE_UL_AND_DL:
+ return alloc_tbfs(the_bts, ms, ms_class, TEST_MODE_DL_ONLY);
+
+ case TEST_MODE_UL_AFTER_DL:
+ case TEST_MODE_DL_AND_UL:
+ return alloc_tbfs(the_bts, ms, ms_class, TEST_MODE_UL_ONLY);
+ }
+
+ return NULL;
+}
+
+static void test_successive_allocation(algo_t algo, unsigned min_class,
+ unsigned max_class, enum test_mode mode,
+ unsigned expect_num, const char *text)
+{
+ BTS the_bts;
+ struct gprs_rlcmac_bts *bts;
+ struct gprs_rlcmac_trx *trx;
+ unsigned counter;
+ unsigned ms_class = min_class;
+
+ printf("Going to test assignment with many TBF, %s\n", text);
+
+ bts = the_bts.bts_data();
+ bts->alloc_algorithm = algo;
+
+ trx = &bts->trx[0];
+ trx->pdch[3].enable();
+ trx->pdch[4].enable();
+ trx->pdch[5].enable();
+ trx->pdch[6].enable();
+ trx->pdch[7].enable();
+
+ for (counter = 0; 1; counter += 1) {
+ gprs_rlcmac_tbf *ul_tbf, *dl_tbf;
+ uint8_t ul_slots = 0;
+ uint8_t dl_slots = 0;
+ unsigned i;
+ int tfi = -1;
+ GprsMs *ms;
+
+ ms = alloc_tbfs(&the_bts, NULL, ms_class, mode);
+ if (!ms)
+ break;
+
+ ul_tbf = ms->ul_tbf();
+ dl_tbf = ms->dl_tbf();
+
+ if (ul_tbf) {
+ ul_slots = 1 << ul_tbf->first_common_ts;
+ tfi = ul_tbf->tfi();
+ } else if (dl_tbf) {
+ ul_slots = 1 << dl_tbf->first_common_ts;
+ tfi = dl_tbf->tfi();
+ }
+
+ for (i = 0; dl_tbf && i < ARRAY_SIZE(dl_tbf->pdch); i += 1)
+ if (dl_tbf->pdch[i])
+ dl_slots |= 1 << i;
+
+ printf(" TBF[%d] class %d reserves %c%c%c%c%c%c%c%c\n",
+ tfi, ms_class,
+ get_dir_char(0x01, ul_slots, dl_slots),
+ get_dir_char(0x02, ul_slots, dl_slots),
+ get_dir_char(0x04, ul_slots, dl_slots),
+ get_dir_char(0x08, ul_slots, dl_slots),
+ get_dir_char(0x10, ul_slots, dl_slots),
+ get_dir_char(0x20, ul_slots, dl_slots),
+ get_dir_char(0x40, ul_slots, dl_slots),
+ get_dir_char(0x80, ul_slots, dl_slots));
+
+ ms_class += 1;
+ if (ms_class > max_class)
+ ms_class = min_class;
+ }
+
+ printf(" Successfully allocated %d UL TBFs\n", counter);
+ OSMO_ASSERT(counter >= expect_num);
+}
+
+static void test_successive_allocation()
+{
+ test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_UL_AND_DL,
+ 7, "algorithm A (UL and DL)");
+ test_successive_allocation(alloc_algorithm_b, 10, 10, TEST_MODE_UL_AND_DL,
+ 7, "algorithm B class 10 (UL and DL)");
+ test_successive_allocation(alloc_algorithm_b, 12, 12, TEST_MODE_UL_AND_DL,
+ 7, "algorithm B class 12 (UL and DL)");
+ test_successive_allocation(alloc_algorithm_b, 1, 12, TEST_MODE_UL_AND_DL,
+ 14, "algorithm B class 1-12 (UL and DL)");
+ test_successive_allocation(alloc_algorithm_b, 1, 29, TEST_MODE_UL_AND_DL,
+ 18, "algorithm B class 1-29 (UL and DL)");
+
+ test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_DL_AND_UL,
+ 7, "algorithm A (DL and UL)");
+ test_successive_allocation(alloc_algorithm_b, 10, 10, TEST_MODE_DL_AND_UL,
+ 7, "algorithm B class 10 (DL and UL)");
+
+ test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_DL_AFTER_UL,
+ 7, "algorithm A (DL after UL)");
+ test_successive_allocation(alloc_algorithm_b, 10, 10, TEST_MODE_DL_AFTER_UL,
+ 7, "algorithm B class 10 (DL after UL)");
+
+ test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_UL_AFTER_DL,
+ 7, "algorithm A (UL after DL)");
+ test_successive_allocation(alloc_algorithm_b, 10, 10, TEST_MODE_UL_AFTER_DL,
+ 7, "algorithm B class 10 (UL after DL)");
+
+ test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_UL_ONLY,
+ 7, "algorithm A (UL only)");
+ test_successive_allocation(alloc_algorithm_b, 10, 10, TEST_MODE_UL_ONLY,
+ 7, "algorithm B class 10 (UL only)");
+
+ test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_DL_ONLY,
+ 7, "algorithm A (DL ONLY)");
+ test_successive_allocation(alloc_algorithm_b, 10, 10, TEST_MODE_DL_ONLY,
+ 7, "algorithm B class 10 (DL ONLY)");
+}
+
int main(int argc, char **argv)
{
tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile AllocTest context");
@@ -403,6 +601,7 @@ int main(int argc, char **argv)
test_alloc_a();
test_alloc_b();
+ test_successive_allocation();
return EXIT_SUCCESS;
}