Skip to content
This repository has been archived by the owner on Sep 16, 2024. It is now read-only.

utime: ticks_diff() raises an exception with large values returned by ticks_us() or ticks_ms() #113

Closed
robert-hh opened this issue Dec 25, 2017 · 4 comments

Comments

@robert-hh
Copy link
Contributor

robert-hh commented Dec 25, 2017

The functions utime.ticks_us() and utime.ticks_ms() may return values, which then cannot be used as input for utime.ticks_diff(). Example:

>>> time.ticks_us()
3636776263
>>> time.ticks_diff(time.ticks_us(), time.ticks_us()+1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: overflow converting long int to machine word
>>> 

The reason is, that the return values are not stripped to values which can be representef by a MP_SMALL_INT, or at least 31 bit.
Edit: Funny enough, the utime module is mostly implemented twice, in esp32/mods/modutime.c and in py/extmod/mphal_utime.c, where the latter seems to have proper value/overflow handling.

@robert-hh
Copy link
Contributor Author

Made a PR attemting to fix that issue.

@robert-hh robert-hh changed the title utime: Inconsistency in value ranges utime: ticks_diff() raises an exception with large values returned by ticks_us() or ticks_ms() Jan 3, 2018
@robert-hh
Copy link
Contributor Author

This simple script will trigger an exception latest after about 35 minutes.

import utime

new = utime.ticks_us()
while True:
    utime.sleep(1)
    old = new
    new = utime.ticks_us()
    print(new, utime.ticks_diff(old,new))

@robert-hh
Copy link
Contributor Author

Actually the minimal change to fix that is to modify ticks_diff() as:

STATIC mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) {
    int32_t start = mp_obj_get_int_truncated(start_in);
    int32_t end = mp_obj_get_int_truncated(end_in);
    return mp_obj_new_int((end - start));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff);

This change will also return a reasonable behavior, if the arguments of the call are swapped - sign change. The only deviating result is achieved with ticks_diff(0x80000000, 0), and ticks_diff(0, 0x8000000), which return the same value -2147483648

@robert-hh
Copy link
Contributor Author

Thanks for merging.

peter-pycom pushed a commit that referenced this issue May 4, 2020
X-Ryl669 pushed a commit to X-Ryl669/pycom-micropython-sigfox that referenced this issue May 12, 2023
This fixes ensure, that the return values of ticks_ms(), ticks_us() and ticks_cpu() fit into a MP_SMALL_INT. That way, they can be fed into ticks_diff() without the risk of an OverflowError (see issue pycom#113). As a side effect, the result of ticks_diff(a, b) is always defined as a reasonable value even if a is a time after b (a > b). In that case, the value is negative. The implementation just copies the mechanism from py/extmod/mphal_utime.c.
Second change: Add the method ticks_add().
X-Ryl669 pushed a commit to X-Ryl669/pycom-micropython-sigfox that referenced this issue May 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant