diff --git a/build-static.sh b/build-static.sh index b36309faac..798ff19fb2 100755 --- a/build-static.sh +++ b/build-static.sh @@ -195,6 +195,9 @@ if [ -n "${COMPRESS}" ] && [ -z "${DEBUG_SYMBOLS}" ] && [ "${os}" = "linux" ]; t SPC_OPT_INSTALL_ARGS="${SPC_OPT_INSTALL_ARGS} upx" fi +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 SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="${SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS} -fPIE -g" 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` diff --git a/frankenphp.c b/frankenphp.c index f665b214f1..99e95bbc9e 100644 --- a/frankenphp.c +++ b/frankenphp.c @@ -98,13 +98,19 @@ 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 + +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 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 @@ -112,7 +118,7 @@ __thread HashTable *prepared_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"