diff --git a/include/pocketpy/common/threads.h b/include/pocketpy/common/threads.h new file mode 100644 index 00000000..adf5d047 --- /dev/null +++ b/include/pocketpy/common/threads.h @@ -0,0 +1,17 @@ +#include +#include + +#if __EMSCRIPTEN__ || __APPLE__ || __linux__ +#include +#define PK_USE_PTHREADS 1 +typedef pthread_t c11_thrd_t; +typedef void* c11_thrd_retval_t; +#else +#include +#define PK_USE_PTHREADS 0 +typedef thrd_t c11_thrd_t; +typedef int c11_thrd_retval_t; +#endif + +bool c11_thrd_create(c11_thrd_t* thrd, c11_thrd_retval_t (*func)(void*), void* arg); +void c11_thrd_yield(); diff --git a/src/common/threads.c b/src/common/threads.c new file mode 100644 index 00000000..a9414a97 --- /dev/null +++ b/src/common/threads.c @@ -0,0 +1,22 @@ +#include "pocketpy/export.h" +#include "pocketpy/common/threads.h" + +#if PK_USE_PTHREADS + +bool c11_thrd_create(c11_thrd_t* thrd, c11_thrd_retval_t (*func)(void*), void* arg) { + int res = pthread_create(thrd, NULL, func, arg); + return res == 0; +} + +void c11_thrd_yield() { sched_yield(); } + +#else + +bool c11_thrd_create(c11_thrd_t* thrd, c11_thrd_retval_t (*func)(void*), void* arg) { + int res = thrd_create(thrd, func, arg); + return res == thrd_success; +} + +void c11_thrd_yield() { thrd_yield(); } + +#endif \ No newline at end of file diff --git a/src/modules/pkpy.c b/src/modules/pkpy.c index 913afabe..74dea82d 100644 --- a/src/modules/pkpy.c +++ b/src/modules/pkpy.c @@ -7,8 +7,7 @@ #include "pocketpy/common/sstream.h" #include "pocketpy/interpreter/vm.h" -#include -#include +#include "pocketpy/common/threads.h" #define DEF_TVALUE_METHODS(T, Field) \ static bool TValue_##T##__new__(int argc, py_Ref argv) { \ @@ -108,7 +107,7 @@ typedef struct c11_ComputeThread { int last_retval_size; char* last_error; - thrd_t thread; + c11_thrd_t thread; void* job; void (*job_dtor)(void*); } c11_ComputeThread; @@ -130,6 +129,8 @@ static void c11_ComputeThread__dtor(c11_ComputeThread* self) { c11__abort("ComputeThread(%d) is not done yet!! But the object was deleted.", self->vm_index); } + if(self->last_retval_data) PK_FREE(self->last_retval_data); + if(self->last_error) PK_FREE(self->last_error); c11_ComputeThread__reset_job(self, NULL, NULL); _pk_compute_thread_flags[self->vm_index] = false; } @@ -189,7 +190,7 @@ static bool ComputeThread_join(int argc, py_Ref argv) { PY_CHECK_ARGC(1); c11_ComputeThread* self = py_touserdata(argv); while(!self->is_done) - thrd_yield(); + c11_thrd_yield(); py_newnone(py_retval()); return true; } @@ -214,7 +215,7 @@ static bool ComputeThread_last_retval(int argc, py_Ref argv) { return py_pickle_loads(self->last_retval_data, self->last_retval_size); } -static int ComputeThreadJob_call(void* arg) { +static c11_thrd_retval_t ComputeThreadJob_call(void* arg) { ComputeThreadJobCall* job = arg; c11_ComputeThread* self = job->self; c11_ComputeThread__on_job_begin(self); @@ -238,17 +239,17 @@ static int ComputeThreadJob_call(void* arg) { self->last_retval_data = c11_memdup(retval_data, retval_size); self->last_retval_size = retval_size; self->is_done = true; - return 0; + return (c11_thrd_retval_t)0; __ERROR: self->last_error = py_formatexc(); self->is_done = true; py_clearexc(p0); py_newnone(py_retval()); - return 0; + return (c11_thrd_retval_t)0; } -static int ComputeThreadJob_exec(void* arg) { +static c11_thrd_retval_t ComputeThreadJob_exec(void* arg) { ComputeThreadJobExec* job = arg; c11_ComputeThread* self = job->self; c11_ComputeThread__on_job_begin(self); @@ -261,13 +262,13 @@ static int ComputeThreadJob_exec(void* arg) { self->last_retval_data = c11_memdup(retval_data, retval_size); self->last_retval_size = retval_size; self->is_done = true; - return 0; + return (c11_thrd_retval_t)0; __ERROR: self->last_error = py_formatexc(); self->is_done = true; py_clearexc(p0); - return 0; + return (c11_thrd_retval_t)0; } static bool ComputeThread_exec(int argc, py_Ref argv) { @@ -284,8 +285,8 @@ static bool ComputeThread_exec(int argc, py_Ref argv) { c11_ComputeThread__reset_job(self, job, ComputeThreadJobExec__dtor); /**************************/ self->is_done = false; - int res = thrd_create(&self->thread, ComputeThreadJob_exec, job); - if(res != thrd_success) { + bool ok = c11_thrd_create(&self->thread, ComputeThreadJob_exec, job); + if(!ok) { self->is_done = true; return OSError("thrd_create() failed"); } @@ -307,8 +308,8 @@ static bool ComputeThread_eval(int argc, py_Ref argv) { c11_ComputeThread__reset_job(self, job, ComputeThreadJobExec__dtor); /**************************/ self->is_done = false; - int res = thrd_create(&self->thread, ComputeThreadJob_exec, job); - if(res != thrd_success) { + bool ok = c11_thrd_create(&self->thread, ComputeThreadJob_exec, job); + if(!ok) { self->is_done = true; return OSError("thrd_create() failed"); } @@ -344,8 +345,8 @@ static bool ComputeThread_call(int argc, py_Ref argv) { c11_ComputeThread__reset_job(self, job, ComputeThreadJobCall__dtor); /**************************/ self->is_done = false; - int res = thrd_create(&self->thread, ComputeThreadJob_call, job); - if(res != thrd_success) { + bool ok = c11_thrd_create(&self->thread, ComputeThreadJob_call, job); + if(!ok) { self->is_done = true; return OSError("thrd_create() failed"); }