gdtoa-misc.c.patch [plain text]
--- gdtoa-misc.c.orig 2010-01-12 10:59:42.000000000 -0800
+++ gdtoa-misc.c 2010-01-12 12:08:17.000000000 -0800
@@ -29,9 +29,20 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
+#define GDTOA_TSD
+#define Omit_Private_Memory
+
+#ifdef GDTOA_TSD
+#include <pthread.h>
+#endif /* GDTOA_TSD */
#include "gdtoaimp.h"
+#ifdef GDTOA_TSD
+static pthread_key_t gdtoa_tsd_key = (pthread_key_t)-1;
+static pthread_mutex_t gdtoa_tsd_lock = PTHREAD_MUTEX_INITIALIZER;
+#else /* !GDTOA_TSD */
static Bigint *freelist[Kmax+1];
+#endif /* GDTOA_TSD */
#ifndef Omit_Private_Memory
#ifndef PRIVATE_MEM
#define PRIVATE_MEM 2304
@@ -40,6 +51,26 @@ THIS SOFTWARE.
static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
#endif
+#ifdef GDTOA_TSD
+static void
+gdtoa_freelist_free(void *x)
+{
+ int i;
+ Bigint *cur, *next;
+ Bigint **fl = (Bigint **)x;
+
+ if (!fl) return;
+ for(i = 0; i < Kmax+1; fl++, i++) {
+ if (!*fl) continue;
+ for(cur = *fl; cur; cur = next) {
+ next = cur->next;
+ free(cur);
+ }
+ }
+ free(x);
+ }
+#endif /* GDTOA_TSD */
+
Bigint *
Balloc
#ifdef KR_headers
@@ -53,8 +84,25 @@ Balloc
#ifndef Omit_Private_Memory
unsigned int len;
#endif
+#ifdef GDTOA_TSD
+ Bigint **freelist;
+ if (gdtoa_tsd_key == (pthread_key_t)-1) {
+ pthread_mutex_lock(&gdtoa_tsd_lock);
+ if (gdtoa_tsd_key == (pthread_key_t)-1) {
+ gdtoa_tsd_key = __LIBC_PTHREAD_KEY_GDTOA_BIGINT;
+ pthread_key_init_np(gdtoa_tsd_key, gdtoa_freelist_free);
+ }
+ pthread_mutex_unlock(&gdtoa_tsd_lock);
+ }
+ if ((freelist = (Bigint **)pthread_getspecific(gdtoa_tsd_key)) == NULL) {
+ freelist = (Bigint **)MALLOC((Kmax+1) * sizeof(Bigint *));
+ bzero(freelist, (Kmax+1) * sizeof(Bigint *));
+ pthread_setspecific(gdtoa_tsd_key, freelist);
+ }
+#else /* !GDTOA_TSD */
ACQUIRE_DTOA_LOCK(0);
+#endif /* GDTOA_TSD */
/* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
/* but this case seems very unlikely. */
if (k <= Kmax && (rv = freelist[k]) !=0) {
@@ -77,7 +125,9 @@ Balloc
rv->k = k;
rv->maxwds = x;
}
+#ifndef GDTOA_TSD
FREE_DTOA_LOCK(0);
+#endif /* GDTOA_TSD */
rv->sign = rv->wds = 0;
return rv;
}
@@ -98,10 +148,16 @@ Bfree
free((void*)v);
#endif
else {
+#ifdef GDTOA_TSD
+ Bigint **freelist = (Bigint **)pthread_getspecific(gdtoa_tsd_key);
+#else /* !GDTOA_TSD */
ACQUIRE_DTOA_LOCK(0);
+#endif /* !GDTOA_TSD */
v->next = freelist[v->k];
freelist[v->k] = v;
+#ifndef GDTOA_TSD
FREE_DTOA_LOCK(0);
+#endif /* !GDTOA_TSD */
}
}
}