From d95477c0c58d96fd059e670e387b4f2e33cafebe Mon Sep 17 00:00:00 2001 From: henderkes Date: Wed, 8 Jul 2026 19:08:11 +0700 Subject: [PATCH 1/4] minimal native tls optimization --- build-static.sh | 2 ++ frankenphp.c | 14 ++++++++++---- go.sh | 2 +- mtls-cflags.sh | 6 ++++++ 4 files changed, 19 insertions(+), 5 deletions(-) create mode 100755 mtls-cflags.sh diff --git a/build-static.sh b/build-static.sh index b36309faac..2b1c6930b5 100755 --- a/build-static.sh +++ b/build-static.sh @@ -195,6 +195,8 @@ if [ -n "${COMPRESS}" ] && [ -z "${DEBUG_SYMBOLS}" ] && [ "${os}" = "linux" ]; t SPC_OPT_INSTALL_ARGS="${SPC_OPT_INSTALL_ARGS} upx" fi +export CGO_CFLAGS="${CGO_CFLAGS} $(sh "${CURRENT_DIR}/mtls-cflags.sh")" + export SPC_DEFAULT_C_FLAGS="-fPIC -O2" if [ -n "${DEBUG_SYMBOLS}" ]; then SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="${SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS} -fPIE -g" diff --git a/frankenphp.c b/frankenphp.c index 1b852e52c7..011171c5b6 100644 --- a/frankenphp.c +++ b/frankenphp.c @@ -98,9 +98,15 @@ bool original_user_abort_setting = 0; frankenphp_interned_strings_t frankenphp_strings = {0}; HashTable *main_thread_env = NULL; -__thread uintptr_t thread_index; -__thread bool is_worker_thread = false; -__thread HashTable *sandboxed_env = NULL; +#if defined(__ELF__) && defined(__GNUC__) +#define THREAD_LOCAL __thread __attribute__((tls_model("local-exec"))) +#else +#define THREAD_LOCAL __thread +#endif + +THREAD_LOCAL uintptr_t thread_index; +THREAD_LOCAL bool is_worker_thread = false; +THREAD_LOCAL HashTable *sandboxed_env = NULL; /* Published via SG(server_context) so ext-parallel children, which inherit * the parent's SG(server_context), can route SAPI callbacks back to the @@ -108,7 +114,7 @@ __thread HashTable *sandboxed_env = NULL; typedef struct { uintptr_t thread_index; } frankenphp_server_ctx; -static __thread frankenphp_server_ctx frankenphp_local_server_ctx; +static THREAD_LOCAL frankenphp_server_ctx frankenphp_local_server_ctx; static inline uintptr_t frankenphp_thread_index(void) { frankenphp_server_ctx *ctx = (frankenphp_server_ctx *)SG(server_context); diff --git a/go.sh b/go.sh index 2f8775ddca..a1172206aa 100755 --- a/go.sh +++ b/go.sh @@ -2,6 +2,6 @@ # Runs the go command with the proper Go and cgo flags. GOFLAGS="$GOFLAGS -tags=nobadger,nomysql,nopgx" \ - CGO_CFLAGS="$CGO_CFLAGS $(php-config --includes)" \ + CGO_CFLAGS="$CGO_CFLAGS $(php-config --includes) $(sh "$(dirname "$0")/mtls-cflags.sh")" \ CGO_LDFLAGS="$CGO_LDFLAGS $(php-config --ldflags) $(php-config --libs)" \ go "$@" diff --git a/mtls-cflags.sh b/mtls-cflags.sh new file mode 100755 index 0000000000..1bd5413786 --- /dev/null +++ b/mtls-cflags.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# Prints -mtls-size=12 if the toolchain compiles and links local-exec TLS with it (excludes non-AArch64 and ld.lld). +d="$(mktemp -d)" || exit 0 +printf '__thread __attribute__((tls_model("local-exec"))) int v;\nint main(void){v=1;return v;}\n' >"$d/p.c" +"${CC:-cc}" -O2 -mtls-size=12 "$d/p.c" -o "$d/p" >/dev/null 2>&1 && printf -- -mtls-size=12 +rm -rf "$d" From 704a3b6d9d39d3d1a5871b28b4b89ea8c05d3a0b Mon Sep 17 00:00:00 2001 From: henderkes Date: Wed, 8 Jul 2026 19:08:22 +0700 Subject: [PATCH 2/4] fix incorrect performance doc --- docs/performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/performance.md b/docs/performance.md index 50ac6f8a5b..b884d045e5 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -18,7 +18,7 @@ We strongly recommend changing these values. For best system stability, it is re To find the right values, it's best to run load tests simulating real traffic. [k6](https://k6.io) and [Gatling](https://gatling.io) are good tools for this. -To configure the number of threads, use the `num_threads` option of the `php_server` and `php` directives. +To configure the number of threads, use the `num_threads` option of the global `frankenphp` directive. To change the number of workers, use the `num` option of the `worker` section of the `frankenphp` directive. ### `max_threads` From 88165a733f13364840a8ead4ef9a605da023689b Mon Sep 17 00:00:00 2001 From: henderkes Date: Wed, 8 Jul 2026 19:14:20 +0700 Subject: [PATCH 3/4] mark others static too (there are no external users... yet?) --- frankenphp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frankenphp.c b/frankenphp.c index 2886741173..99e95bbc9e 100644 --- a/frankenphp.c +++ b/frankenphp.c @@ -104,13 +104,13 @@ HashTable *main_thread_env = NULL; #define THREAD_LOCAL __thread #endif -THREAD_LOCAL uintptr_t thread_index; -THREAD_LOCAL bool is_worker_thread = false; -THREAD_LOCAL HashTable *sandboxed_env = NULL; +static THREAD_LOCAL uintptr_t thread_index; +static THREAD_LOCAL bool is_worker_thread = false; +static THREAD_LOCAL HashTable *sandboxed_env = NULL; /* prepared_env holds entries from php(_server)'s `env KEY VAL`, exposed to * getenv() and merged into $_ENV when 'E' is in variables_order. Separate from * putenv() so those don't leak into $_ENV. */ -THREAD_LOCAL HashTable *prepared_env = NULL; +static THREAD_LOCAL HashTable *prepared_env = NULL; /* Published via SG(server_context) so ext-parallel children, which inherit * the parent's SG(server_context), can route SAPI callbacks back to the From 6db1b020cd81946c27d5f17638af23ae4c4897f2 Mon Sep 17 00:00:00 2001 From: henderkes Date: Wed, 8 Jul 2026 20:46:43 +0700 Subject: [PATCH 4/4] lint --- build-static.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build-static.sh b/build-static.sh index 2b1c6930b5..798ff19fb2 100755 --- a/build-static.sh +++ b/build-static.sh @@ -195,7 +195,8 @@ if [ -n "${COMPRESS}" ] && [ -z "${DEBUG_SYMBOLS}" ] && [ "${os}" = "linux" ]; t SPC_OPT_INSTALL_ARGS="${SPC_OPT_INSTALL_ARGS} upx" fi -export CGO_CFLAGS="${CGO_CFLAGS} $(sh "${CURRENT_DIR}/mtls-cflags.sh")" +MTLS_CFLAGS="$(sh "${CURRENT_DIR}/mtls-cflags.sh")" +export CGO_CFLAGS="${CGO_CFLAGS} ${MTLS_CFLAGS}" export SPC_DEFAULT_C_FLAGS="-fPIC -O2" if [ -n "${DEBUG_SYMBOLS}" ]; then