summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/strtod.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/stdlib/strtod.c')
-rw-r--r--src/lib/libc/stdlib/strtod.c106
1 files changed, 75 insertions, 31 deletions
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
index a8a52e02c5..253bc4ddc0 100644
--- a/src/lib/libc/stdlib/strtod.c
+++ b/src/lib/libc/stdlib/strtod.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: strtod.c,v 1.28 2006/10/13 03:50:14 deraadt Exp $ */ 1/* $OpenBSD: strtod.c,v 1.29 2006/10/29 18:45:56 deraadt Exp $ */
2/**************************************************************** 2/****************************************************************
3 * 3 *
4 * The author of this software is David M. Gay. 4 * The author of this software is David M. Gay.
@@ -125,6 +125,11 @@
125#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} 125#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
126#endif 126#endif
127 127
128#include "thread_private.h"
129
130_THREAD_PRIVATE_KEY(dtoa);
131_THREAD_PRIVATE_KEY(pow5mult);
132
128#ifdef __cplusplus 133#ifdef __cplusplus
129#include "malloc.h" 134#include "malloc.h"
130#include "memory.h" 135#include "memory.h"
@@ -365,21 +370,35 @@ Bigint {
365 370
366 static Bigint *freelist[Kmax+1]; 371 static Bigint *freelist[Kmax+1];
367 372
373#define PRIVATE_MEM 2304
374#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
375 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
376
368 static Bigint * 377 static Bigint *
369Balloc(int k) 378Balloc(int k)
370{ 379{
371 int x; 380 int x;
381 unsigned int len;
372 Bigint *rv; 382 Bigint *rv;
373 383
384 _THREAD_PRIVATE_MUTEX_LOCK(dtoa);
374 if ((rv = freelist[k])) { 385 if ((rv = freelist[k])) {
375 freelist[k] = rv->next; 386 freelist[k] = rv->next;
376 } 387 }
377 else { 388 else {
378 x = 1 << k; 389 x = 1 << k;
379 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)); 390 len = (sizeof(Bigint) + (x-1)*sizeof(Long) + sizeof(double) - 1)
391 /sizeof(double);
392 if (pmem_next - private_mem + len <= PRIVATE_mem) {
393 rv = (Bigint *)pmem_next;
394 pmem_next += len;
395 }
396 else
397 rv = (Bigint *)MALLOC(len *sizeof(double));
380 rv->k = k; 398 rv->k = k;
381 rv->maxwds = x; 399 rv->maxwds = x;
382 } 400 }
401 _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa);
383 rv->sign = rv->wds = 0; 402 rv->sign = rv->wds = 0;
384 return rv; 403 return rv;
385 } 404 }
@@ -388,14 +407,55 @@ Balloc(int k)
388Bfree(Bigint *v) 407Bfree(Bigint *v)
389{ 408{
390 if (v) { 409 if (v) {
410 _THREAD_PRIVATE_MUTEX_LOCK(dtoa);
391 v->next = freelist[v->k]; 411 v->next = freelist[v->k];
392 freelist[v->k] = v; 412 freelist[v->k] = v;
413 _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa);
393 } 414 }
394 } 415 }
395 416
396#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ 417#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
397y->wds*sizeof(Long) + 2*sizeof(int)) 418y->wds*sizeof(Long) + 2*sizeof(int))
398 419
420/* return value is only used as a simple string, so mis-aligned parts
421 * inside the Bigint are not at risk on strict align architectures
422 */
423 static char *
424rv_alloc(int i)
425{
426 int j, k, *r;
427
428 j = sizeof(ULong);
429 for(k = 0;
430 sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
431 j <<= 1)
432 k++;
433 r = (int*)Balloc(k);
434 *r = k;
435 return (char *)(r+1);
436 }
437
438 static char *
439nrv_alloc(char *s, char **rve, int n)
440{
441 char *rv, *t;
442
443 t = rv = rv_alloc(n);
444 while((*t = *s++) !=0)
445 t++;
446 if (rve)
447 *rve = t;
448 return rv;
449 }
450
451 void
452__freedtoa(char *s)
453{
454 Bigint *b = (Bigint *)((int *)s - 1);
455 b->maxwds = 1 << (b->k = *(int*)b);
456 Bfree(b);
457 }
458
399 static Bigint * 459 static Bigint *
400multadd(Bigint *b, int m, int a) /* multiply by m and add a */ 460multadd(Bigint *b, int m, int a) /* multiply by m and add a */
401{ 461{
@@ -651,8 +711,10 @@ pow5mult(Bigint *b, int k)
651 return b; 711 return b;
652 if (!(p5 = p5s)) { 712 if (!(p5 = p5s)) {
653 /* first time */ 713 /* first time */
714 _THREAD_PRIVATE_MUTEX_LOCK(pow5mult);
654 p5 = p5s = i2b(625); 715 p5 = p5s = i2b(625);
655 p5->next = 0; 716 p5->next = 0;
717 _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult);
656 } 718 }
657 for(;;) { 719 for(;;) {
658 if (k & 1) { 720 if (k & 1) {
@@ -663,8 +725,12 @@ pow5mult(Bigint *b, int k)
663 if (!(k >>= 1)) 725 if (!(k >>= 1))
664 break; 726 break;
665 if (!(p51 = p5->next)) { 727 if (!(p51 = p5->next)) {
666 p51 = p5->next = mult(p5,p5); 728 _THREAD_PRIVATE_MUTEX_LOCK(pow5mult);
667 p51->next = 0; 729 if (!(p51 = p5->next)) {
730 p51 = p5->next = mult(p5,p5);
731 p51->next = 0;
732 }
733 _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult);
668 } 734 }
669 p5 = p51; 735 p5 = p51;
670 } 736 }
@@ -1848,17 +1914,9 @@ __dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1848 Bigint *b, *b1, *delta, *mlo, *mhi, *S; 1914 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1849 double ds; 1915 double ds;
1850 char *s, *s0; 1916 char *s, *s0;
1851 static Bigint *result;
1852 static int result_k;
1853 _double d, d2, eps; 1917 _double d, d2, eps;
1854 1918
1855 value(d) = _d; 1919 value(d) = _d;
1856 if (result) {
1857 result->k = result_k;
1858 result->maxwds = 1 << result_k;
1859 Bfree(result);
1860 result = 0;
1861 }
1862 1920
1863 if (word0(d) & Sign_bit) { 1921 if (word0(d) & Sign_bit) {
1864 /* set sign for everything, including 0's and NaNs */ 1922 /* set sign for everything, including 0's and NaNs */
@@ -1877,18 +1935,11 @@ __dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1877 { 1935 {
1878 /* Infinity or NaN */ 1936 /* Infinity or NaN */
1879 *decpt = 9999; 1937 *decpt = 9999;
1880 s =
1881#ifdef IEEE_Arith 1938#ifdef IEEE_Arith
1882 !word1(d) && !(word0(d) & 0xfffff) ? ndigits < 8 ? "Inf" : "Infinity" : 1939 if (!word1(d) && !(word0(d) & 0xfffff))
1940 return nrv_alloc("Infinity", rve, 8);
1883#endif 1941#endif
1884 "NaN"; 1942 return nrv_alloc("NaN", rve, 3);
1885 if (rve)
1886 *rve =
1887#ifdef IEEE_Arith
1888 s[3] ? s + 8 :
1889#endif
1890 s + 3;
1891 return s;
1892 } 1943 }
1893#endif 1944#endif
1894#ifdef IBM 1945#ifdef IBM
@@ -1896,10 +1947,7 @@ __dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1896#endif 1947#endif
1897 if (!value(d)) { 1948 if (!value(d)) {
1898 *decpt = 1; 1949 *decpt = 1;
1899 s = "0"; 1950 return nrv_alloc("0", rve, 1);
1900 if (rve)
1901 *rve = s + 1;
1902 return s;
1903 } 1951 }
1904 1952
1905 b = d2b(value(d), &be, &bbits); 1953 b = d2b(value(d), &be, &bbits);
@@ -2021,11 +2069,7 @@ __dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
2021 if (i <= 0) 2069 if (i <= 0)
2022 i = 1; 2070 i = 1;
2023 } 2071 }
2024 j = sizeof(ULong); 2072 s = s0 = rv_alloc(i);
2025 for(result_k = 0; sizeof(Bigint) - sizeof(ULong) + j <= i;
2026 j <<= 1) result_k++;
2027 result = Balloc(result_k);
2028 s = s0 = (char *)result;
2029 2073
2030 if (ilim >= 0 && ilim <= Quick_max && try_quick) { 2074 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2031 2075