[tor-commits] [tor/master] Use atomic counters for compressor allocation.

nickm at torproject.org nickm at torproject.org
Tue Apr 25 14:46:31 UTC 2017


commit 4266ec766af8e210ac52f597699b44818960ee39
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Apr 25 10:29:07 2017 -0400

    Use atomic counters for compressor allocation.
---
 src/common/compat_threads.c    | 45 ++++++++++++++++++++++++++++++++++++++++++
 src/common/compat_threads.h    | 14 +++++++++++++
 src/common/compress.c          |  8 ++++++++
 src/common/compress.h          |  2 ++
 src/common/compress_lzma.c     | 13 +++++++++---
 src/common/compress_lzma.h     |  2 ++
 src/common/compress_zlib.c     | 14 +++++++++----
 src/common/compress_zlib.h     |  2 ++
 src/common/compress_zstd.c     | 13 +++++++++---
 src/common/compress_zstd.h     |  2 ++
 src/or/main.c                  |  1 +
 src/test/bench.c               |  1 +
 src/test/fuzz/fuzzing_common.c |  1 +
 src/test/testing_common.c      |  1 +
 14 files changed, 109 insertions(+), 10 deletions(-)

diff --git a/src/common/compat_threads.c b/src/common/compat_threads.c
index 7b28a94..8d026dd 100644
--- a/src/common/compat_threads.c
+++ b/src/common/compat_threads.c
@@ -352,3 +352,48 @@ alert_sockets_close(alert_sockets_t *socks)
   socks->read_fd = socks->write_fd = -1;
 }
 
+/*
+ * XXXX We might be smart to move to compiler intrinsics or real atomic
+ * XXXX operations at some point.  But not yet.
+ *
+ */
+
+/** Initialize a new atomic counter with the value 0 */
+void
+atomic_counter_init(atomic_counter_t *counter)
+{
+  tor_mutex_init_nonrecursive(&counter->mutex);
+  counter->val = 0;
+}
+/** Clean up all resources held by an atomic counter. */
+void
+atomic_counter_destroy(atomic_counter_t *counter)
+{
+  tor_mutex_uninit(&counter->mutex);
+  memset(counter, 0, sizeof(*counter));
+}
+/** Add a value to an atomic counter. */
+void
+atomic_counter_add(atomic_counter_t *counter, size_t add)
+{
+  tor_mutex_acquire(&counter->mutex);
+  counter->val += add;
+  tor_mutex_release(&counter->mutex);
+}
+/** Subtract a value from an atomic counter. */
+void
+atomic_counter_sub(atomic_counter_t *counter, size_t sub)
+{
+  // this relies on unsigned overflow, but that's fine.
+  atomic_counter_add(counter, -sub);
+}
+/** Return the current value of an atomic counter */
+size_t
+atomic_counter_get(atomic_counter_t *counter)
+{
+  size_t val;
+  tor_mutex_acquire(&counter->mutex);
+  val = counter->val;
+  tor_mutex_release(&counter->mutex);
+  return val;
+}
diff --git a/src/common/compat_threads.h b/src/common/compat_threads.h
index 2943573..9fa3d0d 100644
--- a/src/common/compat_threads.h
+++ b/src/common/compat_threads.h
@@ -147,5 +147,19 @@ void *tor_threadlocal_get(tor_threadlocal_t *threadlocal);
  */
 void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value);
 
+/**
+ * Atomic counter type; holds a size_t value.
+ */
+typedef struct atomic_counter_t {
+  tor_mutex_t mutex;
+  size_t val;
+} atomic_counter_t;
+
+void atomic_counter_init(atomic_counter_t *counter);
+void atomic_counter_destroy(atomic_counter_t *counter);
+void atomic_counter_add(atomic_counter_t *counter, size_t add);
+void atomic_counter_sub(atomic_counter_t *counter, size_t sub);
+size_t atomic_counter_get(atomic_counter_t *counter);
+
 #endif
 
diff --git a/src/common/compress.c b/src/common/compress.c
index 38b8184..9332c00 100644
--- a/src/common/compress.c
+++ b/src/common/compress.c
@@ -375,3 +375,11 @@ tor_compress_state_size(const tor_compress_state_t *state)
   return 0;
 }
 
+/** Initialize all compression modules. */
+void
+tor_compress_init(void)
+{
+  tor_zlib_init();
+  tor_lzma_init();
+  tor_zstd_init();
+}
diff --git a/src/common/compress.h b/src/common/compress.h
index 2d812e4..5dd916b 100644
--- a/src/common/compress.h
+++ b/src/common/compress.h
@@ -79,5 +79,7 @@ void tor_compress_free(tor_compress_state_t *state);
 
 size_t tor_compress_state_size(const tor_compress_state_t *state);
 
+void tor_compress_init(void);
+
 #endif // TOR_COMPRESS_H.
 
diff --git a/src/common/compress_lzma.c b/src/common/compress_lzma.c
index ae0327f..b0ba4b6 100644
--- a/src/common/compress_lzma.c
+++ b/src/common/compress_lzma.c
@@ -23,7 +23,7 @@
 #endif
 
 /** Total number of bytes allocated for LZMA state. */
-static size_t total_lzma_allocation = 0;
+static atomic_counter_t total_lzma_allocation;
 
 #ifdef HAVE_LZMA
 /** Given <b>level</b> return the memory level. */
@@ -465,6 +465,7 @@ tor_lzma_compress_new(int compress,
     }
   }
 
+  atomic_counter_add(&total_lzma_allocation, result->allocation);
   return result;
 
  err:
@@ -579,7 +580,7 @@ tor_lzma_compress_free(tor_lzma_compress_state_t *state)
   if (state == NULL)
     return;
 
-  total_lzma_allocation -= state->allocation;
+  atomic_counter_sub(&total_lzma_allocation, state->allocation);
 
 #ifdef HAVE_LZMA
   lzma_end(&state->stream);
@@ -600,6 +601,12 @@ tor_lzma_compress_state_size(const tor_lzma_compress_state_t *state)
 size_t
 tor_lzma_get_total_allocation(void)
 {
-  return total_lzma_allocation;
+  return atomic_counter_get(&total_lzma_allocation);
 }
 
+/** Initialize the lzma module */
+void
+tor_lzma_init(void)
+{
+  atomic_counter_init(&total_lzma_allocation);
+}
diff --git a/src/common/compress_lzma.h b/src/common/compress_lzma.h
index 71de56a..60a5f9c 100644
--- a/src/common/compress_lzma.h
+++ b/src/common/compress_lzma.h
@@ -47,5 +47,7 @@ size_t tor_lzma_compress_state_size(const tor_lzma_compress_state_t *state);
 
 size_t tor_lzma_get_total_allocation(void);
 
+void tor_lzma_init(void);
+
 #endif // TOR_COMPRESS_LZMA_H.
 
diff --git a/src/common/compress_zlib.c b/src/common/compress_zlib.c
index faa179f..5425f20 100644
--- a/src/common/compress_zlib.c
+++ b/src/common/compress_zlib.c
@@ -48,7 +48,7 @@ static size_t tor_zlib_state_size_precalc(int inflate,
                                           int windowbits, int memlevel);
 
 /** Total number of bytes allocated for zlib state */
-static size_t total_zlib_allocation = 0;
+static atomic_counter_t total_zlib_allocation;
 
 /** Given <b>level</b> return the memory level. */
 static int
@@ -437,7 +437,7 @@ tor_zlib_compress_new(int compress_,
   }
   out->allocation = tor_zlib_state_size_precalc(!compress_, bits, memlevel);
 
-  total_zlib_allocation += out->allocation;
+  atomic_counter_add(&total_zlib_allocation, out->allocation);
 
   return out;
 
@@ -519,7 +519,7 @@ tor_zlib_compress_free(tor_zlib_compress_state_t *state)
   if (state == NULL)
     return;
 
-  total_zlib_allocation -= state->allocation;
+  atomic_counter_sub(&total_zlib_allocation, state->allocation);
 
   if (state->compress)
     deflateEnd(&state->stream);
@@ -541,6 +541,12 @@ tor_zlib_compress_state_size(const tor_zlib_compress_state_t *state)
 size_t
 tor_zlib_get_total_allocation(void)
 {
-  return total_zlib_allocation;
+  return atomic_counter_get(&total_zlib_allocation);
 }
 
+/** Set up global state for the zlib module */
+void
+tor_zlib_init(void)
+{
+  atomic_counter_init(&total_zlib_allocation);
+}
diff --git a/src/common/compress_zlib.h b/src/common/compress_zlib.h
index 6e8e5c5..817ca27 100644
--- a/src/common/compress_zlib.h
+++ b/src/common/compress_zlib.h
@@ -47,5 +47,7 @@ size_t tor_zlib_compress_state_size(const tor_zlib_compress_state_t *state);
 
 size_t tor_zlib_get_total_allocation(void);
 
+void tor_zlib_init(void);
+
 #endif // TOR_COMPRESS_ZLIB_H.
 
diff --git a/src/common/compress_zstd.c b/src/common/compress_zstd.c
index 664cce1..8725c10 100644
--- a/src/common/compress_zstd.c
+++ b/src/common/compress_zstd.c
@@ -24,7 +24,7 @@
 #endif
 
 /** Total number of bytes allocated for Zstandard state. */
-static size_t total_zstd_allocation = 0;
+static atomic_counter_t total_zstd_allocation;
 
 #ifdef HAVE_ZSTD
 /** Given <b>level</b> return the memory level. */
@@ -446,6 +446,7 @@ tor_zstd_compress_new(int compress,
     }
   }
 
+  atomic_counter_add(&total_zstd_allocation, result->allocation);
   return result;
 
  err:
@@ -578,7 +579,7 @@ tor_zstd_compress_free(tor_zstd_compress_state_t *state)
   if (state == NULL)
     return;
 
-  total_zstd_allocation -= state->allocation;
+  atomic_counter_sub(&total_zstd_allocation, state->allocation);
 
 #ifdef HAVE_ZSTD
   if (state->compress) {
@@ -604,6 +605,12 @@ tor_zstd_compress_state_size(const tor_zstd_compress_state_t *state)
 size_t
 tor_zstd_get_total_allocation(void)
 {
-  return total_zstd_allocation;
+  return atomic_counter_get(&total_zstd_allocation);
 }
 
+/** Initialize the zstd module */
+void
+tor_zstd_init(void)
+{
+  atomic_counter_init(&total_zstd_allocation);
+}
diff --git a/src/common/compress_zstd.h b/src/common/compress_zstd.h
index 663cbdd..186dc3b 100644
--- a/src/common/compress_zstd.h
+++ b/src/common/compress_zstd.h
@@ -47,5 +47,7 @@ size_t tor_zstd_compress_state_size(const tor_zstd_compress_state_t *state);
 
 size_t tor_zstd_get_total_allocation(void);
 
+void tor_zstd_init(void);
+
 #endif // TOR_COMPRESS_ZSTD_H.
 
diff --git a/src/or/main.c b/src/or/main.c
index 1ba6554..5fec7e4 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -3616,6 +3616,7 @@ tor_main(int argc, char *argv[])
 
   update_approx_time(time(NULL));
   tor_threads_init();
+  tor_compress_init();
   init_logging(0);
   monotime_init();
 #ifdef USE_DMALLOC
diff --git a/src/test/bench.c b/src/test/bench.c
index 5da9168..a44dc94 100644
--- a/src/test/bench.c
+++ b/src/test/bench.c
@@ -674,6 +674,7 @@ main(int argc, const char **argv)
   or_options_t *options;
 
   tor_threads_init();
+  tor_compress_init();
 
   if (argc == 4 && !strcmp(argv[1], "diff")) {
     init_logging(1);
diff --git a/src/test/fuzz/fuzzing_common.c b/src/test/fuzz/fuzzing_common.c
index f540176..7aee92d 100644
--- a/src/test/fuzz/fuzzing_common.c
+++ b/src/test/fuzz/fuzzing_common.c
@@ -96,6 +96,7 @@ static void
 global_init(void)
 {
   tor_threads_init();
+  tor_compress_init();
   {
     struct sipkey sipkey = { 1337, 7331 };
     siphash_set_global_key(&sipkey);
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
index 0e37e0d..d3dc761 100644
--- a/src/test/testing_common.c
+++ b/src/test/testing_common.c
@@ -245,6 +245,7 @@ main(int c, const char **v)
   update_approx_time(time(NULL));
   options = options_new();
   tor_threads_init();
+  tor_compress_init();
 
   network_init();
 





More information about the tor-commits mailing list