summaryrefslogtreecommitdiff
path: root/missing
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2025-09-10 00:26:56 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2025-09-10 15:34:30 +0900
commitd0c966adcd8cd04830e75c6b720c0c38427b3419 (patch)
treeb193e6b6f7a90cd0cbdc8b954b6e2488c10d7c6b /missing
parent0887d82406c9a9701acd235e8f510480cea9f218 (diff)
dtoa.c: Extract macro to update 5powers Bigint cache atomically
Diffstat (limited to 'missing')
-rw-r--r--missing/dtoa.c45
1 files changed, 17 insertions, 28 deletions
diff --git a/missing/dtoa.c b/missing/dtoa.c
index 4d266ecf12..b37a13451d 100644
--- a/missing/dtoa.c
+++ b/missing/dtoa.c
@@ -815,29 +815,30 @@ static Bigint *
pow5mult(Bigint *b, int k)
{
Bigint *b1, *p5, *p51;
- Bigint *p5tmp;
int i;
static const int p05[3] = { 5, 25, 125 };
if ((i = k & 3) != 0)
b = multadd(b, p05[i-1], 0);
+#define b_cache(var, addr, new_expr) \
+ if ((var = addr) != 0) {} else { \
+ Bigint *tmp = 0; \
+ ACQUIRE_DTOA_LOCK(1); \
+ if (!(var = addr) && (var = (new_expr)) != 0) { \
+ var->next = 0; \
+ tmp = ATOMIC_PTR_CAS(addr, NULL, var); \
+ } \
+ FREE_DTOA_LOCK(1); \
+ if (UNLIKELY(tmp)) { \
+ Bfree(var); \
+ var = tmp; \
+ } \
+ }
if (!(k >>= 2))
return b;
- if (!(p5 = p5s)) {
- /* first time */
- ACQUIRE_DTOA_LOCK(1);
- if (!(p5 = p5s)) {
- p5 = i2b(625);
- p5->next = 0;
- p5tmp = ATOMIC_PTR_CAS(p5s, NULL, p5);
- if (UNLIKELY(p5tmp)) {
- Bfree(p5);
- p5 = p5tmp;
- }
- }
- FREE_DTOA_LOCK(1);
- }
+ /* first time */
+ b_cache(p5, p5s, i2b(625));
for (;;) {
if (k & 1) {
b1 = mult(b, p5);
@@ -846,19 +847,7 @@ pow5mult(Bigint *b, int k)
}
if (!(k >>= 1))
break;
- if (!(p51 = p5->next)) {
- ACQUIRE_DTOA_LOCK(1);
- if (!(p51 = p5->next)) {
- p51 = mult(p5,p5);
- p51->next = 0;
- p5tmp = ATOMIC_PTR_CAS(p5->next, NULL, p51);
- if (UNLIKELY(p5tmp)) {
- Bfree(p51);
- p51 = p5tmp;
- }
- }
- FREE_DTOA_LOCK(1);
- }
+ b_cache(p51, p5->next, mult(p5, p5));
p5 = p51;
}
return b;