Commit d3d86b17 authored by Nick Mathewson's avatar Nick Mathewson 🥔
Browse files

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
parent d0a5c4f9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ Things we'd like to do in 0.2.0.x:
        - Push/pull documents as appropriate.
        o Have clients know which authorities are v3 authorities, and what
          their keys are.
          - While we're at it, let v3 authorities have fqdns lines.
      - Start caching consensus documents once authorities make them
      - Start downloading and using consensus documents once caches serve them
    . 104: Long and Short Router Descriptors (by Jun 1)
+2 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
#if defined(__GNUC__) && __GNUC__ >= 3
#define ATTR_NORETURN __attribute__((noreturn))
#define ATTR_PURE __attribute__((pure))
#define ATTR_CONST __attribute__((const))
#define ATTR_MALLOC __attribute__((malloc))
#define ATTR_NORETURN __attribute__((noreturn))
#define ATTR_NONNULL(x) __attribute__((nonnull x))
@@ -108,6 +109,7 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
#else
#define ATTR_NORETURN
#define ATTR_PURE
#define ATTR_CONST
#define ATTR_MALLOC
#define ATTR_NORETURN
#define ATTR_NONNULL(x)
+10 −4
Original line number Diff line number Diff line
@@ -361,18 +361,24 @@ mp_pool_new(size_t item_size, size_t chunk_capacity)
  /* Now we figure out how many items fit in each chunk.  We need to fit at
   * least 2 items per chunk. No chunk can be more than MAX_CHUNK bytes long,
   * or less than MIN_CHUNK. */
  /* XXXX020 Try a bit harder here: we want to be a bit less than a power of
     2, not a bit over. */
  if (chunk_capacity > MAX_CHUNK)
    chunk_capacity = MAX_CHUNK;
  if (chunk_capacity < alloc_size * 2 + CHUNK_OVERHEAD)
    chunk_capacity = alloc_size * 2 + CHUNK_OVERHEAD;
  /* Try to be around a power of 2 in size, since that's what allocators like
   * handing out. 512K-1 byte is a lot better than 512K+1 byte. */
  chunk_capacity = (size_t) round_to_power_of_2(chunk_capacity);
  while (chunk_capacity < alloc_size * 2 + CHUNK_OVERHEAD)
    chunk_capacity *= 2;
  if (chunk_capacity < MIN_CHUNK)
    chunk_capacity = MIN_CHUNK;

  pool->new_chunk_capacity = (chunk_capacity-CHUNK_OVERHEAD) / alloc_size;
  pool->item_alloc_size = alloc_size;

  log_debug(LD_MM, "Capacity is %lu, item size is %lu, alloc size is %lu",
            (unsigned long)pool->new_chunk_capacity,
            (unsigned long)pool->item_alloc_size,
            (unsigned long)(pool->new_chunk_capacity*pool->item_alloc_size));

  return pool;
}

+48 −0
Original line number Diff line number Diff line
@@ -213,6 +213,54 @@ _tor_free(void *mem)
  tor_free(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
 * ===== */
+4 −0
Original line number Diff line number Diff line
@@ -142,6 +142,10 @@ extern int dmalloc_free(const char *file, const int line, void *pnt,
/** Macro: true if two values have different boolean values. */
#define bool_neq(a,b) (!(a)!=!(b))

/* Math functions */
int tor_log2(uint64_t u64) ATTR_CONST;
uint64_t round_to_power_of_2(uint64_t u64);

/* String manipulation */

/** Allowable characters in a hexadecimal string. */
Loading