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.
This commit is contained in:
Damien George 2020-02-06 01:05:47 +11:00
parent 7a5752a748
commit 98a3911c43
11 changed files with 30 additions and 26 deletions

View File

@ -162,7 +162,7 @@ NORETURN static void exception_from_errno(int _errno) {
} }
static inline void check_for_exceptions(void) { 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 // This function mimics lwip_getaddrinfo, with added support for mDNS queries

View File

@ -244,8 +244,8 @@ void *esp_native_code_commit(void*, size_t, void*);
#if MICROPY_PY_THREAD #if MICROPY_PY_THREAD
#define MICROPY_EVENT_POLL_HOOK \ #define MICROPY_EVENT_POLL_HOOK \
do { \ do { \
extern void mp_handle_pending(void); \ extern void mp_handle_pending(bool); \
mp_handle_pending(); \ mp_handle_pending(true); \
MICROPY_PY_USOCKET_EVENTS_HANDLER \ MICROPY_PY_USOCKET_EVENTS_HANDLER \
MP_THREAD_GIL_EXIT(); \ MP_THREAD_GIL_EXIT(); \
MP_THREAD_GIL_ENTER(); \ MP_THREAD_GIL_ENTER(); \
@ -253,8 +253,8 @@ void *esp_native_code_commit(void*, size_t, void*);
#else #else
#define MICROPY_EVENT_POLL_HOOK \ #define MICROPY_EVENT_POLL_HOOK \
do { \ do { \
extern void mp_handle_pending(void); \ extern void mp_handle_pending(bool); \
mp_handle_pending(); \ mp_handle_pending(true); \
MICROPY_PY_USOCKET_EVENTS_HANDLER \ MICROPY_PY_USOCKET_EVENTS_HANDLER \
asm("waiti 0"); \ asm("waiti 0"); \
} while (0); } while (0);

View File

@ -157,7 +157,7 @@ void mp_hal_delay_us(uint32_t us) {
if (dt + pend_overhead < us) { if (dt + pend_overhead < us) {
// we have enough time to service pending events // we have enough time to service pending events
// (don't use MICROPY_EVENT_POLL_HOOK because it also yields) // (don't use MICROPY_EVENT_POLL_HOOK because it also yields)
mp_handle_pending(); mp_handle_pending(true);
} }
} }
} }

View File

@ -144,7 +144,7 @@ void mp_hal_delay_ms(uint32_t delay) {
void ets_event_poll(void) { void ets_event_poll(void) {
ets_loop_iter(); ets_loop_iter();
mp_handle_pending(); mp_handle_pending(true);
} }
void __assert_func(const char *file, int line, const char *func, const char *expr) { void __assert_func(const char *file, int line, const char *func, const char *expr) {

View File

@ -135,8 +135,8 @@ extern const struct _mp_obj_module_t mp_module_utime;
#if MICROPY_PY_THREAD #if MICROPY_PY_THREAD
#define MICROPY_EVENT_POLL_HOOK \ #define MICROPY_EVENT_POLL_HOOK \
do { \ do { \
extern void mp_handle_pending(void); \ extern void mp_handle_pending(bool); \
mp_handle_pending(); \ mp_handle_pending(true); \
if (pyb_thread_enabled) { \ if (pyb_thread_enabled) { \
MP_THREAD_GIL_EXIT(); \ MP_THREAD_GIL_EXIT(); \
pyb_thread_yield(); \ pyb_thread_yield(); \
@ -149,8 +149,8 @@ extern const struct _mp_obj_module_t mp_module_utime;
#else #else
#define MICROPY_EVENT_POLL_HOOK \ #define MICROPY_EVENT_POLL_HOOK \
do { \ do { \
extern void mp_handle_pending(void); \ extern void mp_handle_pending(bool); \
mp_handle_pending(); \ mp_handle_pending(true); \
} while (0); } while (0);
#define MICROPY_THREAD_YIELD() #define MICROPY_THREAD_YIELD()

View File

@ -92,8 +92,8 @@ extern const struct _mp_obj_module_t mp_module_utime;
#define MICROPY_EVENT_POLL_HOOK \ #define MICROPY_EVENT_POLL_HOOK \
do { \ do { \
extern void mp_handle_pending(void); \ extern void mp_handle_pending(bool); \
mp_handle_pending(); \ mp_handle_pending(true); \
__WFI(); \ __WFI(); \
} while (0); } while (0);

View File

@ -343,8 +343,8 @@ static inline mp_uint_t disable_irq(void) {
#if MICROPY_PY_THREAD #if MICROPY_PY_THREAD
#define MICROPY_EVENT_POLL_HOOK \ #define MICROPY_EVENT_POLL_HOOK \
do { \ do { \
extern void mp_handle_pending(void); \ extern void mp_handle_pending(bool); \
mp_handle_pending(); \ mp_handle_pending(true); \
if (pyb_thread_enabled) { \ if (pyb_thread_enabled) { \
MP_THREAD_GIL_EXIT(); \ MP_THREAD_GIL_EXIT(); \
pyb_thread_yield(); \ pyb_thread_yield(); \
@ -358,8 +358,8 @@ static inline mp_uint_t disable_irq(void) {
#else #else
#define MICROPY_EVENT_POLL_HOOK \ #define MICROPY_EVENT_POLL_HOOK \
do { \ do { \
extern void mp_handle_pending(void); \ extern void mp_handle_pending(bool); \
mp_handle_pending(); \ mp_handle_pending(true); \
__WFI(); \ __WFI(); \
} while (0); } while (0);

View File

@ -466,7 +466,7 @@ STATIC mp_obj_t extra_coverage(void) {
mp_sched_unlock(); mp_sched_unlock();
// shouldn't do anything while scheduler is locked // shouldn't do anything while scheduler is locked
mp_handle_pending(); mp_handle_pending(true);
// unlock scheduler // unlock scheduler
mp_sched_unlock(); mp_sched_unlock();
@ -474,7 +474,7 @@ STATIC mp_obj_t extra_coverage(void) {
// drain pending callbacks // drain pending callbacks
while (mp_sched_num_pending()) { while (mp_sched_num_pending()) {
mp_handle_pending(); mp_handle_pending(true);
} }
} }

View File

@ -109,7 +109,7 @@ STATIC mp_obj_t mod_time_sleep(mp_obj_t arg) {
if (res != -1 || errno != EINTR) { if (res != -1 || errno != EINTR) {
break; break;
} }
mp_handle_pending(); mp_handle_pending(true);
//printf("select: EINTR: %ld:%ld\n", tv.tv_sec, tv.tv_usec); //printf("select: EINTR: %ld:%ld\n", tv.tv_sec, tv.tv_usec);
#else #else
break; break;

View File

@ -64,7 +64,7 @@ extern const byte mp_binary_op_method_name[];
void mp_init(void); void mp_init(void);
void mp_deinit(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); void mp_handle_pending_tail(mp_uint_t atomic_state);
#if MICROPY_ENABLE_SCHEDULER #if MICROPY_ENABLE_SCHEDULER

View File

@ -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 // 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) { if (MP_STATE_VM(sched_state) == MP_SCHED_PENDING) {
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
mp_obj_t obj = MP_STATE_VM(mp_pending_exception); mp_obj_t obj = MP_STATE_VM(mp_pending_exception);
@ -53,8 +53,10 @@ void mp_handle_pending(void) {
if (!mp_sched_num_pending()) { if (!mp_sched_num_pending()) {
MP_STATE_VM(sched_state) = MP_SCHED_IDLE; MP_STATE_VM(sched_state) = MP_SCHED_IDLE;
} }
MICROPY_END_ATOMIC_SECTION(atomic_state); if (raise_exc) {
nlr_raise(obj); MICROPY_END_ATOMIC_SECTION(atomic_state);
nlr_raise(obj);
}
} }
mp_handle_pending_tail(atomic_state); 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 #else // MICROPY_ENABLE_SCHEDULER
// A variant of this is inlined in the VM at the pending exception check // 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) { if (MP_STATE_VM(mp_pending_exception) != MP_OBJ_NULL) {
mp_obj_t obj = MP_STATE_VM(mp_pending_exception); mp_obj_t obj = MP_STATE_VM(mp_pending_exception);
MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
nlr_raise(obj); if (raise_exc) {
nlr_raise(obj);
}
} }
} }