Remove spinlock in dtoa's Balloc, use xmalloc
The spinlock here performs poorly when there are multiple Ractors. The improvement on single threaded performance doesn't seem that significant, so I think we should just use malloc.
This commit is contained in:
parent
4646ab8917
commit
b3b1d7b295
Notes:
git
2025-04-07 23:57:00 +00:00
@ -98,17 +98,6 @@
|
||||
* if memory is available and otherwise does something you deem
|
||||
* appropriate. If MALLOC is undefined, malloc will be invoked
|
||||
* directly -- and assumed always to succeed.
|
||||
* #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
|
||||
* memory allocations from a private pool of memory when possible.
|
||||
* When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes,
|
||||
* unless #defined to be a different length. This default length
|
||||
* suffices to get rid of MALLOC calls except for unusual cases,
|
||||
* such as decimal-to-binary conversion of a very long string of
|
||||
* digits. The longest string dtoa can return is about 751 bytes
|
||||
* long. For conversions by strtod of strings of 800 digits and
|
||||
* all dtoa conversions in single-threaded executions with 8-byte
|
||||
* pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte
|
||||
* pointers, PRIVATE_MEM >= 7112 appears adequate.
|
||||
* #define INFNAN_CHECK on IEEE systems to cause strtod to check for
|
||||
* Infinity and NaN (case insensitively). On some systems (e.g.,
|
||||
* some HP systems), it may be necessary to #define NAN_WORD0
|
||||
@ -235,14 +224,6 @@ extern void FREE(void*);
|
||||
#define NO_SANITIZE(x, y) y
|
||||
#endif
|
||||
|
||||
#ifndef Omit_Private_Memory
|
||||
#ifndef PRIVATE_MEM
|
||||
#define PRIVATE_MEM 2304
|
||||
#endif
|
||||
#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
|
||||
static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
|
||||
#endif
|
||||
|
||||
#undef IEEE_Arith
|
||||
#undef Avoid_Underflow
|
||||
#ifdef IEEE_BIG_ENDIAN
|
||||
@ -527,60 +508,16 @@ struct Bigint {
|
||||
|
||||
typedef struct Bigint Bigint;
|
||||
|
||||
static Bigint *freelist[Kmax+1];
|
||||
|
||||
#define BLOCKING_BIGINT ((Bigint *)(-1))
|
||||
|
||||
static Bigint *
|
||||
Balloc(int k)
|
||||
{
|
||||
int x;
|
||||
Bigint *rv;
|
||||
#ifndef Omit_Private_Memory
|
||||
size_t len;
|
||||
#endif
|
||||
|
||||
rv = 0;
|
||||
ACQUIRE_DTOA_LOCK(0);
|
||||
if (k <= Kmax) {
|
||||
rv = freelist[k];
|
||||
while (rv) {
|
||||
Bigint *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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!rv) {
|
||||
x = 1 << k;
|
||||
#ifdef Omit_Private_Memory
|
||||
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||
#else
|
||||
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
|
||||
/sizeof(double);
|
||||
if (k <= Kmax) {
|
||||
double *pnext = pmem_next;
|
||||
while (pnext - private_mem + len <= PRIVATE_mem) {
|
||||
double *p = pnext;
|
||||
pnext = ATOMIC_PTR_CAS(pmem_next, pnext, pnext + len);
|
||||
if (LIKELY(p == pnext)) {
|
||||
rv = (Bigint*)pnext;
|
||||
ASSUME(rv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!rv)
|
||||
rv = (Bigint*)MALLOC(len*sizeof(double));
|
||||
#endif
|
||||
rv->k = k;
|
||||
rv->maxwds = x;
|
||||
}
|
||||
FREE_DTOA_LOCK(0);
|
||||
x = 1 << k;
|
||||
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||
rv->k = k;
|
||||
rv->maxwds = x;
|
||||
rv->sign = rv->wds = 0;
|
||||
return rv;
|
||||
}
|
||||
@ -588,21 +525,7 @@ Balloc(int k)
|
||||
static void
|
||||
Bfree(Bigint *v)
|
||||
{
|
||||
Bigint *vn;
|
||||
if (v) {
|
||||
if (v->k > Kmax) {
|
||||
FREE(v);
|
||||
return;
|
||||
}
|
||||
ACQUIRE_DTOA_LOCK(0);
|
||||
do {
|
||||
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);
|
||||
}
|
||||
FREE(v);
|
||||
}
|
||||
|
||||
#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \
|
||||
|
Loading…
x
Reference in New Issue
Block a user