Skip to content

Commit f44fe35

Browse files
committed
perf: use nl_langinfo for the decimal point on glibc ZTS instead of mutex-protected localeconv
1 parent aaa141a commit f44fe35

5 files changed

Lines changed: 33 additions & 31 deletions

File tree

ext/standard/formatted_print.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
#include <locale.h>
2020
#ifdef ZTS
21-
#include "ext/standard/php_string.h" /* for localeconv_r() */
22-
#define LCONV_DECIMAL_POINT (*lconv.decimal_point)
21+
#include "ext/standard/php_string.h" /* for localeconv_decimal_point() */
22+
#define LCONV_DECIMAL_POINT localeconv_decimal_point()
2323
#else
2424
#define LCONV_DECIMAL_POINT (*lconv->decimal_point)
2525
#endif
@@ -221,9 +221,7 @@ php_sprintf_appenddouble(zend_string **buffer, size_t *pos,
221221
char *s = NULL;
222222
size_t s_len = 0;
223223
bool is_negative = false;
224-
#ifdef ZTS
225-
struct lconv lconv;
226-
#else
224+
#ifndef ZTS
227225
struct lconv *lconv;
228226
#endif
229227

@@ -256,9 +254,7 @@ php_sprintf_appenddouble(zend_string **buffer, size_t *pos,
256254
case 'E':
257255
case 'f':
258256
case 'F':
259-
#ifdef ZTS
260-
localeconv_r(&lconv);
261-
#else
257+
#ifndef ZTS
262258
lconv = localeconv();
263259
#endif
264260
s = php_conv_fp((fmt == 'f')?'F':fmt, number, 0, precision,
@@ -285,9 +281,7 @@ php_sprintf_appenddouble(zend_string **buffer, size_t *pos,
285281

286282
char decimal_point = '.';
287283
if (fmt == 'g' || fmt == 'G') {
288-
#ifdef ZTS
289-
localeconv_r(&lconv);
290-
#else
284+
#ifndef ZTS
291285
lconv = localeconv();
292286
#endif
293287
decimal_point = LCONV_DECIMAL_POINT;

ext/standard/php_string.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ PHP_MINIT_FUNCTION(string_intrin);
3232
strnatcmp_ex(a, strlen(a), b, strlen(b), true)
3333
PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, bool is_case_insensitive);
3434
PHPAPI struct lconv *localeconv_r(struct lconv *out);
35+
#ifdef ZTS
36+
PHPAPI char localeconv_decimal_point(void);
37+
#endif
3538
PHPAPI char *php_strtr(char *str, size_t len, const char *str_from, const char *str_to, size_t trlen);
3639
PHPAPI zend_string *php_addslashes(zend_string *str);
3740
PHPAPI void php_stripslashes(zend_string *str);

ext/standard/string.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#include "php_string.h"
2020
#include "php_variables.h"
2121
#include <locale.h>
22+
#ifdef HAVE_NL_LANGINFO
23+
# include <langinfo.h>
24+
#endif
2225
#ifdef HAVE_LANGINFO_H
2326
# include <langinfo.h>
2427
#endif
@@ -88,6 +91,20 @@ static zend_string *php_hex2bin(const unsigned char *old, const size_t oldlen)
8891
}
8992
/* }}} */
9093

94+
#ifdef ZTS
95+
/* read the decimal point through nl_langinfo() (thread-safe), instead of taking the lock. */
96+
PHPAPI char localeconv_decimal_point(void)
97+
{
98+
#if defined(HAVE_NL_LANGINFO) && (defined(__GLIBC__) || defined(__MUSL__))
99+
return *nl_langinfo(RADIXCHAR);
100+
#else
101+
struct lconv lc;
102+
localeconv_r(&lc);
103+
return *lc.decimal_point;
104+
#endif
105+
}
106+
#endif
107+
91108
/* {{{ localeconv_r
92109
* glibc's localeconv is not reentrant, so lets make it so ... sorta */
93110
PHPAPI struct lconv *localeconv_r(struct lconv *out)

main/snprintf.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include <locale.h>
3131
#ifdef ZTS
3232
#include "ext/standard/php_string.h"
33-
#define LCONV_DECIMAL_POINT (*lconv.decimal_point)
33+
#define LCONV_DECIMAL_POINT localeconv_decimal_point()
3434
#else
3535
#define LCONV_DECIMAL_POINT (*lconv->decimal_point)
3636
#endif
@@ -491,9 +491,7 @@ static size_t format_converter(buffy * odp, const char *fmt, va_list ap) /* {{{
491491
char num_buf[NUM_BUF_SIZE];
492492
char char_buf[2]; /* for printing %% and %<unknown> */
493493

494-
#ifdef ZTS
495-
struct lconv lconv;
496-
#else
494+
#ifndef ZTS
497495
struct lconv *lconv = NULL;
498496
#endif
499497

@@ -843,9 +841,7 @@ static size_t format_converter(buffy * odp, const char *fmt, va_list ap) /* {{{
843841
s = "INF";
844842
s_len = 3;
845843
} else {
846-
#ifdef ZTS
847-
localeconv_r(&lconv);
848-
#else
844+
#ifndef ZTS
849845
if (!lconv) {
850846
lconv = localeconv();
851847
}
@@ -902,9 +898,7 @@ static size_t format_converter(buffy * odp, const char *fmt, va_list ap) /* {{{
902898
/*
903899
* * We use &num_buf[ 1 ], so that we have room for the sign
904900
*/
905-
#ifdef ZTS
906-
localeconv_r(&lconv);
907-
#else
901+
#ifndef ZTS
908902
if (!lconv) {
909903
lconv = localeconv();
910904
}

main/spprintf.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
#include <locale.h>
8989
#ifdef ZTS
9090
#include "ext/standard/php_string.h"
91-
#define LCONV_DECIMAL_POINT (*lconv.decimal_point)
91+
#define LCONV_DECIMAL_POINT localeconv_decimal_point()
9292
#else
9393
#define LCONV_DECIMAL_POINT (*lconv->decimal_point)
9494
#endif
@@ -196,9 +196,7 @@ static void xbuf_format_converter(void *xbuf, bool is_char, const char *fmt, va_
196196
char num_buf[NUM_BUF_SIZE];
197197
char char_buf[2]; /* for printing %% and %<unknown> */
198198

199-
#ifdef ZTS
200-
struct lconv lconv;
201-
#else
199+
#ifndef ZTS
202200
struct lconv *lconv = NULL;
203201
#endif
204202

@@ -556,9 +554,7 @@ static void xbuf_format_converter(void *xbuf, bool is_char, const char *fmt, va_
556554
s = "inf";
557555
s_len = 3;
558556
} else {
559-
#ifdef ZTS
560-
localeconv_r(&lconv);
561-
#else
557+
#ifndef ZTS
562558
if (!lconv) {
563559
lconv = localeconv();
564560
}
@@ -614,9 +610,7 @@ static void xbuf_format_converter(void *xbuf, bool is_char, const char *fmt, va_
614610
/*
615611
* * We use &num_buf[ 1 ], so that we have room for the sign
616612
*/
617-
#ifdef ZTS
618-
localeconv_r(&lconv);
619-
#else
613+
#ifndef ZTS
620614
if (!lconv) {
621615
lconv = localeconv();
622616
}

0 commit comments

Comments
 (0)