[PATCH 2/2] cyclic: parse cyclic list only if next cyclic timestamp is reached

Patrice CHOTARD patrice.chotard at foss.st.com
Mon Jul 6 17:16:24 CEST 2026



On 7/3/26 16:38, Marek Vasut wrote:
> On 7/3/26 11:55 AM, Patrice CHOTARD wrote:
> 
> Hello Patrice,
> 
>>>>    +    /* check if the next cyclic function's timestamp is reached */
>>>> +    now = get_timer_us(0);
>>>> +    if (time_after_eq64(gd->next_cyclic_call, now))
>>>> +        return;
>>>> +
>>>>        gd->flags |= GD_FLG_CYCLIC_RUNNING;
>>>>        hlist_for_each_entry_safe(cyclic, tmp, cyclic_get_list(), list) {
>>>>            /*
>>>> @@ -102,7 +108,13 @@ static void cyclic_run(void)
>>>>                    cyclic->already_warned = true;
>>>>                }
>>>>            }
>>>> +        if (next_call > cyclic->next_call)
>>>> +            next_call = cyclic->next_call;
>>>
>>> Can you move this entry to the beginning of the cyclic list, so that the entry with the earliest deadline would be right at the beginning of the list ? That should squeeze some more improvement out of this I think.
>>
>> Hi Marek
>>
>> I did a test, it doesn't bring any noticeable improvements, but nevertheless i will submit a v3 with this update.
> 
> Does the list iteration exit when it finds the first entry that is not going to be executed at this time ? If it does not, then there will be no improvement. But for this to work, the list would have to be surely fully ordered in incrementing timestamp order, is it ?

No, the list iteration parse all entries.

I see your point, on original implementation, entries are not sort by incrementing timestamp order.
I did some implementation test, by sorting cyclic entries in cyclic_list when :
  _ registering a new cyclic callback, put it directly in the right position in cyclic_list.
  _ in cyclic_run(), after running a cyclic, compute its next call and insrt it in the right position in cyclic_list.

There is no noticeable gain.

Thanks
Patrice

> 
>>>
>>>>        }
>>>> +
>>>> +    if (next_call != UINT64_MAX)
>>>
>>> Can the next_call literally hit UINT64_MAX in that one unlikely case ?
>>> You likely do need a separate flag, bool next_call_valid, to avoid that edge case.
>>
>> In case, no cyclic has been registered, we don't parse the cyclic list and next_call stays set to UINT64_MAX
>> We don't want that next_cyclic_call be set to UINT64_MAX, otherwise in that case, we will always exit cyclic_run() before parsing cyclic list.
> Consider this:
> 
> +    u64 next_call = UINT64_MAX;
> ...
>      hlist_for_each_entry_safe(cyclic, tmp, cyclic_get_list(), list) {
> ...
>                 cyclic->next_call = now + cyclic->delay_us; // = ~0ULL
> ...
> +        if (next_call > cyclic->next_call)      // False
> +            next_call = cyclic->next_call;  // Not set
> ...
> +    if (next_call != UINT64_MAX) // False, branch not executed, but it should be executed ?
> +        gd->next_cyclic_call = next_call;
> ...



More information about the U-Boot mailing list