Skip to content

Commit 01d6254

Browse files
committed
Bluetooth: Controller: Replace prepare pipeline with ordered list
Replace prepare pipeline with ordered linked list. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
1 parent 419b28f commit 01d6254

File tree

3 files changed

+230
-135
lines changed

3 files changed

+230
-135
lines changed

‎subsys/bluetooth/controller/ll_sw/lll.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ struct lll_event *ull_prepare_enqueue(lll_is_abort_cb_t is_abort_cb,
614614
lll_prepare_cb_t prepare_cb,
615615
uint8_t is_resume);
616616
void *ull_prepare_dequeue_get(void);
617-
void *ull_prepare_dequeue_iter(uint8_t *idx);
617+
void *ull_prepare_dequeue_iter(void **idx);
618618
void ull_prepare_dequeue(uint8_t caller_id);
619619
void *ull_pdu_rx_alloc_peek(uint8_t count);
620620
void *ull_pdu_rx_alloc_peek_iter(uint8_t *idx);

‎subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c‎

Lines changed: 39 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ static int init_reset(void);
7171
static inline void done_inc(void);
7272
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
7373
static inline bool is_done_sync(void);
74-
static inline struct lll_event *prepare_dequeue_iter_ready_get(uint8_t *idx);
74+
static inline struct lll_event *prepare_dequeue_iter_ready_get(void **idx);
7575
static inline struct lll_event *resume_enqueue(lll_is_abort_cb_t is_abort_cb,
7676
lll_abort_cb_t abort_cb, lll_prepare_cb_t resume_cb,
7777
void *param, uint32_t ticks_at_expire);
@@ -464,9 +464,9 @@ void lll_disable(void *param)
464464
}
465465
{
466466
struct lll_event *next;
467-
uint8_t idx;
467+
void *idx;
468468

469-
idx = UINT8_MAX;
469+
idx = NULL;
470470
next = ull_prepare_dequeue_iter(&idx);
471471
while (next) {
472472
if (!next->is_aborted &&
@@ -480,8 +480,10 @@ void lll_disable(void *param)
480480
* the prepare pipeline hence re-iterate
481481
* through the prepare pipeline.
482482
*/
483-
idx = UINT8_MAX;
483+
idx = NULL;
484484
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
485+
} else if (!idx) {
486+
break;
485487
}
486488

487489
next = ull_prepare_dequeue_iter(&idx);
@@ -830,18 +832,17 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
830832
struct lll_event *ready_short = NULL;
831833
struct lll_event *ready;
832834
struct lll_event *next;
833-
uint8_t idx;
835+
void *idx;
834836
int err;
835837

836838
/* Find the ready prepare in the pipeline */
837-
idx = UINT8_MAX;
839+
idx = NULL;
838840
ready = prepare_dequeue_iter_ready_get(&idx);
839841

840842
/* Find any short prepare */
841843
if (ready) {
842844
uint32_t ticks_at_preempt_min = prepare_param->ticks_at_expire;
843845
uint32_t ticks_at_preempt_next;
844-
uint8_t idx_backup = idx;
845846
uint32_t diff;
846847

847848
ticks_at_preempt_next = ready->prepare_param.ticks_at_expire;
@@ -854,12 +855,15 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
854855
}
855856
} else {
856857
ready = NULL;
857-
idx_backup = UINT8_MAX;
858858
}
859859

860860
do {
861861
struct lll_event *ready_next;
862862

863+
if (!idx) {
864+
break;
865+
}
866+
863867
ready_next = prepare_dequeue_iter_ready_get(&idx);
864868
if (!ready_next) {
865869
break;
@@ -875,8 +879,6 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
875879
ready_short = ready_next;
876880
ticks_at_preempt_min = ticks_at_preempt_next;
877881
} while (true);
878-
879-
idx = idx_backup;
880882
}
881883

882884
/* Current event active or another prepare is ready in the pipeline */
@@ -927,6 +929,8 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
927929
} else {
928930
next = ready;
929931
}
932+
} else if (!idx) {
933+
break;
930934
}
931935

932936
ready = ull_prepare_dequeue_iter(&idx);
@@ -986,6 +990,7 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
986990
*/
987991

988992
/* Find next prepare needing preempt timeout to be setup */
993+
idx = NULL;
989994
next = prepare_dequeue_iter_ready_get(&idx);
990995
if (!next) {
991996
return err;
@@ -1022,14 +1027,20 @@ static inline bool is_done_sync(void)
10221027
#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
10231028
}
10241029

1025-
static inline struct lll_event *prepare_dequeue_iter_ready_get(uint8_t *idx)
1030+
static inline struct lll_event *prepare_dequeue_iter_ready_get(void **idx)
10261031
{
10271032
struct lll_event *ready;
10281033

1029-
do {
1034+
ready = ull_prepare_dequeue_iter(idx);
1035+
while ((ready != NULL) && ((ready->is_aborted != 0U) || (ready->is_resume != 0U) ||
1036+
(ready->prepare_param.defer != 0U))) {
1037+
if (!*idx) {
1038+
ready = NULL;
1039+
break;
1040+
}
1041+
10301042
ready = ull_prepare_dequeue_iter(idx);
1031-
} while ((ready != NULL) && ((ready->is_aborted != 0U) || (ready->is_resume != 0U) ||
1032-
(ready->prepare_param.defer != 0U)));
1043+
}
10331044

10341045
return ready;
10351046
}
@@ -1222,17 +1233,16 @@ static void preempt(void *param)
12221233
{
12231234
lll_prepare_cb_t resume_cb;
12241235
struct lll_event *ready;
1225-
uint8_t idx;
1236+
void *idx;
12261237
int err;
12271238

12281239
/* No event to abort */
12291240
if (!event.curr.abort_cb || !event.curr.param) {
12301241
return;
12311242
}
12321243

1233-
preempt_find_preemptor:
12341244
/* Find a prepare that is ready and not a resume */
1235-
idx = UINT8_MAX;
1245+
idx = NULL;
12361246
ready = prepare_dequeue_iter_ready_get(&idx);
12371247
if (!ready) {
12381248
/* No ready prepare */
@@ -1251,6 +1261,11 @@ static void preempt(void *param)
12511261
uint32_t ticks_at_preempt_next;
12521262
uint32_t diff;
12531263

1264+
if (!idx) {
1265+
preemptor = NULL;
1266+
break;
1267+
}
1268+
12541269
preemptor = prepare_dequeue_iter_ready_get(&idx);
12551270
if (!preemptor) {
12561271
break;
@@ -1292,36 +1307,7 @@ static void preempt(void *param)
12921307
return;
12931308
}
12941309

1295-
/* FIXME: Prepare pipeline is not a ordered list implementation,
1296-
* and for short prepare being enqueued, ideally the
1297-
* pipeline has to be implemented as ordered list.
1298-
* Until then a workaround to abort a prepare present
1299-
* before the short prepare being enqueued is implemented
1300-
* below.
1301-
* A proper solution will be to re-design the pipeline
1302-
* as a ordered list, instead of the current FIFO.
1303-
*/
1304-
1305-
/* Abort the prepare that is present before the short prepare */
1306-
ready->is_aborted = 1;
1307-
ready->abort_cb(&ready->prepare_param, ready->prepare_param.param);
1308-
1309-
/* Abort all events in pipeline before the short prepare */
1310-
if (preemptor != ready_next) {
1311-
goto preempt_find_preemptor;
1312-
}
1313-
1314-
/* As the prepare queue has been refreshed due to the call of
1315-
* abort_cb which invokes the lll_done, find the latest prepare
1316-
*/
1317-
idx = UINT8_MAX;
1318-
ready = prepare_dequeue_iter_ready_get(&idx);
1319-
if (!ready) {
1320-
/* No ready prepare */
1321-
return;
1322-
}
1323-
1324-
LL_ASSERT(ready->prepare_param.param == param);
1310+
ready = preemptor;
13251311
}
13261312

13271313
/* Check if current event want to continue */
@@ -1414,8 +1400,8 @@ static void preempt(void *param)
14141400
lll_abort_cb_t abort_cb;
14151401
uint8_t is_resume_abort;
14161402
struct lll_event *iter;
1417-
uint8_t iter_idx;
14181403
void *curr_param;
1404+
void *iter_idx;
14191405

14201406
/* Remove parameter assignment from currently active radio event so that done event
14211407
* is not generated.
@@ -1434,8 +1420,8 @@ static void preempt(void *param)
14341420
is_resume_abort = 0U;
14351421

14361422
preempt_abort_resume:
1437-
/* Abort any duplicate non-resume, that they get dequeued */
1438-
iter_idx = UINT8_MAX;
1423+
/* Abort any duplicates so that they get dequeued */
1424+
iter_idx = NULL;
14391425
iter = ull_prepare_dequeue_iter(&iter_idx);
14401426
while (iter) {
14411427
if (!iter->is_aborted &&
@@ -1450,8 +1436,10 @@ static void preempt(void *param)
14501436
* the prepare pipeline hence re-iterate
14511437
* through the prepare pipeline.
14521438
*/
1453-
iter_idx = UINT8_MAX;
1439+
iter_idx = NULL;
14541440
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
1441+
} else if (!iter_idx) {
1442+
break;
14551443
}
14561444

14571445
iter = ull_prepare_dequeue_iter(&iter_idx);

0 commit comments

Comments
 (0)