gdtoa-misc.c.patch   [plain text]


--- gdtoa-misc.c.orig	2010-01-07 22:03:21.000000000 -0800
+++ gdtoa-misc.c	2010-01-07 22:25:33.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,9 +84,26 @@ 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);
-	if ( (rv = freelist[k]) !=0) {
+#endif /* GDTOA_TSD */
+	if (k <= Kmax && (rv = freelist[k]) !=0) {
 		freelist[k] = rv->next;
 		}
 	else {
@@ -65,7 +113,7 @@ Balloc
 #else
 		len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
 			/sizeof(double);
-		if (pmem_next - private_mem + len <= PRIVATE_mem) {
+		if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
 			rv = (Bigint*)pmem_next;
 			pmem_next += len;
 			}
@@ -75,7 +123,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;
 	}
@@ -89,10 +139,20 @@ Bfree
 #endif
 {
 	if (v) {
-		ACQUIRE_DTOA_LOCK(0);
-		v->next = freelist[v->k];
-		freelist[v->k] = v;
-		FREE_DTOA_LOCK(0);
+		if (v->k > Kmax)
+			free((void*)v);
+		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 */
+			}
 		}
 	}