From 98a3911c430b0cc96e1821d7ca589b9be3355fc3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 Feb 2020 01:05:47 +1100 Subject: [PATCH] py/scheduler: Add "raise_exc" argument to mp_handle_pending. Previous behaviour is when this argument is set to "true", in which case the function will raise any pending exception. Setting it to "false" will cancel any pending exception. --- ports/esp32/modsocket.c | 2 +- ports/esp32/mpconfigport.h | 8 ++++---- ports/esp32/mphalport.c | 2 +- ports/esp8266/esp_mphal.c | 2 +- ports/javascript/mpconfigport.h | 8 ++++---- ports/samd/mpconfigport.h | 4 ++-- ports/stm32/mpconfigport.h | 8 ++++---- ports/unix/coverage.c | 4 ++-- ports/unix/modtime.c | 2 +- py/runtime.h | 2 +- py/scheduler.c | 14 +++++++++----- 11 files changed, 30 insertions(+), 26 deletions(-) diff --git a/ports/esp32/modsocket.c b/ports/esp32/modsocket.c index e11af60e2..60a028c13 100644 --- a/ports/esp32/modsocket.c +++ b/ports/esp32/modsocket.c @@ -162,7 +162,7 @@ NORETURN static void exception_from_errno(int _errno) { } static inline void check_for_exceptions(void) { - mp_handle_pending(); + mp_handle_pending(true); } // This function mimics lwip_getaddrinfo, with added support for mDNS queries diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 983c882ae..96e47fbba 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -244,8 +244,8 @@ void *esp_native_code_commit(void*, size_t, void*); #if MICROPY_PY_THREAD #define MICROPY_EVENT_POLL_HOOK \ do { \ - extern void mp_handle_pending(void); \ - mp_handle_pending(); \ + extern void mp_handle_pending(bool); \ + mp_handle_pending(true); \ MICROPY_PY_USOCKET_EVENTS_HANDLER \ MP_THREAD_GIL_EXIT(); \ MP_THREAD_GIL_ENTER(); \ @@ -253,8 +253,8 @@ void *esp_native_code_commit(void*, size_t, void*); #else #define MICROPY_EVENT_POLL_HOOK \ do { \ - extern void mp_handle_pending(void); \ - mp_handle_pending(); \ + extern void mp_handle_pending(bool); \ + mp_handle_pending(true); \ MICROPY_PY_USOCKET_EVENTS_HANDLER \ asm("waiti 0"); \ } while (0); diff --git a/ports/esp32/mphalport.c b/ports/esp32/mphalport.c index 305e87593..c701cb4bc 100644 --- a/ports/esp32/mphalport.c +++ b/ports/esp32/mphalport.c @@ -157,7 +157,7 @@ void mp_hal_delay_us(uint32_t us) { if (dt + pend_overhead < us) { // we have enough time to service pending events // (don't use MICROPY_EVENT_POLL_HOOK because it also yields) - mp_handle_pending(); + mp_handle_pending(true); } } } diff --git a/ports/esp8266/esp_mphal.c b/ports/esp8266/esp_mphal.c index 25201425b..d840cf040 100644 --- a/ports/esp8266/esp_mphal.c +++ b/ports/esp8266/esp_mphal.c @@ -144,7 +144,7 @@ void mp_hal_delay_ms(uint32_t delay) { void ets_event_poll(void) { ets_loop_iter(); - mp_handle_pending(); + mp_handle_pending(true); } void __assert_func(const char *file, int line, const char *func, const char *expr) { diff --git a/ports/javascript/mpconfigport.h b/ports/javascript/mpconfigport.h index 8ea43d84c..bc4e05343 100644 --- a/ports/javascript/mpconfigport.h +++ b/ports/javascript/mpconfigport.h @@ -135,8 +135,8 @@ extern const struct _mp_obj_module_t mp_module_utime; #if MICROPY_PY_THREAD #define MICROPY_EVENT_POLL_HOOK \ do { \ - extern void mp_handle_pending(void); \ - mp_handle_pending(); \ + extern void mp_handle_pending(bool); \ + mp_handle_pending(true); \ if (pyb_thread_enabled) { \ MP_THREAD_GIL_EXIT(); \ pyb_thread_yield(); \ @@ -149,8 +149,8 @@ extern const struct _mp_obj_module_t mp_module_utime; #else #define MICROPY_EVENT_POLL_HOOK \ do { \ - extern void mp_handle_pending(void); \ - mp_handle_pending(); \ + extern void mp_handle_pending(bool); \ + mp_handle_pending(true); \ } while (0); #define MICROPY_THREAD_YIELD() diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 5b81d96b3..d77b9d56b 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -92,8 +92,8 @@ extern const struct _mp_obj_module_t mp_module_utime; #define MICROPY_EVENT_POLL_HOOK \ do { \ - extern void mp_handle_pending(void); \ - mp_handle_pending(); \ + extern void mp_handle_pending(bool); \ + mp_handle_pending(true); \ __WFI(); \ } while (0); diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 2e4fc0406..90e387554 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -343,8 +343,8 @@ static inline mp_uint_t disable_irq(void) { #if MICROPY_PY_THREAD #define MICROPY_EVENT_POLL_HOOK \ do { \ - extern void mp_handle_pending(void); \ - mp_handle_pending(); \ + extern void mp_handle_pending(bool); \ + mp_handle_pending(true); \ if (pyb_thread_enabled) { \ MP_THREAD_GIL_EXIT(); \ pyb_thread_yield(); \ @@ -358,8 +358,8 @@ static inline mp_uint_t disable_irq(void) { #else #define MICROPY_EVENT_POLL_HOOK \ do { \ - extern void mp_handle_pending(void); \ - mp_handle_pending(); \ + extern void mp_handle_pending(bool); \ + mp_handle_pending(true); \ __WFI(); \ } while (0); diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index 1b6132cdd..0703d0a33 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -466,7 +466,7 @@ STATIC mp_obj_t extra_coverage(void) { mp_sched_unlock(); // shouldn't do anything while scheduler is locked - mp_handle_pending(); + mp_handle_pending(true); // unlock scheduler mp_sched_unlock(); @@ -474,7 +474,7 @@ STATIC mp_obj_t extra_coverage(void) { // drain pending callbacks while (mp_sched_num_pending()) { - mp_handle_pending(); + mp_handle_pending(true); } } diff --git a/ports/unix/modtime.c b/ports/unix/modtime.c index 479d2a79d..4ea8cb62c 100644 --- a/ports/unix/modtime.c +++ b/ports/unix/modtime.c @@ -109,7 +109,7 @@ STATIC mp_obj_t mod_time_sleep(mp_obj_t arg) { if (res != -1 || errno != EINTR) { break; } - mp_handle_pending(); + mp_handle_pending(true); //printf("select: EINTR: %ld:%ld\n", tv.tv_sec, tv.tv_usec); #else break; diff --git a/py/runtime.h b/py/runtime.h index b54b17b68..1c078ae81 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -64,7 +64,7 @@ extern const byte mp_binary_op_method_name[]; void mp_init(void); void mp_deinit(void); -void mp_handle_pending(void); +void mp_handle_pending(bool raise_exc); void mp_handle_pending_tail(mp_uint_t atomic_state); #if MICROPY_ENABLE_SCHEDULER diff --git a/py/scheduler.c b/py/scheduler.c index e7cbb524d..ff88be958 100644 --- a/py/scheduler.c +++ b/py/scheduler.c @@ -44,7 +44,7 @@ static inline bool mp_sched_empty(void) { } // A variant of this is inlined in the VM at the pending exception check -void mp_handle_pending(void) { +void mp_handle_pending(bool raise_exc) { if (MP_STATE_VM(sched_state) == MP_SCHED_PENDING) { mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); mp_obj_t obj = MP_STATE_VM(mp_pending_exception); @@ -53,8 +53,10 @@ void mp_handle_pending(void) { if (!mp_sched_num_pending()) { MP_STATE_VM(sched_state) = MP_SCHED_IDLE; } - MICROPY_END_ATOMIC_SECTION(atomic_state); - nlr_raise(obj); + if (raise_exc) { + MICROPY_END_ATOMIC_SECTION(atomic_state); + nlr_raise(obj); + } } mp_handle_pending_tail(atomic_state); } @@ -121,11 +123,13 @@ bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg) { #else // MICROPY_ENABLE_SCHEDULER // A variant of this is inlined in the VM at the pending exception check -void mp_handle_pending(void) { +void mp_handle_pending(bool raise_exc) { if (MP_STATE_VM(mp_pending_exception) != MP_OBJ_NULL) { mp_obj_t obj = MP_STATE_VM(mp_pending_exception); MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; - nlr_raise(obj); + if (raise_exc) { + nlr_raise(obj); + } } } -- GitLab