diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-05-24 17:12:57 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-05-24 17:12:57 +0000 |
commit | d3d86b17a761011f62dc2e06c04c0af8f1a75ef6 (patch) | |
tree | efb329c2d77ef6f39c02db8db62bfa18ad5f4d6d /src/common/util.c | |
parent | d0a5c4f9848f44c46f001428bd3078673033ef19 (diff) | |
download | tor-d3d86b17a761011f62dc2e06c04c0af8f1a75ef6.tar.gz tor-d3d86b17a761011f62dc2e06c04c0af8f1a75ef6.zip |
r12916@catbus: nickm | 2007-05-24 12:43:45 -0400
Add math functions to round values to the nearest power of 2. Make mempools more careful about making sure that the size of their chunks is a little less than a power of 2, not a little more.
svn:r10304
Diffstat (limited to 'src/common/util.c')
-rw-r--r-- | src/common/util.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/common/util.c b/src/common/util.c index d4a30a1459..7ca08363d0 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -214,6 +214,54 @@ _tor_free(void *mem) } /* ===== + * Math + * ===== */ + +/** Returns floor(log2(u64)). If u64 is 0, (incorrectly) returns 0. */ +int +tor_log2(uint64_t u64) +{ + int r = 0; + if (u64 >= (U64_LITERAL(1)<<32)) { + u64 >>= 32; + r = 32; + } + if (u64 >= (U64_LITERAL(1)<<16)) { + u64 >>= 16; + r += 16; + } + if (u64 >= (U64_LITERAL(1)<<8)) { + u64 >>= 8; + r += 8; + } + if (u64 >= (U64_LITERAL(1)<<4)) { + u64 >>= 4; + r += 4; + } + if (u64 >= (U64_LITERAL(1)<<2)) { + u64 >>= 2; + r += 2; + } + if (u64 >= (U64_LITERAL(1)<<1)) { + u64 >>= 1; + r += 1; + } + return r; +} + +/** Return the power of 2 closest to <b>u64</b>. */ +uint64_t +round_to_power_of_2(uint64_t u64) +{ + int lg2 = tor_log2(u64); + uint64_t low = U64_LITERAL(1) << lg2, high = U64_LITERAL(1) << (lg2+1); + if (high - u64 < u64 - low) + return high; + else + return low; +} + +/* ===== * String manipulation * ===== */ |