under-the-hood:
ABI/API compatibility wise, we are actually mostly fine, since we can convert the monotonic-clock struct timespec to a struct timeval internally, but.
- API: osmo_timer_remaining() optionally takes a 'now' argument, where the user can feed the current time.
The only place we use osmo_timer_remaining() in Osmocom projects seems to be the fsm: a CTRL command returns the remaining time. There we pass now=NULL.
I would add osmo_timer_remaining2() without the option to pass 'now' and deprecate osmo_timer_remaining().
- ABI: obviously whoever passes gettimeofday() to osmo_timer_remaining(now) would then get wildly chaotic remaining times.
- ABI: manually accessing/comparing osmo_timer_list.timeout no longer works.
The implementation could
- change the old timeval in struct osmo_timer_list to struct timespec (API change that shouldn't affect "proper" API users)
- or keep the old timeval and add a timespec to the end
- Or, internally use osmo_clock_gettime() and divide ts_nsec by 1000 to get tv_usec (and if ts_nsec % 1000, tv_usec++ to remain consistent), still using struct timeval to store and compare.
new API:
Another proposal would be to go all the way: add a completely new osmo_timer_monotonic_* API, including a second list traversal in osmo_timers_{prepare,update,check}(). That would be a bit more work, but ensures full compat, and requires moving all callers to the new API (which could be a good thing).
pro/con:
- in practice, we can move all users to monotonic under the hood with minimal effort, IF we don't give a moist one about users of osmo_timer_remaining(now!=NULL) and accept minimal ABI changes.
- if we also accept API changes that should not practically affect anyone (TM), we can change the current API to struct timespec with nsec precision to avoid dividing by 1000.
- full compat would require a full set of new API, and moving all callers individually (basically just because the current structs are not opaque enough).
I would personally choose the middle one, and accept the slight API/ABI dirtyness, and skip changing all callers manually.
If anyone votes against it (a la, we should not stump unknown users), I am very close to accepting that as well and write up a new API from scratch. It would be rather quick to achieve, basically a copy of the current one with timeval replaced by timespec and gettimeofday replaced by osmo_clock_gettime().