commit 4266ec766af8e210ac52f597699b44818960ee39 Author: Nick Mathewson nickm@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();