diff options
Diffstat (limited to 'missing')
-rw-r--r-- | missing/dtoa.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/missing/dtoa.c b/missing/dtoa.c index 41b0a221d1..a940eabd91 100644 --- a/missing/dtoa.c +++ b/missing/dtoa.c @@ -526,6 +526,8 @@ typedef struct Bigint Bigint; static Bigint *freelist[Kmax+1]; +#define BLOCKING_BIGINT ((Bigint *)(-1)) + static Bigint * Balloc(int k) { @@ -541,8 +543,10 @@ Balloc(int k) rv = freelist[k]; while (rv) { Bigint *rvn = rv; - rv = ATOMIC_PTR_CAS(freelist[k], rv, rv->next); - if (LIKELY(rvn == rv)) { + rv = ATOMIC_PTR_CAS(freelist[k], rv, BLOCKING_BIGINT); + if (LIKELY(rv != BLOCKING_BIGINT && rvn == rv)) { + rvn = ATOMIC_PTR_CAS(freelist[k], BLOCKING_BIGINT, rv->next); + assert(rvn == BLOCKING_BIGINT); ASSUME(rv); break; } @@ -589,7 +593,10 @@ Bfree(Bigint *v) } ACQUIRE_DTOA_LOCK(0); do { - vn = v->next = freelist[v->k]; + do { + vn = ATOMIC_PTR_CAS(freelist[v->k], 0, 0); + } while (UNLIKELY(vn == BLOCKING_BIGINT)); + v->next = vn; } while (UNLIKELY(ATOMIC_PTR_CAS(freelist[v->k], vn, v) != vn)); FREE_DTOA_LOCK(0); } |