From 54c37e800a262219e5f73cb9390a409c0e248ea8 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Thu, 7 Apr 2022 15:46:18 -0600 Subject: [PATCH 1/8] Make vm_interrupt and timed_out atomic This is done by adding a new zend_atomic_bool type. The type definition is only available for compiler alignment and size info; it should be treated as opaque and only the zend_atomic_bool_* family of functions should be used. Note that directly using atomic_bool is complicated. All C++ compilers stdlibs that I checked typedef atomic_bool to std::atomic, which can't be used in an extern "C" section, and there's at least one usage of this in core, and probably more outside of it. So, instead check that atomic_bool has the same size and alignment as native bool and if so we'll cast it. --- Zend/Zend.m4 | 29 ++++++++++++++ Zend/zend_atomic.c | 67 ++++++++++++++++++++++++++++++++ Zend/zend_atomic.h | 21 ++++++++++ Zend/zend_execute.c | 4 +- Zend/zend_execute_API.c | 25 ++++++------ Zend/zend_globals.h | 5 ++- Zend/zend_vm_def.h | 4 +- Zend/zend_vm_execute.h | 4 +- configure.ac | 2 +- ext/opcache/jit/zend_jit_trace.c | 2 +- ext/pcntl/pcntl.c | 2 +- win32/build/config.w32 | 2 +- win32/signal.c | 2 +- 13 files changed, 143 insertions(+), 26 deletions(-) create mode 100644 Zend/zend_atomic.c create mode 100644 Zend/zend_atomic.h diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index fe28134dd92d6..aaa87ecb3fb0d 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -389,3 +389,32 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ if test "$ac_cv_cpuid_count_available" = "yes"; then AC_DEFINE([HAVE_CPUID_COUNT], 1, [whether __cpuid_count is available]) fi + +dnl Check whether is available. +AC_CACHE_CHECK( + [whether is available], + ac_cv_stdatomic_h, + [AC_RUN_IFELSE( + [AC_LANG_SOURCE( + [[ + #include + #include + int main(void) { + atomic_bool val = false; + (void)atomic_load(&val); + atomic_store(&val, true); + (void)atomic_exchange(&val, false); + + if (sizeof(atomic_bool) != sizeof(bool)) return 1; + if (_Alignof(atomic_bool) != _Alignof(bool)) return 1; + return 0; + } + ]] + )], + [ac_cv_stdatomic_h_available=yes], + [ac_cv_stdatomic_h_available=no] + )] +) +if test "$ac_cv_stdatomic_h_available" = "yes"; then + AC_DEFINE([HAVE_STDATOMIC_H], 1, [whether is available]) +fi diff --git a/Zend/zend_atomic.c b/Zend/zend_atomic.c new file mode 100644 index 0000000000000..85c8f4b6d25b2 --- /dev/null +++ b/Zend/zend_atomic.c @@ -0,0 +1,67 @@ +// TODO: license + +#include "zend_atomic.h" + +/* The general strategy here is to use C11's stdatomic.h functions when they + * are available, and then fall-back to non-atomic operations, except for + * Windows, which has C++ std::atomic_bool but not C atomic_bool. + * + * The defines HAVE_ATOMIC_BOOL should only be set when it is determined that + * representations of atomic_bool and bool are the same, as this is relied on + * in the implementation. + */ + +#if HAVE_STDATOMIC_H +#include +#define HAVE_ATOMIC_BOOL 1 +#elif WIN32 +#include +using std::atomic_bool; +using std::atomic_exchange; +using std::atomic_load; +using std::atomic_store; +static_assert(sizeof(atomic_bool) == sizeof(bool), "Repr of atomic_bool and bool must match"); +static_assert(alignof(atomic_bool) == alignof(bool), "Repr of atomic_bool and bool must match"); +#define HAVE_ATOMIC_BOOL 1 +#else +#define HAVE_ATOMIC_BOOL 0 +#endif + +#if HAVE_ATOMIC_BOOL + +ZEND_API bool zend_atomic_bool_exchange(zend_atomic_bool *obj, bool desired) { + return atomic_exchange((atomic_bool *)obj, desired); +} + +ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj) { + return atomic_load((const atomic_bool *)obj); +} + +ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired) { + atomic_store((atomic_bool *)obj, desired); +} + +#else + +/* Yes, these are not guaranteed to be atomic. Understand that previously + * atomics were never used, so the fact they are sometimes used is an + * improvement. As more platforms support C11 atomics, or as we add support + * for more platforms through intrinsics/asm, this should be used less and + * less until it can be removed. + */ + +ZEND_API bool zend_atomic_bool_exchange(zend_atomic_bool *obj, bool desired) { + bool previous = obj->bytes; + obj->bytes = desired; + return previous; +} + +ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj) { + return obj->bytes; +} + +ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired) { + obj->bytes = desired; +} + +#endif diff --git a/Zend/zend_atomic.h b/Zend/zend_atomic.h new file mode 100644 index 0000000000000..544d277d2ad1b --- /dev/null +++ b/Zend/zend_atomic.h @@ -0,0 +1,21 @@ +// TODO: license + +#include "zend_portability.h" + +#include + +/* These functions correspond to C11's stdatomic.h functions but are type- + * specialized because it's difficult to provide portable routines such as + * exchange without making functions. + * + * Treat zend_atomic_* types as opaque. They have definitions only for size + * and alignment purposes. + */ + +typedef struct zend_atomic_bool_s { + volatile bool bytes; +} zend_atomic_bool; + +ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj); +ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired); +ZEND_API bool zend_atomic_bool_exchange(zend_atomic_bool *obj, bool desired); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 436a5a2fd2a94..9f3b15cafe2bf 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3726,13 +3726,13 @@ ZEND_API void ZEND_FASTCALL zend_free_compiled_variables(zend_execute_data *exec /* }}} */ #define ZEND_VM_INTERRUPT_CHECK() do { \ - if (UNEXPECTED(EG(vm_interrupt))) { \ + if (UNEXPECTED(zend_atomic_bool_load(&EG(vm_interrupt)))) { \ ZEND_VM_INTERRUPT(); \ } \ } while (0) #define ZEND_VM_LOOP_INTERRUPT_CHECK() do { \ - if (UNEXPECTED(EG(vm_interrupt))) { \ + if (UNEXPECTED(zend_atomic_bool_load(&EG(vm_interrupt)))) { \ ZEND_VM_LOOP_INTERRUPT(); \ } \ } while (0) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index e9ecc5d6697d6..220f9e4411e32 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -168,8 +168,8 @@ void init_executor(void) /* {{{ */ zend_objects_store_init(&EG(objects_store), 1024); EG(full_tables_cleanup) = 0; - EG(vm_interrupt) = 0; - EG(timed_out) = 0; + zend_atomic_bool_store(&EG(vm_interrupt), false); + zend_atomic_bool_store(&EG(timed_out), false); EG(exception) = NULL; EG(prev_exception) = NULL; @@ -960,9 +960,8 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ /* This flag is regularly checked while running user functions, but not internal * So see whether interrupt flag was set while the function was running... */ - if (EG(vm_interrupt)) { - EG(vm_interrupt) = 0; - if (EG(timed_out)) { + if (zend_atomic_bool_exchange(&EG(vm_interrupt), false)) { + if (zend_atomic_bool_load(&EG(timed_out))) { zend_timeout(); } else if (zend_interrupt_function) { zend_interrupt_function(EG(current_execute_data)); @@ -1337,7 +1336,7 @@ ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */ } # endif #else - EG(timed_out) = 0; + zend_atomic_bool_store(&EG(timed_out), false); zend_set_timeout_ex(0, 1); #endif @@ -1349,7 +1348,7 @@ ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */ static void zend_timeout_handler(int dummy) /* {{{ */ { #ifndef ZTS - if (EG(timed_out)) { + if (zend_atomic_bool_load(&EG(timed_out))) { /* Die on hard timeout */ const char *error_filename = NULL; uint32_t error_lineno = 0; @@ -1384,8 +1383,8 @@ static void zend_timeout_handler(int dummy) /* {{{ */ zend_on_timeout(EG(timeout_seconds)); } - EG(timed_out) = 1; - EG(vm_interrupt) = 1; + zend_atomic_bool_store(&EG(timed_out), true); + zend_atomic_bool_store(&EG(vm_interrupt), true); #ifndef ZTS if (EG(hard_timeout) > 0) { @@ -1409,8 +1408,8 @@ VOID CALLBACK tq_timer_cb(PVOID arg, BOOLEAN timed_out) } eg = (zend_executor_globals *)arg; - eg->timed_out = 1; - eg->vm_interrupt = 1; + zend_atomic_bool_store(&eg->timed_out, true); + zend_atomic_bool_store(&eg->vm_interrupt, true); } #endif @@ -1496,7 +1495,7 @@ void zend_set_timeout(zend_long seconds, bool reset_signals) /* {{{ */ EG(timeout_seconds) = seconds; zend_set_timeout_ex(seconds, reset_signals); - EG(timed_out) = 0; + zend_atomic_bool_store(&EG(timed_out), false); } /* }}} */ @@ -1525,7 +1524,7 @@ void zend_unset_timeout(void) /* {{{ */ # endif } #endif - EG(timed_out) = 0; + zend_atomic_bool_store(&EG(timed_out), false); } /* }}} */ diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index ccee57b3fb1bd..17469fab0c11e 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -25,6 +25,7 @@ #include "zend_globals_macros.h" +#include "zend_atomic.h" #include "zend_stack.h" #include "zend_ptr_stack.h" #include "zend_hash.h" @@ -189,8 +190,8 @@ struct _zend_executor_globals { /* for extended information support */ bool no_extensions; - bool vm_interrupt; - bool timed_out; + zend_atomic_bool vm_interrupt; + zend_atomic_bool timed_out; zend_long hard_timeout; #ifdef ZEND_WIN32 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index bbba2ca0dfc97..e9b146824abe0 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -9892,9 +9892,9 @@ ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA); ZEND_VM_HELPER(zend_interrupt_helper, ANY, ANY) { - EG(vm_interrupt) = 0; + zend_atomic_bool_store(&EG(vm_interrupt), false); SAVE_OPLINE(); - if (EG(timed_out)) { + if (zend_atomic_bool_load(&EG(timed_out))) { zend_timeout(); } else if (zend_interrupt_function) { zend_interrupt_function(execute_data); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 1b27785470062..839c3086f9e39 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3537,9 +3537,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_FORWARD_SPEC_H static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { - EG(vm_interrupt) = 0; + zend_atomic_bool_store(&EG(vm_interrupt), false); SAVE_OPLINE(); - if (EG(timed_out)) { + if (zend_atomic_bool_load(&EG(timed_out))) { zend_timeout(); } else if (zend_interrupt_function) { zend_interrupt_function(execute_data); diff --git a/configure.ac b/configure.ac index c2886439afa6b..9d24ae23cb42b 100644 --- a/configure.ac +++ b/configure.ac @@ -1637,7 +1637,7 @@ PHP_ADD_SOURCES(Zend, \ zend_closures.c zend_weakrefs.c zend_float.c zend_string.c zend_signal.c zend_generators.c \ zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \ zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c \ - zend_observer.c zend_system_id.c zend_enum.c zend_fibers.c \ + zend_observer.c zend_system_id.c zend_enum.c zend_fibers.c zend_atomic.c \ Optimizer/zend_optimizer.c \ Optimizer/pass1.c \ Optimizer/pass3.c \ diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index ad19722dead4f..77b8d4575546f 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -8023,7 +8023,7 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf EX(opline) = opline; } - if (EG(vm_interrupt) || JIT_G(tracing)) { + if (zend_atomic_bool_load(&EG(vm_interrupt)) || JIT_G(tracing)) { return 1; /* Lock-free check if the side trace was already JIT-ed or blacklist-ed in another process */ } else if (t->exit_info[exit_num].flags & (ZEND_JIT_EXIT_JITED|ZEND_JIT_EXIT_BLACKLISTED)) { diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 8931ba92af538..91760e997c30a 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1383,7 +1383,7 @@ static void pcntl_signal_handler(int signo) PCNTL_G(tail) = psig; PCNTL_G(pending_signals) = 1; if (PCNTL_G(async_signals)) { - EG(vm_interrupt) = 1; + zend_atomic_bool_store(&EG(vm_interrupt), true); } } diff --git a/win32/build/config.w32 b/win32/build/config.w32 index b28a97672e3ff..4809b6a789c27 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -238,7 +238,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \ zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \ zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_observer.c zend_system_id.c \ - zend_enum.c zend_fibers.c"); + zend_enum.c zend_fibers.c zend_atomic.h"); ADD_SOURCES("Zend\\Optimizer", "zend_optimizer.c pass1.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dfg.c dfa_pass.c zend_ssa.c zend_inference.c zend_func_info.c zend_call_graph.c zend_dump.c escape_analysis.c compact_vars.c dce.c sccp.c scdf.c"); var FIBER_ASSEMBLER = X64 ? PATH_PROG('ML64') : PATH_PROG('ML'); diff --git a/win32/signal.c b/win32/signal.c index 088a0044283fc..3c35f66eaca10 100644 --- a/win32/signal.c +++ b/win32/signal.c @@ -22,7 +22,7 @@ /* true globals; only used from main thread and from kernel callback */ static zval ctrl_handler; static DWORD ctrl_evt = (DWORD)-1; -static bool *vm_interrupt_flag = NULL; +static volatile bool *vm_interrupt_flag = NULL; static void (*orig_interrupt_function)(zend_execute_data *execute_data); From fe340fd4ae7fc6df2d6940f692c54748327aa0f9 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Thu, 7 Apr 2022 15:47:56 -0600 Subject: [PATCH 2/8] WIN32 -> ZEND_WIN32 --- Zend/zend_atomic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_atomic.c b/Zend/zend_atomic.c index 85c8f4b6d25b2..0a57b413b8d9c 100644 --- a/Zend/zend_atomic.c +++ b/Zend/zend_atomic.c @@ -14,7 +14,7 @@ #if HAVE_STDATOMIC_H #include #define HAVE_ATOMIC_BOOL 1 -#elif WIN32 +#elif ZEND_WIN32 #include using std::atomic_bool; using std::atomic_exchange; From 98ed8c3bbd3b4b6e8e7fa5bed646cd7f425bdfc3 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Thu, 7 Apr 2022 21:19:26 -0600 Subject: [PATCH 3/8] Fix some Windows build errors --- Zend/zend_execute_API.c | 4 ++-- win32/build/config.w32 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 220f9e4411e32..0bd95ec756388 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1329,7 +1329,7 @@ ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */ timer is not restarted properly, it could hang in the shutdown function. */ if (EG(hard_timeout) > 0) { - EG(timed_out) = 0; + zend_atomic_bool_store(&EG(timed_out), 0); zend_set_timeout_ex(EG(hard_timeout), 1); /* XXX Abused, introduce an additional flag if the value needs to be kept. */ EG(hard_timeout) = 0; @@ -1504,7 +1504,7 @@ void zend_unset_timeout(void) /* {{{ */ #ifdef ZEND_WIN32 if (NULL != tq_timer) { if (!DeleteTimerQueueTimer(NULL, tq_timer, INVALID_HANDLE_VALUE)) { - EG(timed_out) = 0; + zend_atomic_bool_store(&EG(timed_out), 0); tq_timer = NULL; zend_error_noreturn(E_ERROR, "Could not delete queued timer"); return; diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 4809b6a789c27..ace404d2c3363 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -238,7 +238,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \ zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \ zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_observer.c zend_system_id.c \ - zend_enum.c zend_fibers.c zend_atomic.h"); + zend_enum.c zend_fibers.c zend_atomic.c"); ADD_SOURCES("Zend\\Optimizer", "zend_optimizer.c pass1.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dfg.c dfa_pass.c zend_ssa.c zend_inference.c zend_func_info.c zend_call_graph.c zend_dump.c escape_analysis.c compact_vars.c dce.c sccp.c scdf.c"); var FIBER_ASSEMBLER = X64 ? PATH_PROG('ML64') : PATH_PROG('ML'); From b2eee6557fd46cda53687697e055c5067a104b24 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Thu, 7 Apr 2022 21:34:41 -0600 Subject: [PATCH 4/8] Try splitting C/C++ for atomic --- Zend/zend_atomic.c | 16 +--------------- Zend/zend_atomic.cpp | 25 +++++++++++++++++++++++++ Zend/zend_atomic.h | 4 ++++ win32/build/config.w32 | 2 +- 4 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 Zend/zend_atomic.cpp diff --git a/Zend/zend_atomic.c b/Zend/zend_atomic.c index 0a57b413b8d9c..641faf68b3bfd 100644 --- a/Zend/zend_atomic.c +++ b/Zend/zend_atomic.c @@ -12,22 +12,8 @@ */ #if HAVE_STDATOMIC_H -#include -#define HAVE_ATOMIC_BOOL 1 -#elif ZEND_WIN32 -#include -using std::atomic_bool; -using std::atomic_exchange; -using std::atomic_load; -using std::atomic_store; -static_assert(sizeof(atomic_bool) == sizeof(bool), "Repr of atomic_bool and bool must match"); -static_assert(alignof(atomic_bool) == alignof(bool), "Repr of atomic_bool and bool must match"); -#define HAVE_ATOMIC_BOOL 1 -#else -#define HAVE_ATOMIC_BOOL 0 -#endif -#if HAVE_ATOMIC_BOOL +#include ZEND_API bool zend_atomic_bool_exchange(zend_atomic_bool *obj, bool desired) { return atomic_exchange((atomic_bool *)obj, desired); diff --git a/Zend/zend_atomic.cpp b/Zend/zend_atomic.cpp new file mode 100644 index 0000000000000..e8872ebaf55c1 --- /dev/null +++ b/Zend/zend_atomic.cpp @@ -0,0 +1,25 @@ +// TODO: license + +#include "zend_atomic.h" + +#if !defined(ZEND_WIN32) +#error This implementation is meant for Windows only. Please refer to zend_atomic.c. +#endif + +#include +using std::atomic_bool; + +static_assert(sizeof(atomic_bool) == sizeof(bool), "Repr of atomic_bool and bool must match"); +static_assert(alignof(atomic_bool) == alignof(bool), "Repr of atomic_bool and bool must match"); + +ZEND_API bool zend_atomic_bool_exchange(zend_atomic_bool *obj, bool desired) { + return std::atomic_exchange((atomic_bool *)obj, desired); +} + +ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj) { + return std::atomic_load((const atomic_bool *)obj); +} + +ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired) { + std::atomic_store((atomic_bool *)obj, desired); +} diff --git a/Zend/zend_atomic.h b/Zend/zend_atomic.h index 544d277d2ad1b..aefea029d49f1 100644 --- a/Zend/zend_atomic.h +++ b/Zend/zend_atomic.h @@ -16,6 +16,10 @@ typedef struct zend_atomic_bool_s { volatile bool bytes; } zend_atomic_bool; +BEGIN_EXTERN_C() + ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj); ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired); ZEND_API bool zend_atomic_bool_exchange(zend_atomic_bool *obj, bool desired); + +END_EXTERN_C() diff --git a/win32/build/config.w32 b/win32/build/config.w32 index ace404d2c3363..850ca92a103d9 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -238,7 +238,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \ zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \ zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_observer.c zend_system_id.c \ - zend_enum.c zend_fibers.c zend_atomic.c"); + zend_enum.c zend_fibers.c zend_atomic.cpp"); ADD_SOURCES("Zend\\Optimizer", "zend_optimizer.c pass1.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dfg.c dfa_pass.c zend_ssa.c zend_inference.c zend_func_info.c zend_call_graph.c zend_dump.c escape_analysis.c compact_vars.c dce.c sccp.c scdf.c"); var FIBER_ASSEMBLER = X64 ? PATH_PROG('ML64') : PATH_PROG('ML'); From b92d75059d6c453f7bc283553581a5b7f45971ab Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Thu, 7 Apr 2022 22:00:28 -0600 Subject: [PATCH 5/8] Try fixing Win32 --- win32/signal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/win32/signal.c b/win32/signal.c index 3c35f66eaca10..8b11dc5bc9a62 100644 --- a/win32/signal.c +++ b/win32/signal.c @@ -16,13 +16,14 @@ #include "php.h" #include "SAPI.h" +#include "zend_atomic.h" #include "win32/console.h" /* true globals; only used from main thread and from kernel callback */ static zval ctrl_handler; static DWORD ctrl_evt = (DWORD)-1; -static volatile bool *vm_interrupt_flag = NULL; +static zend_atomic_bool *vm_interrupt_flag = NULL; static void (*orig_interrupt_function)(zend_execute_data *execute_data); @@ -77,7 +78,7 @@ static BOOL WINAPI php_win32_signal_system_ctrl_handler(DWORD evt) return FALSE; } - (void)InterlockedExchange8(vm_interrupt_flag, 1); + zend_atomic_bool_store(vm_interrupt_flag, true); ctrl_evt = evt; From 6aa95684d955fb7c3b944d787e7804ca07f88292 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 8 Apr 2022 09:10:04 -0600 Subject: [PATCH 6/8] Add header guards --- Zend/zend_atomic.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Zend/zend_atomic.h b/Zend/zend_atomic.h index aefea029d49f1..1bdf49c6605e1 100644 --- a/Zend/zend_atomic.h +++ b/Zend/zend_atomic.h @@ -1,5 +1,8 @@ // TODO: license +#ifndef ZEND_ATOMIC_H +#define ZEND_ATOMIC_H + #include "zend_portability.h" #include @@ -23,3 +26,5 @@ ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired); ZEND_API bool zend_atomic_bool_exchange(zend_atomic_bool *obj, bool desired); END_EXTERN_C() + +#endif From 30d3b042bbdc16519a74e12707d7774cab7ecfab Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 8 Apr 2022 09:13:17 -0600 Subject: [PATCH 7/8] Add license --- Zend/zend_atomic.c | 14 +++++++++++++- Zend/zend_atomic.cpp | 14 +++++++++++++- Zend/zend_atomic.h | 14 +++++++++++++- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/Zend/zend_atomic.c b/Zend/zend_atomic.c index 641faf68b3bfd..589f8d3075d0f 100644 --- a/Zend/zend_atomic.c +++ b/Zend/zend_atomic.c @@ -1,4 +1,16 @@ -// TODO: license +/* + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Levi Morrison | + +----------------------------------------------------------------------+ + */ #include "zend_atomic.h" diff --git a/Zend/zend_atomic.cpp b/Zend/zend_atomic.cpp index e8872ebaf55c1..bcf9c4f161a6d 100644 --- a/Zend/zend_atomic.cpp +++ b/Zend/zend_atomic.cpp @@ -1,4 +1,16 @@ -// TODO: license +/* + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Levi Morrison | + +----------------------------------------------------------------------+ + */ #include "zend_atomic.h" diff --git a/Zend/zend_atomic.h b/Zend/zend_atomic.h index 1bdf49c6605e1..6d1e3388c35b0 100644 --- a/Zend/zend_atomic.h +++ b/Zend/zend_atomic.h @@ -1,4 +1,16 @@ -// TODO: license +/* + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Levi Morrison | + +----------------------------------------------------------------------+ + */ #ifndef ZEND_ATOMIC_H #define ZEND_ATOMIC_H From 8f381d028f12ba29c0a56a88dde44edb8d3d3a1c Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 8 Apr 2022 09:22:24 -0600 Subject: [PATCH 8/8] Fix phpdbg --- sapi/phpdbg/phpdbg_prompt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index dfdac95cae58d..6126ea8e0734b 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -1663,7 +1663,7 @@ void phpdbg_execute_ex(zend_execute_data *execute_data) /* {{{ */ } #ifdef ZEND_WIN32 - if (EG(timed_out)) { + if (zend_atomic_bool_load(&EG(timed_out))) { zend_timeout(); } #endif