py/vm: Add MICROPY_PY_THREAD_GIL_VM_DIVISOR option.

This improves efficiency of GIL release within the VM, by only doing the
release after a fixed number of jump-opcodes have executed in the current
thread.
pull/1/head
Damien George 2017-02-06 10:50:43 +11:00
parent 234f07f16c
commit f6c22a0679
2 changed files with 23 additions and 3 deletions

View File

@ -949,6 +949,12 @@ typedef double mp_float_t;
#define MICROPY_PY_THREAD_GIL (MICROPY_PY_THREAD)
#endif
// Number of VM jump-loops to do before releasing the GIL.
// Set this to 0 to disable the divisor.
#ifndef MICROPY_PY_THREAD_GIL_VM_DIVISOR
#define MICROPY_PY_THREAD_GIL_VM_DIVISOR (32)
#endif
// Extended modules
#ifndef MICROPY_PY_UCTYPES

20
py/vm.c
View File

@ -169,6 +169,12 @@ run_code_state: ;
volatile bool currently_in_except_block = MP_TAGPTR_TAG0(code_state->exc_sp); // 0 or 1, to detect nested exceptions
mp_exc_stack_t *volatile exc_sp = MP_TAGPTR_PTR(code_state->exc_sp); // stack grows up, exc_sp points to top of stack
#if MICROPY_PY_THREAD_GIL && MICROPY_PY_THREAD_GIL_VM_DIVISOR
// This needs to be volatile and outside the VM loop so it persists across handling
// of any exceptions. Otherwise it's possible that the VM never gives up the GIL.
volatile int gil_divisor = MICROPY_PY_THREAD_GIL_VM_DIVISOR;
#endif
// outer exception handling loop
for (;;) {
nlr_buf_t nlr;
@ -1243,9 +1249,17 @@ pending_exception_check:
RAISE(obj);
}
// TODO make GIL release more efficient
MP_THREAD_GIL_EXIT();
MP_THREAD_GIL_ENTER();
#if MICROPY_PY_THREAD_GIL
#if MICROPY_PY_THREAD_GIL_VM_DIVISOR
if (--gil_divisor == 0) {
gil_divisor = MICROPY_PY_THREAD_GIL_VM_DIVISOR;
#else
{
#endif
MP_THREAD_GIL_EXIT();
MP_THREAD_GIL_ENTER();
}
#endif
} // for loop