diff options
author | Damien George <damien.p.george@gmail.com> | 2017-02-06 10:50:43 +1100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2017-02-15 11:28:15 +1100 |
commit | f6c22a06797735e4a65a91491d8373ba951a798b (patch) | |
tree | 3f36bbb80ccbc5c73d8ce0dd4e086738e68fccd9 /py | |
parent | 234f07f16cc845128658cc0b39ac681cae5a8fba (diff) | |
download | micropython-f6c22a06797735e4a65a91491d8373ba951a798b.tar.gz micropython-f6c22a06797735e4a65a91491d8373ba951a798b.zip |
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.
Diffstat (limited to 'py')
-rw-r--r-- | py/mpconfig.h | 6 | ||||
-rw-r--r-- | py/vm.c | 20 |
2 files changed, 23 insertions, 3 deletions
diff --git a/py/mpconfig.h b/py/mpconfig.h index 093625a461..1b47d822f1 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -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 @@ -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 |