Bluetooth: Controller: Ticker low latency with lazy skip

Update the legacy low latency variant of the ticker
implementation to skip to next periodic interval when
ticks to expire is behind the current tick. This makes
the low latency variant of the implementation consistent
with the default ticker implementation.

Also, cleanup conditional compiles in the implementation.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2024-01-13 07:00:30 +01:00 committed by Carles Cufí
commit 7845c0e3d6

View file

@ -494,7 +494,11 @@ static void ticker_by_next_slot_get(struct ticker_instance *instance,
break;
}
} else
#endif /* CONFIG_BT_TICKER_NEXT_SLOT_GET_MATCH */
#else /* !CONFIG_BT_TICKER_NEXT_SLOT_GET_MATCH */
ARG_UNUSED(fp_match_op_func);
ARG_UNUSED(match_op_context);
#endif /* !CONFIG_BT_TICKER_NEXT_SLOT_GET_MATCH */
#if !defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC)
if (ticker->ticks_slot) {
/* Matching not used and node has slot ticks */
@ -519,13 +523,17 @@ static void ticker_by_next_slot_get(struct ticker_instance *instance,
if (remainder) {
*remainder = ticker->remainder_current;
}
#endif /* CONFIG_BT_TICKER_REMAINDER_GET */
#else /* !CONFIG_BT_TICKER_REMAINDER_GET */
ARG_UNUSED(remainder);
#endif /* !CONFIG_BT_TICKER_REMAINDER_GET */
#if defined(CONFIG_BT_TICKER_LAZY_GET)
if (lazy) {
*lazy = ticker->lazy_current;
}
#endif /* CONFIG_BT_TICKER_LAZY_GET */
#else /* !CONFIG_BT_TICKER_LAZY_GET */
ARG_UNUSED(lazy);
#endif /* !CONFIG_BT_TICKER_LAZY_GET */
}
*ticker_id_head = _ticker_id_head;
@ -602,7 +610,7 @@ static uint8_t ticker_enqueue(struct ticker_instance *instance, uint8_t id)
return id;
}
#else /* !CONFIG_BT_TICKER_LOW_LAT */
#else /* CONFIG_BT_TICKER_LOW_LAT */
/**
* @brief Enqueue ticker node
@ -699,7 +707,7 @@ static uint8_t ticker_enqueue(struct ticker_instance *instance, uint8_t id)
return id;
}
#endif /* !CONFIG_BT_TICKER_LOW_LAT */
#endif /* CONFIG_BT_TICKER_LOW_LAT */
/**
* @brief Dequeue ticker node
@ -1727,7 +1735,9 @@ static inline uint32_t ticker_job_node_update(struct ticker_instance *instance,
ticker_mark_expire_info_outdated(instance, user_op->id);
}
}
#endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
#else /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
ARG_UNUSED(instance);
#endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
ticker->next = *insert_head;
*insert_head = user_op->id;
@ -2003,12 +2013,9 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
{
struct ticker_node *node;
uint32_t ticks_expired;
#if !defined(CONFIG_BT_TICKER_LOW_LAT)
uint32_t ticks_latency;
ticks_latency = ticker_ticks_diff_get(ticks_now, ticks_previous);
#endif /* !CONFIG_BT_TICKER_LOW_LAT */
node = &instance->nodes[0];
ticks_expired = 0U;
@ -2032,13 +2039,12 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
/* decrement ticks_elapsed and collect expired ticks */
ticks_elapsed -= ticks_to_expire;
ticks_latency -= ticks_to_expire;
ticks_expired += ticks_to_expire;
state = (ticker->req - ticker->ack) & 0xff;
#if !defined(CONFIG_BT_TICKER_LOW_LAT)
ticks_latency -= ticks_to_expire;
/* Node with lazy count did not expire with callback, but
* was either a collision or re-scheduled. This node should
* not define the active slot reservation (slot_previous).
@ -2150,9 +2156,11 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
}
ticks_to_expire_prep(ticker, instance->ticks_current,
(ticks_previous + ticks_expired));
#else /* !CONFIG_BT_TICKER_LOW_LAT */
((ticks_previous + ticks_expired) &
HAL_TICKER_CNTR_MASK));
#else /* CONFIG_BT_TICKER_LOW_LAT */
uint32_t count;
uint16_t lazy;
/* Prepare for next interval */
ticks_to_expire = 0U;
@ -2161,15 +2169,31 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
ticks_to_expire += ticker->ticks_periodic;
ticks_to_expire += ticker_remainder_inc(ticker);
}
/* Skip intervals that have elapsed w.r.t. current
* ticks.
*/
lazy = 0U;
/* Schedule to a tick in the future */
while (ticks_to_expire < ticks_latency) {
ticks_to_expire += ticker->ticks_periodic;
ticks_to_expire += ticker_remainder_inc(ticker);
lazy++;
}
/* Use the calculated ticks to expire and laziness. */
ticker->ticks_to_expire = ticks_to_expire;
ticker->lazy_current = ticker->lazy_periodic + lazy;
ticks_to_expire_prep(ticker, instance->ticks_current,
(ticks_previous + ticks_expired));
((ticks_previous + ticks_expired) &
HAL_TICKER_CNTR_MASK));
/* Reset latency to periodic offset */
ticker->lazy_current = ticker->lazy_periodic;
/* Reset force state of the node */
ticker->force = 0U;
#endif /* !CONFIG_BT_TICKER_LOW_LAT */
#endif /* CONFIG_BT_TICKER_LOW_LAT */
/* Add to insert list */
ticker->next = *insert_head;
*insert_head = id_expired;
@ -2243,8 +2267,12 @@ static inline uint32_t ticker_job_op_start(struct ticker_instance *instance,
}
ticker_mark_expire_info_outdated(instance, user_op->id);
#endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
#endif /* CONFIG_BT_TICKER_EXT */
#else /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
ARG_UNUSED(instance);
#endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
#else /* !CONFIG_BT_TICKER_EXT */
ARG_UNUSED(instance);
#endif /* !CONFIG_BT_TICKER_EXT */
ticker->ticks_periodic = start->ticks_periodic;
ticker->remainder_periodic = start->remainder_periodic;
@ -2574,7 +2602,7 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance,
return rescheduled;
}
#endif /* CONFIG_BT_TICKER_EXT && !CONFIG_BT_TICKER_SLOT_AGNOSTIC */
#else /* !CONFIG_BT_TICKER_LOW_LAT */
#else /* CONFIG_BT_TICKER_LOW_LAT */
/**
* @brief Insert new ticker node
@ -2687,7 +2715,7 @@ static inline uint8_t ticker_job_insert(struct ticker_instance *instance,
return TICKER_STATUS_SUCCESS;
}
#endif /* !CONFIG_BT_TICKER_LOW_LAT */
#endif /* CONFIG_BT_TICKER_LOW_LAT */
/**
* @brief Insert and start ticker nodes for all users
@ -2988,10 +3016,8 @@ ticker_job_compare_update(struct ticker_instance *instance,
ticks_to_expire = ticker->ticks_to_expire;
/* If ticks_to_expire is zero, then immediately trigger the worker.
* Under BT_TICKER_LOW_LAT, mesh loopback test fails pending
* investigation hence immediate trigger not used for BT_TICKER_LOW_LAT.
*/
if (!IS_ENABLED(CONFIG_BT_TICKER_LOW_LAT) && !ticks_to_expire) {
if (!ticks_to_expire) {
return 1U;
}
@ -3011,12 +3037,7 @@ ticker_job_compare_update(struct ticker_instance *instance,
cc = instance->ticks_current;
ticks_diff = ticker_ticks_diff_get(ctr_curr, cc);
/* Under BT_TICKER_LOW_LAT, bsim test fails, pending
* investigation immediate trigger not used for
* BT_TICKER_LOW_LAT.
*/
if (!IS_ENABLED(CONFIG_BT_TICKER_LOW_LAT) &&
(ticks_diff >= ticks_to_expire)) {
if (ticks_diff >= ticks_to_expire) {
return 1U;
}
@ -3157,9 +3178,14 @@ void ticker_job(void *param)
/* Handle inquiries */
ticker_job_list_inquire(instance);
}
#endif /* CONFIG_BT_TICKER_JOB_IDLE_GET ||
* CONFIG_BT_TICKER_NEXT_SLOT_GET ||
* CONFIG_BT_TICKER_PRIORITY_SET
#else /* !CONFIG_BT_TICKER_JOB_IDLE_GET &&
* !CONFIG_BT_TICKER_NEXT_SLOT_GET &&
* !CONFIG_BT_TICKER_PRIORITY_SET
*/
ARG_UNUSED(pending);
#endif /* !CONFIG_BT_TICKER_JOB_IDLE_GET &&
* !CONFIG_BT_TICKER_NEXT_SLOT_GET &&
* !CONFIG_BT_TICKER_PRIORITY_SET
*/
#if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
@ -3466,6 +3492,8 @@ uint8_t ticker_start_us(uint8_t instance_index, uint8_t user_id,
user_op->params.start.ticks_first = ticks_first;
#if defined(CONFIG_BT_TICKER_REMAINDER)
user_op->params.start.remainder_first = remainder_first;
#else /* !CONFIG_BT_TICKER_REMAINDER */
ARG_UNUSED(remainder_first);
#endif /* !CONFIG_BT_TICKER_REMAINDER */
user_op->params.start.ticks_periodic = ticks_periodic;
user_op->params.start.remainder_periodic = remainder_periodic;