diff --git a/py/smallint.h b/py/smallint.h index 7bdf405a8b..19b5209ec7 100644 --- a/py/smallint.h +++ b/py/smallint.h @@ -36,11 +36,15 @@ #define MP_SMALL_INT_MIN ((mp_int_t)(((mp_int_t)WORD_MSBIT_HIGH) >> 1)) #define MP_SMALL_INT_FITS(n) ((((n) ^ ((n) << 1)) & WORD_MSBIT_HIGH) == 0) +// Mask to truncate mp_int_t to positive value +#define MP_SMALL_INT_POSITIVE_MASK ~(WORD_MSBIT_HIGH | (WORD_MSBIT_HIGH >> 1)) #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B #define MP_SMALL_INT_MIN ((mp_int_t)(((mp_int_t)WORD_MSBIT_HIGH) >> 2)) #define MP_SMALL_INT_FITS(n) ((((n) & MP_SMALL_INT_MIN) == 0) || (((n) & MP_SMALL_INT_MIN) == MP_SMALL_INT_MIN)) +// Mask to truncate mp_int_t to positive value +#define MP_SMALL_INT_POSITIVE_MASK ~(WORD_MSBIT_HIGH | (WORD_MSBIT_HIGH >> 1) | (WORD_MSBIT_HIGH >> 2)) #endif diff --git a/unix/modtime.c b/unix/modtime.c index f933c4313e..4a15f1a392 100644 --- a/unix/modtime.c +++ b/unix/modtime.c @@ -31,6 +31,7 @@ #include #include "py/runtime.h" +#include "py/smallint.h" #ifdef _WIN32 void msec_sleep_tv(struct timeval *tv) { @@ -69,6 +70,29 @@ STATIC mp_obj_t mod_time_time(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_time_obj, mod_time_time); +STATIC mp_obj_t mod_time_ticks_us(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + mp_uint_t us = tv.tv_sec * 1000000 + tv.tv_usec; + return MP_OBJ_NEW_SMALL_INT(us & MP_SMALL_INT_POSITIVE_MASK); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_ticks_us_obj, mod_time_ticks_us); + +STATIC mp_obj_t mod_time_ticks_ms(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + mp_uint_t ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; + return MP_OBJ_NEW_SMALL_INT(ms & MP_SMALL_INT_POSITIVE_MASK); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_ticks_ms_obj, mod_time_ticks_ms); + +STATIC mp_obj_t mod_time_ticks_diff(mp_obj_t oldval, mp_obj_t newval) { + mp_uint_t old = MP_OBJ_SMALL_INT_VALUE(oldval); + mp_uint_t new = MP_OBJ_SMALL_INT_VALUE(newval); + return MP_OBJ_NEW_SMALL_INT((new - old) & MP_SMALL_INT_POSITIVE_MASK); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_time_ticks_diff_obj, mod_time_ticks_diff); + // Note: this is deprecated since CPy3.3, but pystone still uses it. STATIC mp_obj_t mod_time_clock(void) { #if MICROPY_PY_BUILTINS_FLOAT @@ -116,6 +140,9 @@ STATIC const mp_map_elem_t mp_module_time_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&mod_time_sleep_ms_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&mod_time_sleep_us_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&mod_time_time_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&mod_time_ticks_ms_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&mod_time_ticks_us_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&mod_time_ticks_diff_obj }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_time_globals, mp_module_time_globals_table); diff --git a/unix/qstrdefsport.h b/unix/qstrdefsport.h index 5cc822f72d..013d198ad4 100644 --- a/unix/qstrdefsport.h +++ b/unix/qstrdefsport.h @@ -62,6 +62,9 @@ Q(clock) Q(sleep) Q(sleep_ms) Q(sleep_us) +Q(ticks_ms) +Q(ticks_us) +Q(ticks_diff) Q(socket) Q(sockaddr_in)