diff --git a/CMakeLists.txt b/CMakeLists.txt index f9ec20fb..945b0c75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,10 @@ if(PK_ENABLE_OS) add_definitions(-DPK_ENABLE_OS=1) endif() +if(PK_ENABLE_THREADS) + add_definitions(-DPK_ENABLE_THREADS=1) +endif() + if(PK_ENABLE_DETERMINISM) add_subdirectory(3rd/dmath/dmath) add_definitions(-DPK_ENABLE_DETERMINISM=1) @@ -104,8 +108,10 @@ if(PK_ENABLE_DETERMINISM) endif() endif() -find_package(Threads REQUIRED) -target_link_libraries(${PROJECT_NAME} Threads::Threads) +if(PK_ENABLE_THREADS) + find_package(Threads REQUIRED) + target_link_libraries(${PROJECT_NAME} Threads::Threads) +endif() if(UNIX AND NOT APPLE) if(NOT PK_ENABLE_DETERMINISM) diff --git a/CMakeOptions.txt b/CMakeOptions.txt index 10f4fa20..e9e241e2 100644 --- a/CMakeOptions.txt +++ b/CMakeOptions.txt @@ -7,6 +7,7 @@ endif() # system features option(PK_ENABLE_OS "" OFF) +option(PK_ENABLE_THREADS "" OFF) option(PK_ENABLE_DETERMINISM "" OFF) option(PK_ENABLE_WATCHDOG "" OFF) option(PK_ENABLE_CUSTOM_SNAME "" OFF) diff --git a/cmake_build.py b/cmake_build.py index 0e47e990..f1e1a3bd 100644 --- a/cmake_build.py +++ b/cmake_build.py @@ -20,7 +20,7 @@ assert config in ['Debug', 'Release', 'RelWithDebInfo'] os.chdir("build") -code = os.system(f"cmake .. -DPK_ENABLE_OS=ON -DPK_ENABLE_DETERMINISM=ON -DCMAKE_BUILD_TYPE={config} {extra_flags}") +code = os.system(f"cmake .. -DPK_ENABLE_OS=ON -DPK_ENABLE_THREADS=ON -DPK_ENABLE_DETERMINISM=ON -DCMAKE_BUILD_TYPE={config} {extra_flags}") assert code == 0 code = os.system(f"cmake --build . --config {config} -j 4") assert code == 0 diff --git a/include/pocketpy/common/threads.h b/include/pocketpy/common/threads.h index 0791433a..d1d1fa51 100644 --- a/include/pocketpy/common/threads.h +++ b/include/pocketpy/common/threads.h @@ -1,5 +1,9 @@ #pragma once +#include "pocketpy/config.h" + +#if PK_ENABLE_THREADS + #include #include @@ -17,3 +21,5 @@ typedef int c11_thrd_retval_t; bool c11_thrd_create(c11_thrd_t* thrd, c11_thrd_retval_t (*func)(void*), void* arg); void c11_thrd_yield(); + +#endif \ No newline at end of file diff --git a/include/pocketpy/config.h b/include/pocketpy/config.h index 91ad1d4e..b9c9278c 100644 --- a/include/pocketpy/config.h +++ b/include/pocketpy/config.h @@ -7,11 +7,14 @@ #define PK_VERSION_PATCH 0 /*************** feature settings ***************/ -// Whether to compile os-related modules or not #ifndef PK_ENABLE_OS // can be overridden by cmake #define PK_ENABLE_OS 1 #endif +#ifndef PK_ENABLE_THREADS // can be overridden by cmake +#define PK_ENABLE_THREADS 1 +#endif + #ifndef PK_ENABLE_DETERMINISM // must be enabled from cmake #define PK_ENABLE_DETERMINISM 0 #endif diff --git a/src/common/name.c b/src/common/name.c index d10f1597..0eaa8211 100644 --- a/src/common/name.c +++ b/src/common/name.c @@ -2,9 +2,8 @@ #include "pocketpy/common/name.h" #include "pocketpy/common/str.h" -#include "pocketpy/common/threads.h" #include "pocketpy/pocketpy.h" -#include +#include "pocketpy/common/threads.h" typedef struct NameBucket NameBucket; @@ -17,7 +16,9 @@ typedef struct NameBucket { static struct { NameBucket* table[0x10000]; +#if PK_ENABLE_THREADS atomic_flag lock; +#endif } pk_string_table; #define MAGIC_METHOD(x) py_Name x; @@ -43,9 +44,11 @@ void pk_names_finalize() { } py_Name py_namev(c11_sv name) { +#if PK_ENABLE_THREADS while(atomic_flag_test_and_set(&pk_string_table.lock)) { c11_thrd_yield(); } +#endif uint64_t hash = c11_sv__hash(name); int index = hash & 0xFFFF; NameBucket* p = pk_string_table.table[index]; @@ -61,7 +64,9 @@ py_Name py_namev(c11_sv name) { p = p->next; } if(found) { +#if PK_ENABLE_THREADS atomic_flag_clear(&pk_string_table.lock); +#endif return (py_Name)p; } @@ -78,7 +83,9 @@ py_Name py_namev(c11_sv name) { assert(prev->next == NULL); prev->next = bucket; } +#if PK_ENABLE_THREADS atomic_flag_clear(&pk_string_table.lock); +#endif return (py_Name)bucket; } diff --git a/src/common/threads.c b/src/common/threads.c index a9414a97..a2bb62cc 100644 --- a/src/common/threads.c +++ b/src/common/threads.c @@ -1,6 +1,7 @@ -#include "pocketpy/export.h" #include "pocketpy/common/threads.h" +#if PK_ENABLE_THREADS + #if PK_USE_PTHREADS bool c11_thrd_create(c11_thrd_t* thrd, c11_thrd_retval_t (*func)(void*), void* arg) { @@ -19,4 +20,6 @@ bool c11_thrd_create(c11_thrd_t* thrd, c11_thrd_retval_t (*func)(void*), void* a void c11_thrd_yield() { thrd_yield(); } -#endif \ No newline at end of file +#endif + +#endif // PK_ENABLE_THREADS \ No newline at end of file diff --git a/src/modules/os.c b/src/modules/os.c index abeb1e06..cceb1718 100644 --- a/src/modules/os.c +++ b/src/modules/os.c @@ -2,7 +2,7 @@ #include "pocketpy/pocketpy.h" #include "pocketpy/interpreter/vm.h" -#if PK_ENABLE_OS == 1 +#if PK_ENABLE_OS #include diff --git a/src/modules/pkpy.c b/src/modules/pkpy.c index 58bbc8a6..564551a7 100644 --- a/src/modules/pkpy.c +++ b/src/modules/pkpy.c @@ -106,6 +106,8 @@ static bool pkpy_watchdog_end(int argc, py_Ref argv) { } #endif +#if PK_ENABLE_THREADS + typedef struct c11_ComputeThread c11_ComputeThread; typedef struct { @@ -456,6 +458,8 @@ static void pk_ComputeThread__register(py_Ref mod) { py_bindmethod(type, "eval", ComputeThread_eval); } +#endif // PK_ENABLE_THREADS + static void pkpy_configmacros_add(py_Ref dict, const char* key, int val) { assert(dict->type == tp_dict); py_TValue tmp; @@ -508,11 +512,14 @@ void pk__add_module_pkpy() { py_bindfunc(mod, "watchdog_end", pkpy_watchdog_end); #endif +#if PK_ENABLE_THREADS pk_ComputeThread__register(mod); +#endif py_Ref configmacros = py_emplacedict(mod, py_name("configmacros")); py_newdict(configmacros); pkpy_configmacros_add(configmacros, "PK_ENABLE_OS", PK_ENABLE_OS); + pkpy_configmacros_add(configmacros, "PK_ENABLE_THREADS", PK_ENABLE_THREADS); pkpy_configmacros_add(configmacros, "PK_ENABLE_DETERMINISM", PK_ENABLE_DETERMINISM); pkpy_configmacros_add(configmacros, "PK_ENABLE_WATCHDOG", PK_ENABLE_WATCHDOG); pkpy_configmacros_add(configmacros, "PK_GC_MIN_THRESHOLD", PK_GC_MIN_THRESHOLD); diff --git a/tests/98_thread.py b/tests/98_thread.py index bc428315..6f4c5d2e 100644 --- a/tests/98_thread.py +++ b/tests/98_thread.py @@ -1,4 +1,11 @@ -from pkpy import ComputeThread +from pkpy import configmacros + +if configmacros['PK_ENABLE_THREADS'] == 1: + from pkpy import ComputeThread +else: + print('threads is not enabled, skipping test...') + exit() + import time thread_1 = ComputeThread(1)