diff options
| author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2025-09-10 00:26:56 +0900 |
|---|---|---|
| committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2025-09-10 15:34:30 +0900 |
| commit | d0c966adcd8cd04830e75c6b720c0c38427b3419 (patch) | |
| tree | b193e6b6f7a90cd0cbdc8b954b6e2488c10d7c6b /missing | |
| parent | 0887d82406c9a9701acd235e8f510480cea9f218 (diff) | |
dtoa.c: Extract macro to update 5powers Bigint cache atomically
Diffstat (limited to 'missing')
| -rw-r--r-- | missing/dtoa.c | 45 |
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; |
