Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | --- 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 */ } } } |