Bluetooth: controller: Framework for new feature BT_CTLR_JIT_SCHEDULING

This option enables BT_TICKER_SLOT_AGNOSTIC which eliminates
priorities and collision resolving in the ticker.

Event scheduling states are stored in the lll_hdr, and event priority
is passed from LLL implementation, and runtime priority calculated.

LLL implementation decides whether to program radio, start preemption
timer, and/or queue prepare in the prepare pipeline.

Event arbitration is made possible via the common LLL, but not yet
implemented in Nordic LLL.

Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
Morten Priess 2021-03-03 16:13:35 +01:00 committed by Carles Cufí
commit 772a77718e
4 changed files with 66 additions and 1 deletions

View file

@ -570,6 +570,15 @@ config BT_TICKER_SLOT_AGNOSTIC
reservations and collision handling, and operates as a simple reservations and collision handling, and operates as a simple
multi-instance programmable timer. multi-instance programmable timer.
config BT_CTLR_JIT_SCHEDULING
bool "Just-in-Time Scheduling"
select BT_TICKER_SLOT_AGNOSTIC
help
This option enables the experimental 'Next Generation' scheduling
feature, which eliminates priorities and collision resolving in the
ticker, and instead relies on just-in-time ("lazy") resolution in
the link layer.
config BT_CTLR_USER_EXT config BT_CTLR_USER_EXT
prompt "Enable proprietary extensions in Controller" prompt "Enable proprietary extensions in Controller"
bool bool

View file

@ -160,12 +160,19 @@ struct ull_hdr {
struct lll_hdr { struct lll_hdr {
void *parent; void *parent;
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
uint8_t score;
uint8_t latency;
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
}; };
struct lll_prepare_param { struct lll_prepare_param {
uint32_t ticks_at_expire; uint32_t ticks_at_expire;
uint32_t remainder; uint32_t remainder;
uint16_t lazy; uint16_t lazy;
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
int8_t prio;
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
uint8_t force; uint8_t force;
void *param; void *param;
}; };
@ -379,8 +386,15 @@ static inline void lll_hdr_init(void *lll, void *parent)
struct lll_hdr *hdr = lll; struct lll_hdr *hdr = lll;
hdr->parent = parent; hdr->parent = parent;
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
hdr->score = 0U;
hdr->latency = 0U;
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
} }
void lll_done_score(void *param, uint8_t too_late, uint8_t aborted);
int lll_init(void); int lll_init(void);
int lll_reset(void); int lll_reset(void);
void lll_resume(void *param); void lll_resume(void *param);

View file

@ -41,7 +41,27 @@ int lll_prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
lll_prepare_cb_t prepare_cb, int8_t event_prio, lll_prepare_cb_t prepare_cb, int8_t event_prio,
struct lll_prepare_param *prepare_param) struct lll_prepare_param *prepare_param)
{ {
/* TODO: Calculate priority */ #if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
int prio = event_prio;
struct lll_hdr *hdr = prepare_param->param;
/* Establish priority based on:
* 1. Event priority passed to function
* 2. Force flag => priority = -127
* 3. Score (events terminated- and too late)
* 4. Latency (skipped- and programmed latency)
* 5. Critical priority is immutable (-128)
*/
if (prio > -128) {
if (prepare_param->force) {
prio = -127;
} else {
prio = MAX(-127, prio - hdr->score - hdr->latency);
}
}
prepare_param->prio = prio;
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
return lll_prepare_resolve(is_abort_cb, abort_cb, prepare_cb, return lll_prepare_resolve(is_abort_cb, abort_cb, prepare_cb,
prepare_param, 0, 0); prepare_param, 0, 0);
@ -58,3 +78,21 @@ void lll_resume(void *param)
next->is_resume, 1); next->is_resume, 1);
LL_ASSERT(!ret || ret == -EINPROGRESS); LL_ASSERT(!ret || ret == -EINPROGRESS);
} }
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
void lll_done_score(void *param, uint8_t too_late, uint8_t aborted)
{
struct lll_hdr *hdr = param;
if (!hdr) {
return;
}
if (!too_late && !aborted) {
hdr->score = 0;
hdr->latency = 0;
} else {
hdr->score++;
}
}
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */

View file

@ -344,6 +344,10 @@ int lll_done(void *param)
ull_prepare_dequeue(TICKER_USER_ID_LLL); ull_prepare_dequeue(TICKER_USER_ID_LLL);
#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ #endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
lll_done_score(param, 0, 0); /* TODO */
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
/* Let ULL know about LLL event done */ /* Let ULL know about LLL event done */
evdone = ull_event_done(ull); evdone = ull_event_done(ull);
LL_ASSERT(evdone); LL_ASSERT(evdone);