(wrong string) ée

From: <git_AT_suckless.org>
Date: Tue, 26 Apr 2016 22:40:59 +0200 (CEST)

commit 3413d878a7b1a37ff362ddfa9141349e73af917a
Author: Mattias Andrée <maandree_AT_kth.se>
AuthorDate: Tue Apr 26 22:40:43 2016 +0200
Commit: Mattias Andrée <maandree_AT_kth.se>
CommitDate: Tue Apr 26 22:40:43 2016 +0200

    Ensure that failure does not result in memory leak
    
    Signed-off-by: Mattias Andrée <maandree_AT_kth.se>

diff --git a/src/internals.h b/src/internals.h
index bfe2e6f..3ee7bd3 100644
--- a/src/internals.h
+++ b/src/internals.h
_AT_@ -89,11 +89,13 @@ extern int libzahl_error;
 extern zahl_char_t **libzahl_pool[sizeof(size_t) * 8];
 extern size_t libzahl_pool_n[sizeof(size_t) * 8];
 extern size_t libzahl_pool_alloc[sizeof(size_t) * 8];
+extern struct zahl **libzahl_temp_stack;
+extern struct zahl **libzahl_temp_stack_head;
+extern struct zahl **libzahl_temp_stack_end;
 
 #define likely(expr) ZAHL_LIKELY(expr)
 #define unlikely(expr) ZAHL_UNLIKELY(expr)
 
-#define libzahl_failure(error) (libzahl_error = (error), longjmp(libzahl_jmp_buf, 1))
 #define SET_SIGNUM(a, signum) ZAHL_SET_SIGNUM(a, signum)
 #define SET(a, b) ZAHL_SET(a, b)
 #define ENSURE_SIZE(a, n) do { if ((a)->alloced < (n)) libzahl_realloc(a, (n)); } while (0)
_AT_@ -117,6 +119,16 @@ void libzahl_realloc(z_t a, size_t need);
 void zmul_impl(z_t a, z_t b, z_t c);
 void zsqr_impl(z_t a, z_t b);
 
+static void
+libzahl_failure(int error)
+{
+ libzahl_error = (error);
+ if (libzahl_temp_stack)
+ while (libzahl_temp_stack_head != libzahl_temp_stack)
+ zfree(*--libzahl_temp_stack_head);
+ longjmp(libzahl_jmp_buf, 1);
+}
+
 static inline void
 zmemcpy(zahl_char_t *restrict d, const zahl_char_t *restrict s, register size_t n)
 {
_AT_@ -272,3 +284,54 @@ zsplit_unsigned_fast_small_auto(z_t high, z_t low, z_t a, size_t n)
         if (unlikely(!low->chars[0]))
                 low->sign = 0;
 }
+
+/* Calls to these functions must be called in stack-order
+ * For example,
+ *
+ * zinit_temp(a);
+ * zinit_temp(b);
+ * zfree_temp(b);
+ * zinit_temp(c);
+ * zfree_temp(c);
+ * zfree_temp(a);
+ *
+ *
+ * And not (swap the two last lines)
+ *
+ * zinit_temp(a);
+ * zinit_temp(b);
+ * zfree_temp(b);
+ * zinit_temp(c);
+ * zfree_temp(a);
+ * zfree_temp(c);
+ *
+ * { */
+
+static inline void
+zinit_temp(z_t a)
+{
+ zinit(a);
+ if (unlikely(libzahl_temp_stack_head == libzahl_temp_stack_end)) {
+ size_t n = (size_t)(libzahl_temp_stack_end - libzahl_temp_stack);
+ void* old = libzahl_temp_stack;
+ libzahl_temp_stack = realloc(old, 2 * n * sizeof(*libzahl_temp_stack));
+ if (unlikely(!libzahl_temp_stack)) {
+ libzahl_temp_stack = old;
+ if (!errno) /* sigh... */
+ errno = ENOMEM;
+ libzahl_failure(errno);
+ }
+ libzahl_temp_stack_head = libzahl_temp_stack + n;
+ libzahl_temp_stack_end = libzahl_temp_stack_head + n;
+ }
+ *libzahl_temp_stack_head++ = a;
+}
+
+static inline void
+zfree_temp(z_t a)
+{
+ zfree(a);
+ libzahl_temp_stack_head--;
+}
+
+/* } */
diff --git a/src/zmul.c b/src/zmul.c
index 6633edd..6ea6d21 100644
--- a/src/zmul.c
+++ b/src/zmul.c
_AT_@ -48,10 +48,10 @@ zmul_impl(z_t a, z_t b, z_t c)
         m = MAX(m, m2);
         m2 = m >> 1;
 
- zinit(b_high);
- zinit(b_low);
- zinit(c_high);
- zinit(c_low);
+ zinit_temp(b_high);
+ zinit_temp(b_low);
+ zinit_temp(c_high);
+ zinit_temp(c_low);
 
         zsplit(b_high, b_low, b, m2);
         zsplit(c_high, c_low, c, m2);
_AT_@ -73,10 +73,10 @@ zmul_impl(z_t a, z_t b, z_t c)
         zadd_unsigned_assign(a, z2);
 
 
- zfree(b_high);
- zfree(b_low);
- zfree(c_high);
- zfree(c_low);
+ zfree_temp(c_low);
+ zfree_temp(c_high);
+ zfree_temp(b_low);
+ zfree_temp(b_high);
 }
 
 void
diff --git a/src/zsetup.c b/src/zsetup.c
index 10fc5f5..e36bff3 100644
--- a/src/zsetup.c
+++ b/src/zsetup.c
_AT_@ -15,6 +15,9 @@ int libzahl_error;
 zahl_char_t **libzahl_pool[sizeof(size_t) * 8];
 size_t libzahl_pool_n[sizeof(size_t) * 8];
 size_t libzahl_pool_alloc[sizeof(size_t) * 8];
+struct zahl **libzahl_temp_stack;
+struct zahl **libzahl_temp_stack_head;
+struct zahl **libzahl_temp_stack_end;
 
 
 void
_AT_@ -23,7 +26,7 @@ zsetup(jmp_buf env)
         size_t i;
         *libzahl_jmp_buf = *env;
 
- if (!libzahl_set_up) {
+ if (likely(!libzahl_set_up)) {
                 libzahl_set_up = 1;
 
                 memset(libzahl_pool, 0, sizeof(libzahl_pool));
_AT_@ -40,5 +43,14 @@ zsetup(jmp_buf env)
 #undef X
                 for (i = BITS_PER_CHAR; i--;)
                         zinit(libzahl_tmp_divmod_ds[i]);
+
+ libzahl_temp_stack = malloc(256 * sizeof(*libzahl_temp_stack));
+ if (unlikely(!libzahl_temp_stack)) {
+ if (!errno) /* sigh... */
+ errno = ENOMEM;
+ libzahl_failure(errno);
+ }
+ libzahl_temp_stack_head = libzahl_temp_stack;
+ libzahl_temp_stack_end = libzahl_temp_stack + 256;
         }
 }
diff --git a/src/zsqr.c b/src/zsqr.c
index 0b0ff67..5d99229 100644
--- a/src/zsqr.c
+++ b/src/zsqr.c
_AT_@ -50,8 +50,8 @@ zsqr_impl(z_t a, z_t b)
                 zsqr_impl(z2, high);
                 zlsh(a, z2, bits << 1);
         } else {
- zinit(z0);
- zinit(z1);
+ zinit_temp(z0);
+ zinit_temp(z1);
 
                 zsqr_impl(z0, low);
 
_AT_@ -64,8 +64,8 @@ zsqr_impl(z_t a, z_t b)
                 zadd_unsigned_assign(a, z1);
                 zadd_unsigned_assign(a, z0);
 
- zfree(z0);
- zfree(z1);
+ zfree_temp(z1);
+ zfree_temp(z0);
         }
 }
 
diff --git a/src/zunsetup.c b/src/zunsetup.c
index ba84dd7..48ee9e3 100644
--- a/src/zunsetup.c
+++ b/src/zunsetup.c
_AT_@ -24,5 +24,7 @@ zunsetup(void)
                                 free(libzahl_pool[i][libzahl_pool_n[i]]);
                         free(libzahl_pool[i]);
                 }
+
+ free(libzahl_temp_stack);
         }
 }
diff --git a/zahl-internals.h b/zahl-internals.h
index 9ac29b2..9d6df24 100644
--- a/zahl-internals.h
+++ b/zahl-internals.h
_AT_@ -62,3 +62,13 @@
 
 
 typedef uint64_t zahl_char_t;
+
+struct zahl {
+ int sign;
+#if INT_MAX != LONG_MAX
+ int padding__;
+#endif
+ size_t used;
+ size_t alloced;
+ zahl_char_t *chars;
+};
diff --git a/zahl.h b/zahl.h
index 2df05e7..aca34f4 100644
--- a/zahl.h
+++ b/zahl.h
_AT_@ -16,16 +16,7 @@
 
 
 
-/* This structure should be considered opaque. */
-typedef struct {
- int sign;
-#if INT_MAX != LONG_MAX
- int padding__;
-#endif
- size_t used;
- size_t alloced;
- zahl_char_t *chars;
-} z_t[1];
+typedef struct zahl z_t[1];
 
 
 
Received on Tue Apr 26 2016 - 22:40:59 CEST

This archive was generated by hypermail 2.3.0 : Tue Apr 26 2016 - 22:48:15 CEST