From f991cae01967837793bd032386dbfe7e3080eefa Mon Sep 17 00:00:00 2001 From: Marc Date: Sat, 26 Sep 2026 18:47:45 +0200 Subject: [PATCH 1/3] remove different implementations of zend_atomic --- UPGRADING.INTERNALS | 4 + Zend/zend_atomic.c | 10 -- Zend/zend_atomic.h | 350 +++++---------------------------------- win32/build/confutils.js | 14 +- 4 files changed, 53 insertions(+), 325 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index a97aa97e5283..66dca48e7c32 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -22,6 +22,10 @@ PHP 8.7 INTERNALS UPGRADE NOTES 2. Build system changes ======================== +- Windows build system changes: + . C11 atomics are now required. MSVC builds require Visual Studio 2022 17.5 or + later and enable /experimental:c11atomics. + - Unix build system changes: . Autoconf minimum required version upgraded to 2.71. diff --git a/Zend/zend_atomic.c b/Zend/zend_atomic.c index 98a39c583437..80ccd2bdfe1d 100644 --- a/Zend/zend_atomic.c +++ b/Zend/zend_atomic.c @@ -57,19 +57,9 @@ ZEND_API void zend_atomic_int_store(zend_atomic_int *obj, int desired) { zend_atomic_int_store_ex(obj, desired); } -#if (defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS)) && !defined(HAVE_C11_ATOMICS) -/* On these platforms it is non-const due to underlying APIs. */ -ZEND_API bool zend_atomic_bool_load(zend_atomic_bool *obj) { - return zend_atomic_bool_load_ex(obj); -} -ZEND_API int zend_atomic_int_load(zend_atomic_int *obj) { - return zend_atomic_int_load_ex(obj); -} -#else ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj) { return zend_atomic_bool_load_ex(obj); } ZEND_API int zend_atomic_int_load(const zend_atomic_int *obj) { return zend_atomic_int_load_ex(obj); } -#endif diff --git a/Zend/zend_atomic.h b/Zend/zend_atomic.h index 31558996c3c3..1ee0e0129f23 100644 --- a/Zend/zend_atomic.h +++ b/Zend/zend_atomic.h @@ -19,351 +19,87 @@ #include -#define ZEND_GCC_PREREQ(x, y) \ - ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || (__GNUC__ > (x))) - -/* Builtins are used to avoid library linkage */ -#if __has_feature(c_atomic) && defined(__clang__) -#define HAVE_C11_ATOMICS 1 -#elif ZEND_GCC_PREREQ(4, 7) -#define HAVE_GNUC_ATOMICS 1 -#elif defined(__GNUC__) -#define HAVE_SYNC_ATOMICS 1 -#elif !defined(ZEND_WIN32) -#define HAVE_NO_ATOMICS 1 +#ifdef __cplusplus +extern "C++" { +# include +} +#else +# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L +# error "Zend requires C11 or later" +# endif +# ifdef __STDC_NO_ATOMICS__ +# error "Zend requires C11 atomics" +# endif +# include #endif -#undef ZEND_GCC_PREREQ - /* Treat zend_atomic_* types as opaque. They have definitions only for size * and alignment purposes. */ -#if (defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS)) && !defined(HAVE_C11_ATOMICS) -typedef struct zend_atomic_bool_s { - volatile char value; -} zend_atomic_bool; -typedef struct zend_atomic_int_s { -# ifdef ZEND_WIN32 - volatile long value; -# else - volatile int value; -# endif -} zend_atomic_int; -#elif defined(HAVE_C11_ATOMICS) typedef struct zend_atomic_bool_s { - _Atomic(bool) value; -} zend_atomic_bool; -typedef struct zend_atomic_int_s { - _Atomic(int) value; -} zend_atomic_int; +#ifdef __cplusplus + std::atomic_bool value; #else -typedef struct zend_atomic_bool_s { - volatile bool value; + atomic_bool value; +#endif } zend_atomic_bool; typedef struct zend_atomic_int_s { - volatile int value; -} zend_atomic_int; +#ifdef __cplusplus + std::atomic_int value; +#else + atomic_int value; #endif +} zend_atomic_int; BEGIN_EXTERN_C() -#if defined(ZEND_WIN32) && !defined(HAVE_C11_ATOMICS) +/* The standard atomic operations use sequentially consistent ordering. + * In C++, argument-dependent lookup selects the std::atomic overloads. + */ +#define ZEND_ATOMIC_BOOL_INIT(obj, desired) atomic_init(&(obj)->value, (bool) (desired)) +#define ZEND_ATOMIC_INT_INIT(obj, desired) atomic_init(&(obj)->value, (int) (desired)) -#ifndef InterlockedExchange8 -#define InterlockedExchange8 _InterlockedExchange8 -#endif -#ifndef InterlockedOr8 -#define InterlockedOr8 _InterlockedOr8 -#endif -#ifndef InterlockedCompareExchange8 -#define InterlockedCompareExchange8 _InterlockedCompareExchange8 -#endif -#ifndef InterlockedExchange -#define InterlockedExchange _InterlockedExchange -#endif -#ifndef InterlockedOr -#define InterlockedOr _InterlockedOr -#endif -#ifndef InterlockedCompareExchange -#define InterlockedCompareExchange _InterlockedCompareExchange +#ifdef __cplusplus +# define ZEND_ATOMIC_BOOL_INITIALIZER(desired) {{(bool) (desired)}} +# define ZEND_ATOMIC_INT_INITIALIZER(desired) {{(int) (desired)}} +#else +# define ZEND_ATOMIC_BOOL_INITIALIZER(desired) {.value = (desired)} +# define ZEND_ATOMIC_INT_INITIALIZER(desired) {.value = (desired)} #endif -#define ZEND_ATOMIC_BOOL_INIT(obj, desired) ((obj)->value = (desired)) -#define ZEND_ATOMIC_INT_INIT(obj, desired) ((obj)->value = (desired)) - -#define ZEND_ATOMIC_BOOL_INITIALIZER(desired) {.value = (desired)} -#define ZEND_ATOMIC_INT_INITIALIZER(desired) {.value = (desired)} - -static zend_always_inline bool zend_atomic_bool_exchange_ex(zend_atomic_bool *obj, bool desired) { - return InterlockedExchange8(&obj->value, desired); -} - -static zend_always_inline int zend_atomic_int_exchange_ex(zend_atomic_int *obj, int desired) { - return (int) InterlockedExchange(&obj->value, desired); -} - -static zend_always_inline bool zend_atomic_bool_compare_exchange_ex(zend_atomic_bool *obj, bool *expected, bool desired) { - bool prev = (bool) InterlockedCompareExchange8(&obj->value, *expected, desired); - if (prev == *expected) { - return true; - } else { - *expected = prev; - return false; - } -} - -static zend_always_inline bool zend_atomic_int_compare_exchange_ex(zend_atomic_int *obj, int *expected, int desired) { - int prev = (int) InterlockedCompareExchange(&obj->value, *expected, desired); - if (prev == *expected) { - return true; - } else { - *expected = prev; - return false; - } -} - -/* On this platform it is non-const due to Interlocked API */ -static zend_always_inline bool zend_atomic_bool_load_ex(zend_atomic_bool *obj) { - /* Or'ing with false won't change the value. */ - return InterlockedOr8(&obj->value, false); -} - -static zend_always_inline int zend_atomic_int_load_ex(zend_atomic_int *obj) { - /* Or'ing with 0 won't change the value. */ - return (int) InterlockedOr(&obj->value, 0); -} - -static zend_always_inline void zend_atomic_bool_store_ex(zend_atomic_bool *obj, bool desired) { - (void)InterlockedExchange8(&obj->value, desired); -} - -static zend_always_inline void zend_atomic_int_store_ex(zend_atomic_int *obj, int desired) { - (void)InterlockedExchange(&obj->value, desired); -} - -#elif defined(HAVE_C11_ATOMICS) - -#define ZEND_ATOMIC_BOOL_INIT(obj, desired) __c11_atomic_init(&(obj)->value, (desired)) -#define ZEND_ATOMIC_INT_INIT(obj, desired) __c11_atomic_init(&(obj)->value, (desired)) - -#define ZEND_ATOMIC_BOOL_INITIALIZER(desired) {.value = (desired)} -#define ZEND_ATOMIC_INT_INITIALIZER(desired) {.value = (desired)} - static zend_always_inline bool zend_atomic_bool_exchange_ex(zend_atomic_bool *obj, bool desired) { - return __c11_atomic_exchange(&obj->value, desired, __ATOMIC_SEQ_CST); + return atomic_exchange(&obj->value, desired); } static zend_always_inline int zend_atomic_int_exchange_ex(zend_atomic_int *obj, int desired) { - return __c11_atomic_exchange(&obj->value, desired, __ATOMIC_SEQ_CST); + return atomic_exchange(&obj->value, desired); } static zend_always_inline bool zend_atomic_bool_compare_exchange_ex(zend_atomic_bool *obj, bool *expected, bool desired) { - return __c11_atomic_compare_exchange_strong(&obj->value, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return atomic_compare_exchange_strong(&obj->value, expected, desired); } static zend_always_inline bool zend_atomic_int_compare_exchange_ex(zend_atomic_int *obj, int *expected, int desired) { - return __c11_atomic_compare_exchange_strong(&obj->value, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return atomic_compare_exchange_strong(&obj->value, expected, desired); } static zend_always_inline bool zend_atomic_bool_load_ex(const zend_atomic_bool *obj) { - return __c11_atomic_load(&obj->value, __ATOMIC_SEQ_CST); + return atomic_load(&obj->value); } static zend_always_inline int zend_atomic_int_load_ex(const zend_atomic_int *obj) { - return __c11_atomic_load(&obj->value, __ATOMIC_SEQ_CST); + return atomic_load(&obj->value); } static zend_always_inline void zend_atomic_bool_store_ex(zend_atomic_bool *obj, bool desired) { - __c11_atomic_store(&obj->value, desired, __ATOMIC_SEQ_CST); + atomic_store(&obj->value, desired); } static zend_always_inline void zend_atomic_int_store_ex(zend_atomic_int *obj, int desired) { - __c11_atomic_store(&obj->value, desired, __ATOMIC_SEQ_CST); + atomic_store(&obj->value, desired); } -#elif defined(HAVE_GNUC_ATOMICS) - -/* bool */ - -#define ZEND_ATOMIC_BOOL_INIT(obj, desired) ((obj)->value = (desired)) -#define ZEND_ATOMIC_INT_INIT(obj, desired) ((obj)->value = (desired)) - -#define ZEND_ATOMIC_BOOL_INITIALIZER(desired) {.value = (desired)} -#define ZEND_ATOMIC_INT_INITIALIZER(desired) {.value = (desired)} - -static zend_always_inline bool zend_atomic_bool_exchange_ex(zend_atomic_bool *obj, bool desired) { - bool prev = false; - __atomic_exchange(&obj->value, &desired, &prev, __ATOMIC_SEQ_CST); - return prev; -} - -static zend_always_inline int zend_atomic_int_exchange_ex(zend_atomic_int *obj, int desired) { - int prev = false; - __atomic_exchange(&obj->value, &desired, &prev, __ATOMIC_SEQ_CST); - return prev; -} - -static zend_always_inline bool zend_atomic_bool_compare_exchange_ex(zend_atomic_bool *obj, bool *expected, bool desired) { - return __atomic_compare_exchange(&obj->value, expected, &desired, /* weak */ false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); -} - -static zend_always_inline bool zend_atomic_int_compare_exchange_ex(zend_atomic_int *obj, int *expected, int desired) { - return __atomic_compare_exchange(&obj->value, expected, &desired, /* weak */ false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); -} - -static zend_always_inline bool zend_atomic_bool_load_ex(const zend_atomic_bool *obj) { - bool prev = false; - __atomic_load(&obj->value, &prev, __ATOMIC_SEQ_CST); - return prev; -} - -static zend_always_inline int zend_atomic_int_load_ex(const zend_atomic_int *obj) { - int prev = false; - __atomic_load(&obj->value, &prev, __ATOMIC_SEQ_CST); - return prev; -} - -static zend_always_inline void zend_atomic_bool_store_ex(zend_atomic_bool *obj, bool desired) { - __atomic_store(&obj->value, &desired, __ATOMIC_SEQ_CST); -} - -static zend_always_inline void zend_atomic_int_store_ex(zend_atomic_int *obj, int desired) { - __atomic_store(&obj->value, &desired, __ATOMIC_SEQ_CST); -} - -#elif defined(HAVE_SYNC_ATOMICS) - -#define ZEND_ATOMIC_BOOL_INIT(obj, desired) ((obj)->value = (desired)) -#define ZEND_ATOMIC_INT_INIT(obj, desired) ((obj)->value = (desired)) - -#define ZEND_ATOMIC_BOOL_INITIALIZER(desired) {.value = (desired)} -#define ZEND_ATOMIC_INT_INITIALIZER(desired) {.value = (desired)} - -static zend_always_inline bool zend_atomic_bool_exchange_ex(zend_atomic_bool *obj, bool desired) { - bool prev = __sync_lock_test_and_set(&obj->value, desired); - - /* __sync_lock_test_and_set only does an acquire barrier, so sync - * immediately after. - */ - __sync_synchronize(); - return prev; -} - -static zend_always_inline int zend_atomic_int_exchange_ex(zend_atomic_int *obj, int desired) { - int prev = __sync_lock_test_and_set(&obj->value, desired); - - /* __sync_lock_test_and_set only does an acquire barrier, so sync - * immediately after. - */ - __sync_synchronize(); - return prev; -} - -static zend_always_inline bool zend_atomic_bool_compare_exchange_ex(zend_atomic_bool *obj, bool *expected, bool desired) { - bool prev = __sync_val_compare_and_swap(&obj->value, *expected, desired); - if (prev == *expected) { - return true; - } else { - *expected = prev; - return false; - } -} - -static zend_always_inline bool zend_atomic_int_compare_exchange_ex(zend_atomic_int *obj, int *expected, int desired) { - int prev = __sync_val_compare_and_swap(&obj->value, *expected, desired); - if (prev == *expected) { - return true; - } else { - *expected = prev; - return false; - } -} - -static zend_always_inline bool zend_atomic_bool_load_ex(zend_atomic_bool *obj) { - /* Or'ing false won't change the value */ - return __sync_fetch_and_or(&obj->value, false); -} - -static zend_always_inline int zend_atomic_int_load_ex(zend_atomic_int *obj) { - /* Or'ing 0 won't change the value */ - return __sync_fetch_and_or(&obj->value, 0); -} - -static zend_always_inline void zend_atomic_bool_store_ex(zend_atomic_bool *obj, bool desired) { - __sync_synchronize(); - obj->value = desired; - __sync_synchronize(); -} - -static zend_always_inline void zend_atomic_int_store_ex(zend_atomic_int *obj, int desired) { - __sync_synchronize(); - obj->value = desired; - __sync_synchronize(); -} - -#elif defined(HAVE_NO_ATOMICS) - -#warning No atomics support detected. Please open an issue with platform details. - -#define ZEND_ATOMIC_BOOL_INIT(obj, desired) ((obj)->value = (desired)) -#define ZEND_ATOMIC_INT_INIT(obj, desired) ((obj)->value = (desired)) - -#define ZEND_ATOMIC_BOOL_INITIALIZER(desired) {.value = (desired)} -#define ZEND_ATOMIC_INT_INITIALIZER(desired) {.value = (desired)} - -static zend_always_inline void zend_atomic_bool_store_ex(zend_atomic_bool *obj, bool desired) { - obj->value = desired; -} - -static zend_always_inline void zend_atomic_int_store_ex(zend_atomic_int *obj, int desired) { - obj->value = desired; -} - -static zend_always_inline bool zend_atomic_bool_compare_exchange_ex(zend_atomic_int *obj, bool *expected, bool desired) { - bool prev = obj->value; - if (prev == *expected) { - obj->value = desired; - return true; - } else { - *expected = prev; - return false; - } -} - -static zend_always_inline bool zend_atomic_int_compare_exchange_ex(zend_atomic_int *obj, int *expected, int desired) { - int prev = obj->value; - if (prev == *expected) { - obj->value = desired; - return true; - } else { - *expected = prev; - return false; - } -} - -static zend_always_inline bool zend_atomic_bool_load_ex(const zend_atomic_bool *obj) { - return obj->value; -} - -static zend_always_inline int zend_atomic_int_load_ex(const zend_atomic_int *obj) { - return obj->value; -} - -static zend_always_inline bool zend_atomic_bool_exchange_ex(zend_atomic_bool *obj, bool desired) { - bool prev = obj->value; - obj->value = desired; - return prev; -} - -static zend_always_inline int zend_atomic_int_exchange_ex(zend_atomic_int *obj, int desired) { - int prev = obj->value; - obj->value = desired; - return prev; -} - -#endif - ZEND_API void zend_atomic_bool_init(zend_atomic_bool *obj, bool desired); ZEND_API void zend_atomic_int_init(zend_atomic_int *obj, int desired); @@ -376,14 +112,8 @@ ZEND_API bool zend_atomic_int_compare_exchange(zend_atomic_int *obj, int *expect ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired); ZEND_API void zend_atomic_int_store(zend_atomic_int *obj, int desired); -#if (defined(ZEND_WIN32) && !defined(HAVE_C11_ATOMICS)) || defined(HAVE_SYNC_ATOMICS) -/* On these platforms it is non-const due to underlying APIs. */ -ZEND_API bool zend_atomic_bool_load(zend_atomic_bool *obj); -ZEND_API int zend_atomic_int_load(zend_atomic_int *obj); -#else ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj); ZEND_API int zend_atomic_int_load(const zend_atomic_int *obj); -#endif END_EXTERN_C() diff --git a/win32/build/confutils.js b/win32/build/confutils.js index c5128f70498e..9b9ac1db1384 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -1625,6 +1625,10 @@ function ADD_SOURCES(dir, file_list, target, obj_dir, duplicate_sources) sym = target.toUpperCase() + "_GLOBAL_OBJS"; flags = "CFLAGS_" + target.toUpperCase() + '_OBJ'; + var c11_flags = ICC_TOOLSET ? " /Qstd=c11" : " /std:c11"; + if (VS_TOOLSET) { + c11_flags += " /experimental:c11atomics"; + } var bd = get_define('BUILD_DIR'); var respd = bd + '\\resp'; @@ -1790,7 +1794,7 @@ function ADD_SOURCES(dir, file_list, target, obj_dir, duplicate_sources) "--library=win32\\build\\cppcheck.cfg " + "--library=" + cppcheck_lib + " " + /* "--rule-file=win32\build\cppcheck_rules.xml " + */ - " --std=c89 --std=c++11 " + + " --std=c11 --std=c++11 " + "--quiet --inconclusive --template=vs -j 4 " + "--suppress=unmatchedSuppression " + "--suppressions-list=win32\\build\\cppcheck_suppress.txt "; @@ -1809,7 +1813,7 @@ function ADD_SOURCES(dir, file_list, target, obj_dir, duplicate_sources) var _tmp = src.split("\\"); var filename = _tmp.pop(); obj = filename.replace(re, ".obj"); - var c11_flag = VS_TOOLSET && !cxx_mode_targets[target] && /\.c$/i.test(src) ? " /std:c11" : ""; + var c11_flag = !cxx_mode_targets[target] && /\.c$/i.test(src) ? c11_flags : ""; MFO.WriteLine("\t" + CMD_MOD1 + "$(CC)" + c11_flag + " $(" + flags + ") $(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + d + obj); @@ -1830,12 +1834,12 @@ function ADD_SOURCES(dir, file_list, target, obj_dir, duplicate_sources) var source = file_list[srcs_by_dir[k][j]]; var source_path = dir + "\\" + source + " "; src_line += source_path; - src_lines[VS_TOOLSET && /\.c$/i.test(source) ? 0 : 1] += source_path; + src_lines[/\.c$/i.test(source) ? 0 : 1] += source_path; } for (var language = 0; language < src_lines.length; language++) { if (src_lines[language]) { - var c11_flag = language == 0 && !cxx_mode_targets[target] ? " /std:c11" : ""; + var c11_flag = language == 0 && !cxx_mode_targets[target] ? c11_flags : ""; MFO.WriteLine("\t" + CMD_MOD1 + "$(CC)" + c11_flag + " $(" + flags + ") $(CFLAGS) /Fo" + sub_build + d + " $(" + bd_flags_name + ") /c " + src_lines[language]); } } @@ -3149,7 +3153,7 @@ function toolset_get_compiler_version() if (VS_TOOLSET) { version = probe_binary(PHP_CL).substr(0, 5).replace('.', ''); - if (version < 1920) { + if (version < 1935) { ERROR("Building with MSC_VER " + version + " is no longer supported"); } return version; From 04d09af6b1e06c593d3fa5ab036f2e753d3e88b6 Mon Sep 17 00:00:00 2001 From: Marc Date: Sat, 26 Sep 2026 19:44:48 +0200 Subject: [PATCH 2/3] up to c17 --- UPGRADING.INTERNALS | 5 +++-- ext/intl/config.w32 | 3 ++- win32/build/confutils.js | 20 ++++++++------------ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 66dca48e7c32..da4aa0b5a30b 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -23,8 +23,9 @@ PHP 8.7 INTERNALS UPGRADE NOTES ======================== - Windows build system changes: - . C11 atomics are now required. MSVC builds require Visual Studio 2022 17.5 or - later and enable /experimental:c11atomics. + . C sources are now compiled as C17 and require C11 atomics. MSVC builds require + Visual Studio 2022 17.5 or later and enable /experimental:c11atomics. + . C++-only extension compiler flags can be added to CXXFLAGS_. - Unix build system changes: . Autoconf minimum required version upgraded to 2.71. diff --git a/ext/intl/config.w32 b/ext/intl/config.w32 index 5f689214c1b6..0ca9fcdef43e 100644 --- a/ext/intl/config.w32 +++ b/ext/intl/config.w32 @@ -125,7 +125,8 @@ if (PHP_INTL != "no") { /* Compat for ICU before 58.1.*/ CHECK_LIB("icule.lib", "intl", PHP_INTL); CHECK_LIB("iculx.lib", "intl", PHP_INTL); - ADD_FLAG("CFLAGS_INTL", "/std:c++17 /EHsc /DUNISTR_FROM_CHAR_EXPLICIT=explicit /DUNISTR_FROM_STRING_EXPLICIT=explicit /DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1 /DU_HIDE_OBSOLETE_UTF_OLD_H=1"); + ADD_FLAG("CXXFLAGS_INTL", "/std:c++17 /EHsc"); + ADD_FLAG("CFLAGS_INTL", "/DUNISTR_FROM_CHAR_EXPLICIT=explicit /DUNISTR_FROM_STRING_EXPLICIT=explicit /DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1 /DU_HIDE_OBSOLETE_UTF_OLD_H=1"); } else { WARNING("intl not enabled; libraries and/or headers not found"); } diff --git a/win32/build/confutils.js b/win32/build/confutils.js index 9b9ac1db1384..d01e3902e13d 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -58,7 +58,6 @@ var MINRE2C = "1.0.3"; /* Store the enabled extensions (summary + QA check) */ var extensions_enabled = new Array(); -var cxx_mode_targets = {}; /* Store the SAPI enabled (summary + QA check) */ var sapi_enabled = new Array(); @@ -1468,10 +1467,6 @@ function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir, cxx_mod var extname_for_printing; var ldflags; - if (cxx_mode) { - cxx_mode_targets[extname] = true; - } - if (shared == null) { if (force_all_shared()) { shared = true; @@ -1625,10 +1620,11 @@ function ADD_SOURCES(dir, file_list, target, obj_dir, duplicate_sources) sym = target.toUpperCase() + "_GLOBAL_OBJS"; flags = "CFLAGS_" + target.toUpperCase() + '_OBJ'; - var c11_flags = ICC_TOOLSET ? " /Qstd=c11" : " /std:c11"; + var c_flags = ICC_TOOLSET ? " /Qstd=c17" : " /std:c17"; if (VS_TOOLSET) { - c11_flags += " /experimental:c11atomics"; + c_flags += " /experimental:c11atomics"; } + var cxx_flags = " $(CXXFLAGS_" + target.toUpperCase() + ")"; var bd = get_define('BUILD_DIR'); var respd = bd + '\\resp'; @@ -1794,7 +1790,7 @@ function ADD_SOURCES(dir, file_list, target, obj_dir, duplicate_sources) "--library=win32\\build\\cppcheck.cfg " + "--library=" + cppcheck_lib + " " + /* "--rule-file=win32\build\cppcheck_rules.xml " + */ - " --std=c11 --std=c++11 " + + " --std=c17 --std=c++11 " + "--quiet --inconclusive --template=vs -j 4 " + "--suppress=unmatchedSuppression " + "--suppressions-list=win32\\build\\cppcheck_suppress.txt "; @@ -1813,9 +1809,9 @@ function ADD_SOURCES(dir, file_list, target, obj_dir, duplicate_sources) var _tmp = src.split("\\"); var filename = _tmp.pop(); obj = filename.replace(re, ".obj"); - var c11_flag = !cxx_mode_targets[target] && /\.c$/i.test(src) ? c11_flags : ""; + var language_flags = /\.c$/i.test(src) ? c_flags : cxx_flags; - MFO.WriteLine("\t" + CMD_MOD1 + "$(CC)" + c11_flag + " $(" + flags + ") $(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + d + obj); + MFO.WriteLine("\t" + CMD_MOD1 + "$(CC)" + language_flags + " $(" + flags + ") $(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + d + obj); if ("clang" == PHP_ANALYZER) { MFO.WriteLine("\t" + CMD_MOD1 + "\"$(CLANG_CL)\" " + analyzer_base_args + " $(" + flags + "_ANALYZER) $(CFLAGS_ANALYZER) $(" + bd_flags_name + "_ANALYZER) " + dir + "\\" + src); @@ -1839,8 +1835,8 @@ function ADD_SOURCES(dir, file_list, target, obj_dir, duplicate_sources) for (var language = 0; language < src_lines.length; language++) { if (src_lines[language]) { - var c11_flag = language == 0 && !cxx_mode_targets[target] ? c11_flags : ""; - MFO.WriteLine("\t" + CMD_MOD1 + "$(CC)" + c11_flag + " $(" + flags + ") $(CFLAGS) /Fo" + sub_build + d + " $(" + bd_flags_name + ") /c " + src_lines[language]); + var language_flags = language == 0 ? c_flags : cxx_flags; + MFO.WriteLine("\t" + CMD_MOD1 + "$(CC)" + language_flags + " $(" + flags + ") $(CFLAGS) /Fo" + sub_build + d + " $(" + bd_flags_name + ") /c " + src_lines[language]); } } From 4be1214f6944f14c859b475d4fb529c4e438320e Mon Sep 17 00:00:00 2001 From: Marc Date: Sun, 27 Sep 2026 09:57:32 +0200 Subject: [PATCH 3/3] remove zend_atomic entirely --- UPGRADING.INTERNALS | 2 + Zend/zend_atomic.c | 65 ----------------- Zend/zend_atomic.h | 120 ------------------------------- Zend/zend_execute.c | 10 +-- Zend/zend_execute_API.c | 28 ++++---- Zend/zend_globals.h | 5 +- Zend/zend_portability.h | 17 +++++ Zend/zend_vm_def.h | 4 +- Zend/zend_vm_execute.h | 8 +-- configure.ac | 1 - ext/opcache/jit/zend_jit_trace.c | 2 +- ext/pcntl/pcntl.c | 4 +- ext/random/csprng.c | 9 ++- ext/zend_test/object_handlers.c | 2 +- ext/zend_test/observer.c | 2 +- sapi/phpdbg/phpdbg_prompt.c | 2 +- win32/build/config.w32 | 2 +- win32/signal.c | 4 +- 18 files changed, 59 insertions(+), 228 deletions(-) delete mode 100644 Zend/zend_atomic.c delete mode 100644 Zend/zend_atomic.h diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index da4aa0b5a30b..7792827e45cb 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -17,6 +17,8 @@ PHP 8.7 INTERNALS UPGRADE NOTES - Removed zend_execute_scripts(). Manually call zend_execute_script() in a loop instead. - Removed ZEND_STATIC_ASSERT(). Use C11 static_assert() directly instead. +- Removed zend_atomic.h and the zend_atomic_* types and functions. + Use the standard C11 atomic_* types and functions instead. ======================== 2. Build system changes diff --git a/Zend/zend_atomic.c b/Zend/zend_atomic.c deleted file mode 100644 index 80ccd2bdfe1d..000000000000 --- a/Zend/zend_atomic.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Levi Morrison | - +----------------------------------------------------------------------+ - */ - -#include "zend_atomic.h" - -/* This file contains the non-inline copy of atomic functions. This is useful - * for extensions written in languages such as Rust. C and C++ compilers are - * probably going to inline these functions, but in the case they don't, this - * is also where the code will go. - */ - -/* Defined for FFI users; everyone else use ZEND_ATOMIC_*_INIT. - * This is NOT ATOMIC as it is meant for initialization. - */ -ZEND_API void zend_atomic_bool_init(zend_atomic_bool *obj, bool desired) { - ZEND_ATOMIC_BOOL_INIT(obj, desired); -} - -ZEND_API void zend_atomic_int_init(zend_atomic_int *obj, int desired) { - ZEND_ATOMIC_INT_INIT(obj, desired); -} - -ZEND_API bool zend_atomic_bool_exchange(zend_atomic_bool *obj, bool desired) { - return zend_atomic_bool_exchange_ex(obj, desired); -} - -ZEND_API int zend_atomic_int_exchange(zend_atomic_int *obj, int desired) { - return zend_atomic_int_exchange_ex(obj, desired); -} - -ZEND_API bool zend_atomic_bool_compare_exchange(zend_atomic_bool *obj, bool *expected, bool desired) -{ - return zend_atomic_bool_compare_exchange_ex(obj, expected, desired); -} - -ZEND_API bool zend_atomic_int_compare_exchange(zend_atomic_int *obj, int *expected, int desired) -{ - return zend_atomic_int_compare_exchange_ex(obj, expected, desired); -} - -ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired) { - zend_atomic_bool_store_ex(obj, desired); -} - -ZEND_API void zend_atomic_int_store(zend_atomic_int *obj, int desired) { - zend_atomic_int_store_ex(obj, desired); -} - -ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj) { - return zend_atomic_bool_load_ex(obj); -} -ZEND_API int zend_atomic_int_load(const zend_atomic_int *obj) { - return zend_atomic_int_load_ex(obj); -} diff --git a/Zend/zend_atomic.h b/Zend/zend_atomic.h deleted file mode 100644 index 1ee0e0129f23..000000000000 --- a/Zend/zend_atomic.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Levi Morrison | - +----------------------------------------------------------------------+ - */ - -#ifndef ZEND_ATOMIC_H -#define ZEND_ATOMIC_H - -#include "zend_portability.h" - -#include - -#ifdef __cplusplus -extern "C++" { -# include -} -#else -# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L -# error "Zend requires C11 or later" -# endif -# ifdef __STDC_NO_ATOMICS__ -# error "Zend requires C11 atomics" -# endif -# include -#endif - -/* Treat zend_atomic_* types as opaque. They have definitions only for size - * and alignment purposes. - */ - -typedef struct zend_atomic_bool_s { -#ifdef __cplusplus - std::atomic_bool value; -#else - atomic_bool value; -#endif -} zend_atomic_bool; -typedef struct zend_atomic_int_s { -#ifdef __cplusplus - std::atomic_int value; -#else - atomic_int value; -#endif -} zend_atomic_int; - -BEGIN_EXTERN_C() - -/* The standard atomic operations use sequentially consistent ordering. - * In C++, argument-dependent lookup selects the std::atomic overloads. - */ -#define ZEND_ATOMIC_BOOL_INIT(obj, desired) atomic_init(&(obj)->value, (bool) (desired)) -#define ZEND_ATOMIC_INT_INIT(obj, desired) atomic_init(&(obj)->value, (int) (desired)) - -#ifdef __cplusplus -# define ZEND_ATOMIC_BOOL_INITIALIZER(desired) {{(bool) (desired)}} -# define ZEND_ATOMIC_INT_INITIALIZER(desired) {{(int) (desired)}} -#else -# define ZEND_ATOMIC_BOOL_INITIALIZER(desired) {.value = (desired)} -# define ZEND_ATOMIC_INT_INITIALIZER(desired) {.value = (desired)} -#endif - -static zend_always_inline bool zend_atomic_bool_exchange_ex(zend_atomic_bool *obj, bool desired) { - return atomic_exchange(&obj->value, desired); -} - -static zend_always_inline int zend_atomic_int_exchange_ex(zend_atomic_int *obj, int desired) { - return atomic_exchange(&obj->value, desired); -} - -static zend_always_inline bool zend_atomic_bool_compare_exchange_ex(zend_atomic_bool *obj, bool *expected, bool desired) { - return atomic_compare_exchange_strong(&obj->value, expected, desired); -} - -static zend_always_inline bool zend_atomic_int_compare_exchange_ex(zend_atomic_int *obj, int *expected, int desired) { - return atomic_compare_exchange_strong(&obj->value, expected, desired); -} - -static zend_always_inline bool zend_atomic_bool_load_ex(const zend_atomic_bool *obj) { - return atomic_load(&obj->value); -} - -static zend_always_inline int zend_atomic_int_load_ex(const zend_atomic_int *obj) { - return atomic_load(&obj->value); -} - -static zend_always_inline void zend_atomic_bool_store_ex(zend_atomic_bool *obj, bool desired) { - atomic_store(&obj->value, desired); -} - -static zend_always_inline void zend_atomic_int_store_ex(zend_atomic_int *obj, int desired) { - atomic_store(&obj->value, desired); -} - -ZEND_API void zend_atomic_bool_init(zend_atomic_bool *obj, bool desired); -ZEND_API void zend_atomic_int_init(zend_atomic_int *obj, int desired); - -ZEND_API bool zend_atomic_bool_exchange(zend_atomic_bool *obj, bool desired); -ZEND_API int zend_atomic_int_exchange(zend_atomic_int *obj, int desired); - -ZEND_API bool zend_atomic_bool_compare_exchange(zend_atomic_bool *obj, bool *expected, bool desired); -ZEND_API bool zend_atomic_int_compare_exchange(zend_atomic_int *obj, int *expected, int desired); - -ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired); -ZEND_API void zend_atomic_int_store(zend_atomic_int *obj, int desired); - -ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj); -ZEND_API int zend_atomic_int_load(const zend_atomic_int *obj); - -END_EXTERN_C() - -#endif diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 799475d7df9e..c867361556df 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4339,8 +4339,8 @@ ZEND_API void ZEND_FASTCALL zend_free_compiled_variables(zend_execute_data *exec ZEND_API ZEND_COLD void ZEND_FASTCALL zend_fcall_interrupt(zend_execute_data *call) { - zend_atomic_bool_store_ex(&EG(vm_interrupt), false); - if (zend_atomic_bool_load_ex(&EG(timed_out))) { + atomic_store(&EG(vm_interrupt), false); + if (atomic_load(&EG(timed_out))) { zend_timeout(); } else if (zend_interrupt_function) { zend_interrupt_function(call); @@ -4348,7 +4348,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_fcall_interrupt(zend_execute_data *ca } #define ZEND_VM_INTERRUPT_CHECK() do { \ - if (UNEXPECTED(zend_atomic_bool_load_ex(&EG(vm_interrupt)))) { \ + if (UNEXPECTED(atomic_load(&EG(vm_interrupt)))) { \ ZEND_VM_INTERRUPT(); \ } \ } while (0) @@ -4360,14 +4360,14 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_fcall_interrupt(zend_execute_data *ca #endif #define ZEND_VM_LOOP_INTERRUPT_CHECK() do { \ - if (UNEXPECTED(zend_atomic_bool_load_ex(&EG(vm_interrupt)))) { \ + if (UNEXPECTED(atomic_load(&EG(vm_interrupt)))) { \ ZEND_VM_KIND_TAILCALL_SAVE_OPLINE(); \ ZEND_VM_LOOP_INTERRUPT(); \ } \ } while (0) #define ZEND_VM_FCALL_INTERRUPT_CHECK(call) do { \ - if (UNEXPECTED(zend_atomic_bool_load_ex(&EG(vm_interrupt)))) { \ + if (UNEXPECTED(atomic_load(&EG(vm_interrupt)))) { \ zend_fcall_interrupt(call); \ } \ } while (0) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 59fb717b5d28..c6e52fbfa1ac 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -172,8 +172,8 @@ void init_executor(void) /* {{{ */ zend_lazy_objects_init(&EG(lazy_objects_store)); EG(full_tables_cleanup) = 0; - ZEND_ATOMIC_BOOL_INIT(&EG(vm_interrupt), false); - ZEND_ATOMIC_BOOL_INIT(&EG(timed_out), false); + atomic_init(&EG(vm_interrupt), false); + atomic_init(&EG(timed_out), false); EG(exception) = NULL; @@ -1099,8 +1099,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 (zend_atomic_bool_exchange_ex(&EG(vm_interrupt), false)) { - if (zend_atomic_bool_load_ex(&EG(timed_out))) { + if (atomic_exchange(&EG(vm_interrupt), false)) { + if (atomic_load(&EG(timed_out))) { zend_timeout(); } else if (zend_interrupt_function) { zend_interrupt_function(EG(current_execute_data)); @@ -1476,14 +1476,14 @@ 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) { - zend_atomic_bool_store_ex(&EG(timed_out), false); + atomic_store(&EG(timed_out), false); zend_set_timeout_ex(EG(hard_timeout), true); /* XXX Abused, introduce an additional flag if the value needs to be kept. */ EG(hard_timeout) = 0; } # endif #else - zend_atomic_bool_store_ex(&EG(timed_out), false); + atomic_store(&EG(timed_out), false); zend_set_timeout_ex(0, true); #endif @@ -1528,7 +1528,7 @@ static void zend_timeout_handler(int dummy) /* {{{ */ return; } #else - if (zend_atomic_bool_load_ex(&EG(timed_out))) { + if (atomic_load(&EG(timed_out))) { /* Die on hard timeout */ const char *error_filename = NULL; uint32_t error_lineno = 0; @@ -1563,8 +1563,8 @@ static void zend_timeout_handler(int dummy) /* {{{ */ zend_on_timeout(EG(timeout_seconds)); } - zend_atomic_bool_store_ex(&EG(timed_out), true); - zend_atomic_bool_store_ex(&EG(vm_interrupt), true); + atomic_store(&EG(timed_out), true); + atomic_store(&EG(vm_interrupt), true); #ifndef ZTS if (EG(hard_timeout) > 0) { @@ -1588,8 +1588,8 @@ VOID CALLBACK tq_timer_cb(PVOID arg, BOOLEAN timed_out) } eg = (zend_executor_globals *)arg; - zend_atomic_bool_store_ex(&eg->timed_out, true); - zend_atomic_bool_store_ex(&eg->vm_interrupt, true); + atomic_store(&eg->timed_out, true); + atomic_store(&eg->vm_interrupt, true); } #endif @@ -1697,7 +1697,7 @@ void zend_set_timeout(zend_long seconds, bool reset_signals) /* {{{ */ EG(timeout_seconds) = seconds; zend_set_timeout_ex(seconds, reset_signals); - zend_atomic_bool_store_ex(&EG(timed_out), false); + atomic_store(&EG(timed_out), false); } /* }}} */ @@ -1706,7 +1706,7 @@ void zend_unset_timeout(void) /* {{{ */ #ifdef ZEND_WIN32 if (NULL != tq_timer) { if (!DeleteTimerQueueTimer(NULL, tq_timer, INVALID_HANDLE_VALUE)) { - zend_atomic_bool_store_ex(&EG(timed_out), false); + atomic_store(&EG(timed_out), false); tq_timer = NULL; zend_error_noreturn(E_ERROR, "Could not delete queued timer"); } @@ -1729,7 +1729,7 @@ void zend_unset_timeout(void) /* {{{ */ # endif } #endif - zend_atomic_bool_store_ex(&EG(timed_out), false); + atomic_store(&EG(timed_out), false); } /* }}} */ diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index b7835ed63226..d74bd8e63447 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -26,7 +26,6 @@ #include "zend_globals_macros.h" -#include "zend_atomic.h" #include "zend_stack.h" #include "zend_ptr_stack.h" #include "zend_hash.h" @@ -223,8 +222,8 @@ struct _zend_executor_globals { bool full_tables_cleanup; - zend_atomic_bool vm_interrupt; - zend_atomic_bool timed_out; + atomic_bool vm_interrupt; + atomic_bool timed_out; HashTable autoload_current_classnames; diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index e6c7ed992b40..2549bacfec3c 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -52,6 +52,23 @@ #include #include +#ifdef __cplusplus +extern "C++" { +# include +/* Make the atomic types used by Zend available to C++ extensions. */ +using std::atomic_bool; +using std::atomic_int; +} +#else +# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L +# error "Zend requires C11 or later" +# endif +# ifdef __STDC_NO_ATOMICS__ +# error "Zend requires C11 atomics" +# endif +# include +#endif + #ifdef HAVE_UNIX_H # include #endif diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index c0fd2eef277b..be69d2624cfd 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -10711,14 +10711,14 @@ ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA); ZEND_VM_HELPER(zend_interrupt_helper, ANY, ANY) { - zend_atomic_bool_store_ex(&EG(vm_interrupt), false); + atomic_store(&EG(vm_interrupt), false); #if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL /* opline is &call_interrupt_op. Load orig opline. */ LOAD_OPLINE(); #else SAVE_OPLINE(); #endif - if (zend_atomic_bool_load_ex(&EG(timed_out))) { + if (atomic_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 b956b638b7e4..5e5677a9f0b1 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4032,14 +4032,14 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_J static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { - zend_atomic_bool_store_ex(&EG(vm_interrupt), false); + atomic_store(&EG(vm_interrupt), false); #if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL /* opline is &call_interrupt_op. Load orig opline. */ LOAD_OPLINE(); #else SAVE_OPLINE(); #endif - if (zend_atomic_bool_load_ex(&EG(timed_out))) { + if (atomic_load(&EG(timed_out))) { zend_timeout(); } else if (zend_interrupt_function) { zend_interrupt_function(execute_data); @@ -56877,14 +56877,14 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_FO static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) { - zend_atomic_bool_store_ex(&EG(vm_interrupt), false); + atomic_store(&EG(vm_interrupt), false); #if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL /* opline is &call_interrupt_op. Load orig opline. */ LOAD_OPLINE(); #else SAVE_OPLINE(); #endif - if (zend_atomic_bool_load_ex(&EG(timed_out))) { + if (atomic_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 50df06a6b479..f48f1e8de90e 100644 --- a/configure.ac +++ b/configure.ac @@ -1757,7 +1757,6 @@ PHP_ADD_SOURCES([Zend], m4_normalize([ zend_alloc.c zend_API.c zend_ast.c - zend_atomic.c zend_attributes.c zend_autoload.c zend_builtin_functions.c diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 45936ba01f48..21c15630bdf8 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -8836,7 +8836,7 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf EX(opline) = opline; } - if (zend_atomic_bool_load_ex(&EG(vm_interrupt)) || JIT_G(tracing)) { + if (atomic_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 38e6c4ae2bc3..69a60c039d8f 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1345,7 +1345,7 @@ static void pcntl_signal_handler(int signo, siginfo_t *siginfo, void *context) PCNTL_G(tail) = psig; PCNTL_G(pending_signals) = true; if (PCNTL_G(async_signals)) { - zend_atomic_bool_store_ex(&EG(vm_interrupt), true); + atomic_store(&EG(vm_interrupt), true); } } @@ -1453,7 +1453,7 @@ void pcntl_signal_dispatch(void) PCNTL_G(tail) = next; if (PCNTL_G(async_signals)) { - zend_atomic_bool_store_ex(&EG(vm_interrupt), true); + atomic_store(&EG(vm_interrupt), true); } } else { PCNTL_G(pending_signals) = false; diff --git a/ext/random/csprng.c b/ext/random/csprng.c index 4c474fb86796..b6333aaea284 100644 --- a/ext/random/csprng.c +++ b/ext/random/csprng.c @@ -24,7 +24,6 @@ #include "php.h" #include "Zend/zend_exceptions.h" -#include "Zend/zend_atomic.h" #include "php_random.h" #include "php_random_csprng.h" @@ -61,7 +60,7 @@ #endif #ifndef PHP_WIN32 -static zend_atomic_int random_fd = ZEND_ATOMIC_INT_INITIALIZER(-1); +static atomic_int random_fd = -1; #endif ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, size_t errstr_size) @@ -146,7 +145,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_random_bytes_ex(void *bytes, size_ } # endif if (read_bytes < size) { - int fd = zend_atomic_int_load_ex(&random_fd); + int fd = atomic_load(&random_fd); struct stat st; if (fd < 0) { @@ -179,7 +178,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_random_bytes_ex(void *bytes, size_ return FAILURE; } int expected = -1; - if (!zend_atomic_int_compare_exchange_ex(&random_fd, &expected, fd)) { + if (!atomic_compare_exchange_strong(&random_fd, &expected, fd)) { close(fd); /* expected is now the actual value of random_fd */ fd = expected; @@ -265,7 +264,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_random_int(zend_long min, zend_lon PHPAPI void php_random_csprng_shutdown(void) { #ifndef PHP_WIN32 - int fd = zend_atomic_int_exchange(&random_fd, -1); + int fd = atomic_exchange(&random_fd, -1); if (fd != -1) { close(fd); } diff --git a/ext/zend_test/object_handlers.c b/ext/zend_test/object_handlers.c index 6b8bf4ab9912..9e78e9fdf524 100644 --- a/ext/zend_test/object_handlers.c +++ b/ext/zend_test/object_handlers.c @@ -250,7 +250,7 @@ static int vm_interrupt_comparable_compare(zval *op1, zval *op2) { ZEND_COMPARE_OBJECTS_FALLBACK(op1, op2); - zend_atomic_bool_store_ex(&EG(vm_interrupt), true); + atomic_store(&EG(vm_interrupt), true); return ZEND_THREEWAY_COMPARE( Z_LVAL_P(OBJ_PROP_NUM(Z_OBJ_P(op1), 0)), diff --git a/ext/zend_test/observer.c b/ext/zend_test/observer.c index 2fd4073b4af0..77ce0cc2525e 100644 --- a/ext/zend_test/observer.c +++ b/ext/zend_test/observer.c @@ -76,7 +76,7 @@ static void observer_begin(zend_execute_data *execute_data) assert_observer_opline(execute_data); if (ZT_G(observer_set_vm_interrupt_on_begin)) { - zend_atomic_bool_store_ex(&EG(vm_interrupt), true); + atomic_store(&EG(vm_interrupt), true); } if (!ZT_G(observer_show_output)) { diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 88afd1b3752e..b879cde43653 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -1652,7 +1652,7 @@ void phpdbg_execute_ex(zend_execute_data *execute_data) /* {{{ */ } #ifdef ZEND_WIN32 - if (zend_atomic_bool_load_ex(&EG(timed_out))) { + if (atomic_load(&EG(timed_out))) { zend_timeout(); } #endif diff --git a/win32/build/config.w32 b/win32/build/config.w32 index f352d4c794aa..253dab653986 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -240,7 +240,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_hrtime.c zend_frameless_function.c zend_property_hooks.c \ + zend_enum.c zend_fibers.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c \ zend_lazy_objects.c zend_autoload.c zend_partial.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"); diff --git a/win32/signal.c b/win32/signal.c index abce3edb2fd1..1cf917d595a0 100644 --- a/win32/signal.c +++ b/win32/signal.c @@ -20,7 +20,7 @@ /* true globals; only used from main thread and from kernel callback */ static zend_fcall_info_cache ctrl_handler; static DWORD ctrl_evt = (DWORD)-1; -static zend_atomic_bool *vm_interrupt_flag = NULL; +static atomic_bool *vm_interrupt_flag = NULL; static void (*orig_interrupt_function)(zend_execute_data *execute_data); @@ -91,7 +91,7 @@ static BOOL WINAPI php_win32_signal_system_ctrl_handler(DWORD evt) return FALSE; } - zend_atomic_bool_store_ex(vm_interrupt_flag, true); + atomic_store(vm_interrupt_flag, true); ctrl_evt = evt;