summaryrefslogtreecommitdiff
path: root/cesar/mac
diff options
context:
space:
mode:
authorNicolas Schodet2012-06-07 08:57:38 +0200
committerNicolas Schodet2012-06-27 11:11:54 +0200
commit62ec663af87cf359d07f2edc60e8c74443569e16 (patch)
tree324e4057f823c9901cb57d163fa3a7873e80e031 /cesar/mac
parent463f0847697ec238376ef1f6b438f79d09daa03f (diff)
cesar/mac/common: add mfs_tx_max_seg_nb_update, refs #3087
Diffstat (limited to 'cesar/mac')
-rw-r--r--cesar/mac/common/mfs.h7
-rw-r--r--cesar/mac/common/src/mfs.c28
-rw-r--r--cesar/mac/common/test/mfs/src/test_mfs.c41
3 files changed, 76 insertions, 0 deletions
diff --git a/cesar/mac/common/mfs.h b/cesar/mac/common/mfs.h
index a07acc0f82..619000a482 100644
--- a/cesar/mac/common/mfs.h
+++ b/cesar/mac/common/mfs.h
@@ -297,6 +297,13 @@ mfs_tx_init (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei);
void
mfs_tx_init_unassociated (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei);
+/**
+ * Update the MFS TX segment limit.
+ * \param active_nb number of active MFS
+ */
+void
+mfs_tx_max_seg_nb_update (int active_nb);
+
END_DECLS
#endif /* mac_common_mfs_h */
diff --git a/cesar/mac/common/src/mfs.c b/cesar/mac/common/src/mfs.c
index f28139d695..2d500507eb 100644
--- a/cesar/mac/common/src/mfs.c
+++ b/cesar/mac/common/src/mfs.c
@@ -16,6 +16,11 @@
#include "mac/common/defs.h"
#include "mac/common/timings.h"
+#include "common/module.h"
+#if MODULE_INCLUDED (mac_sar)
+#include "config/sar/pbpool/size.h"
+#endif
+
/** MFS MME window size (fixed). */
#define MFS_WINDOW_SIZE_MME MFS_WINDOW_SIZE_8
@@ -28,6 +33,9 @@
/** Default TX MFS segment limit. */
#define MFS_TX_MAX_SEG_NB_DEFAULT 1200
+/** Minimum TX MFS segment limit. */
+#define MFS_TX_MAX_SEG_NB_MIN 42
+
/** Window size values table (values of the RxWSz field of the FCs in which
* it is included). */
const u16 mfs_window_size[MFS_WINDOW_SIZE_NB] = { 4, 8, 16, 24, 32, 48, 64, 80,
@@ -127,3 +135,23 @@ mfs_tx_init_unassociated (mfs_tx_t *mfs, bool bcast, bool mme, uint lid,
mfs->fsm_state = MFS_FSM_CMD_NOP;
}
+void
+mfs_tx_max_seg_nb_update (int active_nb)
+{
+ /* Try to have a good estimate of available memory. */
+ uint blk_nb = blk_slack_total ();
+#ifdef CONFIG_SAR_PBPOOL_SIZE
+ blk_nb -= CONFIG_SAR_PBPOOL_SIZE;
+#endif
+ /* Empiric margin. */
+ blk_nb = blk_nb * 15 / 16;
+ /* Now share all this memory between active MFS. */
+ int new_limit = blk_nb / (active_nb + 1);
+ if (new_limit > MFS_TX_MAX_SEG_NB_DEFAULT)
+ mfs_tx_max_seg_nb = MFS_TX_MAX_SEG_NB_DEFAULT;
+ else if (new_limit < MFS_TX_MAX_SEG_NB_MIN)
+ mfs_tx_max_seg_nb = MFS_TX_MAX_SEG_NB_MIN;
+ else
+ mfs_tx_max_seg_nb = new_limit;
+}
+
diff --git a/cesar/mac/common/test/mfs/src/test_mfs.c b/cesar/mac/common/test/mfs/src/test_mfs.c
index e6c2f20f54..1e688ea457 100644
--- a/cesar/mac/common/test/mfs/src/test_mfs.c
+++ b/cesar/mac/common/test/mfs/src/test_mfs.c
@@ -42,10 +42,51 @@ mfs_window_size_test_case (test_t t)
}
void
+mfs_tx_max_seg_nb_test_case (test_t t)
+{
+ /* Make an allocation to initialise the allocator. */
+ blk_release (blk_alloc ());
+ /* Now test. */
+ test_case_begin (t, "mfs_tx_max_seg_nb");
+ test_begin (t, "default")
+ {
+ test_fail_unless (mfs_tx_max_seg_nb < 2000 && mfs_tx_max_seg_nb > 10);
+ } test_end;
+ int def = mfs_tx_max_seg_nb;
+ test_begin (t, "update low")
+ {
+ mfs_tx_max_seg_nb_update (0);
+ test_fail_unless (mfs_tx_max_seg_nb == def);
+ mfs_tx_max_seg_nb_update (1);
+ test_fail_unless (mfs_tx_max_seg_nb == def);
+ mfs_tx_max_seg_nb_update (2);
+ test_fail_unless (mfs_tx_max_seg_nb == def);
+ } test_end;
+ test_begin (t, "update high")
+ {
+ mfs_tx_max_seg_nb_update (1000);
+ test_fail_unless (mfs_tx_max_seg_nb > 10
+ && mfs_tx_max_seg_nb < def / 10);
+ } test_end;
+ test_begin (t, "update middle")
+ {
+ uint i;
+ int last = def;
+ for (i = 10; i < 20; i++)
+ {
+ mfs_tx_max_seg_nb_update (i);
+ test_fail_unless (mfs_tx_max_seg_nb < last);
+ last = mfs_tx_max_seg_nb;
+ }
+ } test_end;
+}
+
+void
mfs_test_suite (test_t t)
{
test_suite_begin (t, "mfs");
mfs_window_size_test_case (t);
+ mfs_tx_max_seg_nb_test_case (t);
}
int