php-src/Zend/zend_strtod.h
Arnaud Le Blanc 9bbc195d11
Remove zend_strtod mutex (#13974)
`zend_strtod.c` uses a global state (mostly an allocation freelist) protected by a mutex in ZTS builds. This state is used by `zend_dtoa()`, `zend_strtod()`, and variants. This creates a lot of contention in concurrent loads. `zend_dtoa()` is used to format floats to string, e.g. in sprintf, json_encode, serialize, uniqid.

Here I move the global state to the thread specific `executor_globals` and remove the mutex.

The impact on non-concurrent environments is null or negligible, but there is a considerable speed up on concurrent environments, especially on Alpine/Musl.
2024-04-23 11:52:38 +02:00

52 lines
2.3 KiB
C

/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Derick Rethans <derick@php.net> |
+----------------------------------------------------------------------+
*/
/* This is a header file for the strtod implementation by David M. Gay which
* can be found in zend_strtod.c */
#ifndef ZEND_STRTOD_H
#define ZEND_STRTOD_H
#include <zend.h>
BEGIN_EXTERN_C()
#define ZEND_STRTOD_K_MAX 7
typedef struct _zend_strtod_bigint zend_strtod_bigint;
typedef struct _zend_strtod_state {
zend_strtod_bigint *freelist[ZEND_STRTOD_K_MAX+1];
zend_strtod_bigint *p5s;
char *result;
} zend_strtod_state;
ZEND_API void zend_freedtoa(char *s);
ZEND_API char *zend_dtoa(double _d, int mode, int ndigits, int *decpt, bool *sign, char **rve);
ZEND_API char *zend_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf);
ZEND_API double zend_strtod(const char *s00, const char **se);
ZEND_API double zend_hex_strtod(const char *str, const char **endptr);
ZEND_API double zend_oct_strtod(const char *str, const char **endptr);
ZEND_API double zend_bin_strtod(const char *str, const char **endptr);
ZEND_API int zend_shutdown_strtod(void);
END_EXTERN_C()
/* double limits */
#include <float.h>
#if defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP)
#define ZEND_DOUBLE_MAX_LENGTH (3 + DBL_MANT_DIG - DBL_MIN_EXP)
#else
#define ZEND_DOUBLE_MAX_LENGTH 1080
#endif
#endif