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
|
* if memory is available and otherwise does something you deem
|
||||||
* appropriate. If MALLOC is undefined, malloc will be invoked
|
* appropriate. If MALLOC is undefined, malloc will be invoked
|
||||||
* directly -- and assumed always to succeed.
|
* 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
|
* #define INFNAN_CHECK on IEEE systems to cause strtod to check for
|
||||||
* Infinity and NaN (case insensitively). On some systems (e.g.,
|
* Infinity and NaN (case insensitively). On some systems (e.g.,
|
||||||
* some HP systems), it may be necessary to #define NAN_WORD0
|
* 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
|
#define NO_SANITIZE(x, y) y
|
||||||
#endif
|
#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 IEEE_Arith
|
||||||
#undef Avoid_Underflow
|
#undef Avoid_Underflow
|
||||||
#ifdef IEEE_BIG_ENDIAN
|
#ifdef IEEE_BIG_ENDIAN
|
||||||
@ -527,60 +508,16 @@ struct Bigint {
|
|||||||
|
|
||||||
typedef struct Bigint Bigint;
|
typedef struct Bigint Bigint;
|
||||||
|
|
||||||
static Bigint *freelist[Kmax+1];
|
|
||||||
|
|
||||||
#define BLOCKING_BIGINT ((Bigint *)(-1))
|
|
||||||
|
|
||||||
static Bigint *
|
static Bigint *
|
||||||
Balloc(int k)
|
Balloc(int k)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
Bigint *rv;
|
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;
|
x = 1 << k;
|
||||||
#ifdef Omit_Private_Memory
|
|
||||||
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
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->k = k;
|
||||||
rv->maxwds = x;
|
rv->maxwds = x;
|
||||||
}
|
|
||||||
FREE_DTOA_LOCK(0);
|
|
||||||
rv->sign = rv->wds = 0;
|
rv->sign = rv->wds = 0;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -588,21 +525,7 @@ Balloc(int k)
|
|||||||
static void
|
static void
|
||||||
Bfree(Bigint *v)
|
Bfree(Bigint *v)
|
||||||
{
|
{
|
||||||
Bigint *vn;
|
|
||||||
if (v) {
|
|
||||||
if (v->k > Kmax) {
|
|
||||||
FREE(v);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \
|
#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user