Skip to content

Commit

Permalink
nimble/ll: Improve scheduling of 1st BIG event
Browse files Browse the repository at this point in the history
This improves BIG scheduling in case periodic advertising interval is
an integer multiple of ISO interval. In such case placing BIG event
directly before periodic advertising event makes sure both won't overlap
even if periodic advertising data changes in future.

Note that there may still be conflicts with other instances and this
patch doesn't resolve that.
  • Loading branch information
andrzej-kaczmarek committed Oct 6, 2023
1 parent b0951c7 commit 312b92a
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 14 deletions.
2 changes: 1 addition & 1 deletion nimble/controller/include/controller/ble_ll_sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ uint32_t ble_ll_sched_css_get_conn_interval_us(void);
#endif

#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
int ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first);
int ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first, int fixed);
#endif /* BLE_LL_ISO_BROADCASTER */

#ifdef __cplusplus
Expand Down
32 changes: 21 additions & 11 deletions nimble/controller/src/ble_ll_iso_big.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big)
}

/* XXX this should always succeed since we preempt anything for now */
rc = ble_ll_sched_iso_big(&big->sch, 0);
rc = ble_ll_sched_iso_big(&big->sch, 0, 0);
assert(rc == 0);
} while (rc < 0);

Expand Down Expand Up @@ -1029,26 +1029,36 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
* not enough for some phys to run scheduler item.
*/

/* XXX schedule BIG just after periodic advertising; this is temporary hack
* to avoid collision as commonly both have intervals that are multiple
* of 10ms...
*/
uint32_t start_time, end_time, big_time;
uint32_t sync_delay_ticks = ble_ll_tmr_u2t_up(big->sync_delay);
uint32_t iso_interval_ticks = ble_ll_tmr_u2t_up(big->iso_interval * 1250);
int big_event_fixed;

rc = ble_ll_adv_sync_sched_get(big->advsm, &start_time, &end_time);
if (rc) {
big_time = ble_ll_tmr_get() + ble_ll_tmr_u2t(5000);
/* Set 1st BIG one interval after "now", this ensures it's always
* scheduled in the future.
*/
big_time = ble_ll_tmr_get() + iso_interval_ticks;
big_event_fixed = 0;
} else {
big_time = end_time + 25;
/* Set 1st BIG event directly before periodic advertising event, this
* way it will not overlap it even if periodic advertising data changes.
* Make sure it's in the future.
*/
big_time = start_time - g_ble_ll_sched_offset_ticks - sync_delay_ticks - 1;
while (big_time - g_ble_ll_sched_offset_ticks < ble_ll_tmr_get()) {
big_time += iso_interval_ticks;
}
big_event_fixed = 1;
}

/* Schedule 1st event a bit in future */
big->sch.start_time = big_time;
big->sch.remainder = 0;
big->sch.end_time = big->sch.start_time +
ble_ll_tmr_u2t_up(big->sync_delay) + 1;
big->sch.end_time = big->sch.start_time + sync_delay_ticks + 1;
big->sch.start_time -= g_ble_ll_sched_offset_ticks;

rc = ble_ll_sched_iso_big(&big->sch, 1);
rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed);
if (rc < 0) {
ble_ll_iso_big_free(big);
return -EFAULT;
Expand Down
4 changes: 2 additions & 2 deletions nimble/controller/src/ble_ll_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -838,14 +838,14 @@ ble_ll_sched_adv_resched_pdu(struct ble_ll_sched_item *sch)

#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
int
ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first)
ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first, int fixed)
{
os_sr_t sr;
int rc;

OS_ENTER_CRITICAL(sr);

if (first) {
if (first && !fixed) {
rc = ble_ll_sched_insert(sch, BLE_LL_SCHED_MAX_DELAY_ANY, preempt_none);
} else {
/* XXX provide better strategy for preemption */
Expand Down

0 comments on commit 312b92a

Please sign in to comment.