diff options
author | David Lechner <david@pybricks.com> | 2020-01-22 18:14:03 -0600 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2020-01-26 23:21:29 +1100 |
commit | fee7e5617f55b4778de74ee185fcc3950cdc7b6d (patch) | |
tree | 9a1fec68969ee8e27e74a5e92761ae1a194580bb /ports/unix/modos.c | |
parent | 96716b46e1c4945d3fe08d9ba91920ca28f9c986 (diff) | |
download | micropython-fee7e5617f55b4778de74ee185fcc3950cdc7b6d.tar.gz micropython-fee7e5617f55b4778de74ee185fcc3950cdc7b6d.zip |
unix: Release GIL during all system calls.
Addition of GIL EXIT/ENTER pairs are:
- modos: release the GIL during system calls. CPython does this as well.
- moduselect: release the GIL during the poll() syscall. This call can be
blocking, so it is important to allow other threads to run at this time.
- modusocket: release the GIL during system calls. Many of these calls can
be blocking, so it is important to allow other threads to run.
- unix_mphal: release the GIL during the read and write syscalls in
mp_hal_stdin_rx_chr and mp_hal_stdout_tx_strn. If we don't do this
threads are blocked when the REPL or the builtin input function are used.
- file, main, mpconfigport.h: release GIL during syscalls in built-in
functions that could block.
Diffstat (limited to 'ports/unix/modos.c')
-rw-r--r-- | ports/unix/modos.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/ports/unix/modos.c b/ports/unix/modos.c index c3b0c20b2b..e5bd5da1eb 100644 --- a/ports/unix/modos.c +++ b/ports/unix/modos.c @@ -38,6 +38,7 @@ #include "py/runtime.h" #include "py/objtuple.h" #include "py/mphal.h" +#include "py/mpthread.h" #include "extmod/vfs.h" #include "extmod/misc.h" @@ -49,7 +50,9 @@ STATIC mp_obj_t mod_os_stat(mp_obj_t path_in) { struct stat sb; const char *path = mp_obj_str_get_str(path_in); + MP_THREAD_GIL_EXIT(); int res = stat(path, &sb); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(res, errno); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); @@ -89,7 +92,9 @@ STATIC mp_obj_t mod_os_statvfs(mp_obj_t path_in) { STRUCT_STATVFS sb; const char *path = mp_obj_str_get_str(path_in); + MP_THREAD_GIL_EXIT(); int res = STATVFS(path, &sb); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(res, errno); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); @@ -116,7 +121,9 @@ STATIC mp_obj_t mod_os_remove(mp_obj_t path_in) { // of that function. But Python remove() follows ANSI C, and explicitly // required to raise exception on attempt to remove a directory. Thus, // call POSIX unlink() here. + MP_THREAD_GIL_EXIT(); int r = unlink(path); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(r, errno); @@ -128,7 +135,9 @@ STATIC mp_obj_t mod_os_rename(mp_obj_t old_path_in, mp_obj_t new_path_in) { const char *old_path = mp_obj_str_get_str(old_path_in); const char *new_path = mp_obj_str_get_str(new_path_in); + MP_THREAD_GIL_EXIT(); int r = rename(old_path, new_path); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(r, errno); @@ -139,7 +148,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_os_rename_obj, mod_os_rename); STATIC mp_obj_t mod_os_rmdir(mp_obj_t path_in) { const char *path = mp_obj_str_get_str(path_in); + MP_THREAD_GIL_EXIT(); int r = rmdir(path); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(r, errno); @@ -150,7 +161,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_rmdir_obj, mod_os_rmdir); STATIC mp_obj_t mod_os_system(mp_obj_t cmd_in) { const char *cmd = mp_obj_str_get_str(cmd_in); + MP_THREAD_GIL_EXIT(); int r = system(cmd); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(r, errno); @@ -170,11 +183,13 @@ MP_DEFINE_CONST_FUN_OBJ_1(mod_os_getenv_obj, mod_os_getenv); STATIC mp_obj_t mod_os_mkdir(mp_obj_t path_in) { // TODO: Accept mode param const char *path = mp_obj_str_get_str(path_in); + MP_THREAD_GIL_EXIT(); #ifdef _WIN32 int r = mkdir(path); #else int r = mkdir(path, 0777); #endif + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(r, errno); return mp_const_none; } @@ -192,13 +207,16 @@ STATIC mp_obj_t listdir_next(mp_obj_t self_in) { if (self->dir == NULL) { goto done; } + MP_THREAD_GIL_EXIT(); struct dirent *dirent = readdir(self->dir); if (dirent == NULL) { closedir(self->dir); + MP_THREAD_GIL_ENTER(); self->dir = NULL; done: return MP_OBJ_STOP_ITERATION; } + MP_THREAD_GIL_ENTER(); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)); t->items[0] = mp_obj_new_str(dirent->d_name, strlen(dirent->d_name)); @@ -235,7 +253,9 @@ STATIC mp_obj_t mod_os_ilistdir(size_t n_args, const mp_obj_t *args) { } mp_obj_listdir_t *o = m_new_obj(mp_obj_listdir_t); o->base.type = &mp_type_polymorph_iter; + MP_THREAD_GIL_EXIT(); o->dir = opendir(path); + MP_THREAD_GIL_ENTER(); o->iternext = listdir_next; return MP_OBJ_FROM_PTR(o); } |