commit b0c1cae18066d0103a440894b5256939852021eb
parent f18ad18729afc971ea77e73869f8fb99da30c701
Author: Mattias Andrée <maandree@kth.se>
Date: Tue, 1 Mar 2016 18:37:05 +0100
Add zsetup, zunsetup, zinit, zfree, zswap, zsave, zload, zbits, and zlsb
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
11 files changed, 189 insertions(+), 0 deletions(-)
diff --git a/TODO b/TODO
@@ -0,0 +1 @@
+Allocations shall be cached.
diff --git a/src/internals.h b/src/internals.h
@@ -0,0 +1,30 @@
+/* See LICENSE file for copyright and license details. */
+#include "../zahl.h"
+
+#define BITS_PER_CHAR 32
+#define FLOOR_BITS_TO_CHARS(bits) ((bits) >> 5)
+#define CEILING_BITS_TO_CHARS(bits) (((bits) + (BITS_PER_CHAR - 1)) >> 5)
+#define BITS_IN_LAST_CHAR(bits) ((bits) & (BITS_PER_CHAR - 1))
+
+#define LIST_TEMPS\
+ X(libzahl_tmp_a)\
+ X(libzahl_tmp_b)\
+ X(libzahl_tmp_c)\
+ X(libzahl_tmp_d)\
+ X(libzahl_tmp_e)\
+ X(libzahl_tmp_f)\
+ X(libzahl_tmp_g)\
+ X(libzahl_tmp_i)\
+ X(libzahl_tmp_j)\
+ X(libzahl_tmp_k)\
+ X(libzahl_tmp_l)\
+ X(libzahl_tmp_m)
+
+#define X(x) extern z_t x;
+LIST_TEMPS
+#undef X
+
+extern jmp_buf libzahl_jmp_buf;
+extern int libzahl_set_up;
+
+#define FAILURE_JUMP() (longjmp(libzahl_jmp_buf, 1))
diff --git a/src/zbits.c b/src/zbits.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+
+size_t
+zbits(z_t a)
+{
+ size_t i;
+ uint32_t x;
+ if (zzero(a)) {
+ return 1;
+ }
+ for (i = a->used - 1;; i--) {
+ x = a->chars[i];
+ if (x) {
+ a->used = i + 1;
+ for (i *= BITS_PER_CHAR; x; x >>= 1, i++);
+ return i;
+ }
+ }
+}
diff --git a/src/zfree.c b/src/zfree.c
@@ -0,0 +1,13 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+#include <stdlib.h>
+
+
+void
+zfree(z_t a)
+{
+ free(a->chars);
+ a->alloced = 0;
+ a->chars = 0;
+}
diff --git a/src/zinit.c b/src/zinit.c
@@ -0,0 +1,10 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+
+void
+zinit(z_t a)
+{
+ a->alloced = 0;
+ a->chars = 0;
+}
diff --git a/src/zload.c b/src/zload.c
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+size_t
+zload(z_t a, const void *buffer)
+{
+ const char *buf = buffer;
+ a->sign = *((int *)buf), buf += sizeof(int);
+ a->used = *((size_t *)buf), buf += sizeof(size_t);
+ a->alloced = *((size_t *)buf), buf += sizeof(size_t);
+ if (a->alloced) {
+ a->chars = realloc(a->chars, a->alloced * sizeof(*(a->chars)));
+ } else {
+ a->chars = 0;
+ }
+ if (a->sign) {
+ memcpy(a->chars, buf, a->used * sizeof(*(a->chars)));
+ }
+ return sizeof(z_t) - sizeof(a->chars) + (a->sign ? a->used * sizeof(*(a->chars)) : 0);
+}
diff --git a/src/zlsb.c b/src/zlsb.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+
+size_t
+zlsb(z_t a)
+{
+ size_t i = 0;
+ uint32_t x;
+ if (zzero(a)) {
+ return SIZE_MAX;
+ }
+ for (;; i++) {
+ x = a->chars[i];
+ if (x) {
+ x = ~x;
+ for (i *= BITS_PER_CHAR; x & 1; x >>= 1, i++);
+ return i;
+ }
+ }
+}
diff --git a/src/zsave.c b/src/zsave.c
@@ -0,0 +1,20 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+#include <string.h>
+
+
+size_t
+zsave(z_t a, void *buffer)
+{
+ if (buffer) {
+ char *buf = buffer;
+ *((int *)buf) = a->sign, buf += sizeof(int);
+ *((size_t *)buf) = a->used, buf += sizeof(size_t);
+ *((size_t *)buf) = a->alloced, buf += sizeof(size_t);
+ if (a->sign) {
+ memcpy(buf, a->chars, a->used * sizeof(*(a->chars)));
+ }
+ }
+ return sizeof(z_t) - sizeof(a->chars) + (a->sign ? a->used * sizeof(*(a->chars)) : 0);
+}
diff --git a/src/zsetup.c b/src/zsetup.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+#define X(x) z_t x;
+LIST_TEMPS
+#undef X
+
+jmp_buf libzahl_jmp_buf;
+int libzahl_set_up = 0;
+
+
+void
+zsetup(jmp_buf env)
+{
+ libzahl_jmp_buf = jmp_buf;
+
+ if (!libzahl_set_up) {
+ libzahl_set_up = 1;
+#define X(x) zinit(zahl_tmp_##x);
+ LIST_TEMPS;
+#undef X
+ }
+}
diff --git a/src/zswap.c b/src/zswap.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+
+void
+zswap(z_t a, z_t b)
+{
+ z_t t;
+ *t = *a;
+ *a = *b;
+ *b = t;
+}
diff --git a/src/zunsetup.c b/src/zunsetup.c
@@ -0,0 +1,14 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+
+void
+zunsetup(jmp_buf env)
+{
+ if (libzahl_set_up) {
+ libzahl_set_up = 0;
+#define X(x) zfree(zahl_tmp_##x);
+ LIST_TEMPS;
+#undef X
+ }
+}