summaryrefslogtreecommitdiff
path: root/cesar/mac
diff options
context:
space:
mode:
authorNicolas Schodet2010-09-21 11:22:24 +0200
committerNicolas Schodet2010-09-21 17:59:07 +0200
commitf3d92fd1e35ad7da5a9866edb5ca750dc3da9e31 (patch)
treeab973b261c0f88e7c50aed5237f708317183a1a6 /cesar/mac
parent925c74aef29af1f88557dd66d62a42228dec3144 (diff)
cesar/mac/pbproc: only extract last segment if there is room left, refs #1868
Diffstat (limited to 'cesar/mac')
-rw-r--r--cesar/mac/pbproc/pbproc.h4
-rw-r--r--cesar/mac/pbproc/src/mfs.c49
-rw-r--r--cesar/mac/pbproc/test/mfs/src/test_mfs.c9
3 files changed, 43 insertions, 19 deletions
diff --git a/cesar/mac/pbproc/pbproc.h b/cesar/mac/pbproc/pbproc.h
index e38d1cb76e..020e1a8fb5 100644
--- a/cesar/mac/pbproc/pbproc.h
+++ b/cesar/mac/pbproc/pbproc.h
@@ -264,7 +264,7 @@ void
pbproc_spoc_coeff_set (pbproc_t *ctx, phy_spoc_coeff_t *coeff);
/**
- * Extract the last segment from an MFS.
+ * Extract the last segment from an MFS in order to segment more data.
* \param mfs MFS to extract from
* \return the last segment or NULL
*
@@ -275,6 +275,8 @@ pbproc_spoc_coeff_set (pbproc_t *ctx, phy_spoc_coeff_t *coeff);
* been taken by the PB Processing already.
*
* This involves the following actions:
+ * - In any cases, if there is no room left in the tail segment (because it
+ * was full or it was sent on medium yet), NULL is returned.
* - If the tail is not owned by the PB Processing, tail is returned without
* any delay.
* - If the tail is owned by the PB Processing, this function tries to take
diff --git a/cesar/mac/pbproc/src/mfs.c b/cesar/mac/pbproc/src/mfs.c
index 101710cdda..62961b7ba8 100644
--- a/cesar/mac/pbproc/src/mfs.c
+++ b/cesar/mac/pbproc/src/mfs.c
@@ -31,24 +31,32 @@ pbproc_mfs_extract_tail (mfs_tx_t *mfs)
/* Tail is not owned by the PB Processing, return immediately. */
if (mfs->pending_seg_nb > 0)
{
- return mfs->tail;
+ if (mfs->last_seg_offset != 0)
+ return mfs->tail;
+ else
+ return 0;
}
else
{
- volatile mfs_tx_t *vmfs = mfs;
- /* Decrement seg_nb to forbid PB Processing to take the last segment. */
- arch_atomic_add (&vmfs->seg_nb, -1);
- if (vmfs->seg_nb == -1)
+ uint flags = arch_isr_lock ();
+ /* If there is a segment owned by PBProc with room for more data, take
+ * it. */
+ if (mfs->seg_nb && mfs->last_seg_offset != 0)
{
- /* Seg_nb was zero, cancel extraction. */
- arch_atomic_add (&vmfs->seg_nb, 1);
- return NULL;
+ /* Decrement seg_nb to forbid PB Processing to take the last
+ * segment. */
+ mfs->seg_nb--;
+ mfs->pending_seg_nb++;
+ arch_isr_unlock (flags);
+ return mfs->tail;
}
else
{
- /* Extraction successful. */
- vmfs->pending_seg_nb++;
- return vmfs->tail;
+ arch_isr_unlock (flags);
+ /* Clear last_seg_offset. If a frame is currently being prepared,
+ * its last segment will never be used again for segmentation. */
+ mfs->last_seg_offset = 0;
+ return NULL;
}
}
}
@@ -140,19 +148,24 @@ pbproc_mfs_beacon_prepare (pbproc_t *ctx, mfs_tx_t *mfs, pb_beacon_t *pb,
+ MAC_PB136_BYTES);
*after_payload = *params;
/* Cancel the previous beacon if possible. */
- pb_t *tail = pbproc_mfs_extract_tail (mfs);
- if (tail)
+ uint flags = arch_isr_lock ();
+ if (mfs->seg_nb)
{
- /* Unchain, the MFS can not be active because there is no segment to
- * send. */
+ /* Decrement seg_nb to forbid PB Processing to take the last
+ * segment. */
+ mfs->seg_nb--;
+ pb_t *tail = mfs->tail;
+ /* Unchain. */
dbg_assert (mfs->seg_nb == 0);
dbg_assert (mfs->head == tail && mfs->tail == tail);
- mfs->head = NULL;
- dbg_invalid_ptr (mfs->tail);
- mfs->pending_seg_nb--;
+ slist_init (mfs->, bare);
+ /* End of critical section. */
+ arch_isr_unlock (flags);
/* Release previous beacon. */
blk_release_desc (&tail->blk);
}
+ else
+ arch_isr_unlock (flags);
/* Add the segment. */
pbproc_mfs_insert_ (mfs, (pb_t *) pb, (pb_t *) pb, 1);
pbproc_mfs_provide (mfs, 1);
diff --git a/cesar/mac/pbproc/test/mfs/src/test_mfs.c b/cesar/mac/pbproc/test/mfs/src/test_mfs.c
index 10795ea5b8..c706057be5 100644
--- a/cesar/mac/pbproc/test/mfs/src/test_mfs.c
+++ b/cesar/mac/pbproc/test/mfs/src/test_mfs.c
@@ -129,6 +129,9 @@ test_pbproc_take (test_pbproc_t *ctx, mfs_tx_t *mfs, uint tt)
ctx->to_take--;
ctx->tx_seg_nb++;
}
+ /* Took last segment? */
+ if (slist_empty (mfs->, bare))
+ mfs->last_seg_offset = 0;
}
void
@@ -195,6 +198,10 @@ mfs_basic_test_case (test_t t)
+ param.sar_add_min;
test_verbose_print ("add: %d", add);
pb_t *tail = pbproc_mfs_extract_tail (mfs);
+ if (tail)
+ test_fail_unless (mfs->last_seg_offset);
+ else
+ test_fail_if (mfs->last_seg_offset);
IT ();
uint insert = tail ? add - 1 : add;
test_verbose_print ("insert: %d", insert);
@@ -222,6 +229,8 @@ mfs_basic_test_case (test_t t)
pbproc_mfs_insert (mfs, sar_head, sar_tail, insert);
IT ();
}
+ mfs->last_seg_offset = 1;
+ IT ();
pbproc_mfs_provide (mfs, add);
IT ();
}