summaryrefslogtreecommitdiffstats
path: root/src/jv_dtoa_tsd.c
diff options
context:
space:
mode:
authorLeonid S. Usov <leonid@practi.net>2018-10-19 21:57:41 +0300
committerWilliam Langford <wlangfor@gmail.com>2019-10-22 14:11:04 -0400
commitcf4b48c7ba30cb30e116b523cff036ea481459f6 (patch)
treeb6d5a0ed3286e77d7d1fb84e8bec3c33686dd96e /src/jv_dtoa_tsd.c
parentb6be13d5de6dd7d8aad5fd871eb6b0b30fc7d7f6 (diff)
Save literal value of the parsed number to preserve it for the output
Extend jv_number to use decNumber for storing number literals. Any math operations on the numbers will truncate them to double precision. Comparisons when both numbers are literal numbers will compare them without truncation. Delay conversion of numbers to doubles until a math operation is performed, to preserve precision. A literal jv_number will only need conversion to double once, and will reuse the resultant double on subsequent conversions. Outputting literal jv_numbers preserves the original precision. Add strong pthread requirement to manage contexts/allocations for converting numbers between their decNumber, string, and double formats.
Diffstat (limited to 'src/jv_dtoa_tsd.c')
-rw-r--r--src/jv_dtoa_tsd.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/jv_dtoa_tsd.c b/src/jv_dtoa_tsd.c
new file mode 100644
index 00000000..0f95df4f
--- /dev/null
+++ b/src/jv_dtoa_tsd.c
@@ -0,0 +1,46 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#include "jv_dtoa_tsd.h"
+#include "jv_dtoa.h"
+#include "jv_alloc.h"
+
+
+static pthread_key_t dtoa_ctx_key;
+static pthread_once_t dtoa_ctx_once = PTHREAD_ONCE_INIT;
+
+static void tsd_dtoa_ctx_dtor(struct dtoa_context *ctx) {
+ if (ctx) {
+ jvp_dtoa_context_free(ctx);
+ jv_mem_free(ctx);
+ }
+}
+
+static void tsd_dtoa_ctx_fini() {
+ struct dtoa_context *ctx = pthread_getspecific(dtoa_ctx_key);
+ tsd_dtoa_ctx_dtor(ctx);
+ pthread_setspecific(dtoa_ctx_key, NULL);
+}
+
+static void tsd_dtoa_ctx_init() {
+ if (pthread_key_create(&dtoa_ctx_key, tsd_dtoa_ctx_dtor) != 0) {
+ fprintf(stderr, "error: cannot create thread specific key");
+ abort();
+ }
+ atexit(tsd_dtoa_ctx_fini);
+}
+
+inline struct dtoa_context *tsd_dtoa_context_get() {
+ pthread_once(&dtoa_ctx_once, tsd_dtoa_ctx_init); // cannot fail
+ struct dtoa_context *ctx = (struct dtoa_context*)pthread_getspecific(dtoa_ctx_key);
+ if (!ctx) {
+ ctx = malloc(sizeof(struct dtoa_context));
+ jvp_dtoa_context_init(ctx);
+ if (pthread_setspecific(dtoa_ctx_key, ctx) != 0) {
+ fprintf(stderr, "error: cannot set thread specific data");
+ abort();
+ }
+ }
+ return ctx;
+} \ No newline at end of file