You’re still missing the point, Richard. None of what you raise is relevant to the race at hand. The internal data structures of the timer representation are completly irrelevant.
When the setting of the callback and its invocation “overlap,” the trivial solution is to ensure atomicity. Yet there is still a race condition that may in one scenario change the callback before it is invoked and another one afterwards, ending up in two different callback invocation sequences.
Consider a periodic 500ms callback and another 300ms timer (possibly executing in a different task thus no serialization in the timer task) that toggles the first timer’s callback at every invocation. This leads to a fairly predictable pattern of callbacks invoked every 500ms, right? Except that at time stamps 1500,3000 etc, the callback modification falls at “the same time,” meaning that depending on a number of issues such as task priorization, starvation, ISR load etc, an unpredictable toggle occurrs.
If we want that to happen or not is up to the application, so the application would need to inform the OS how it wants the scenario to be handled. My point is that this mechanism is too error prone to be usefully implementable, also given the fact that there are several ways to implement dynmaic callbacks on the application level. Thus I’d vote against an API which would create a support nightmare just to serve a fringe condition that can much more flexibly be handled on app level.