[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r17161: {tor} Document some dmalloc stuff and some stupid C tricks. (tor/trunk/src/common)



Author: nickm
Date: 2008-10-27 12:30:52 -0400 (Mon, 27 Oct 2008)
New Revision: 17161

Modified:
   tor/trunk/src/common/compat.h
   tor/trunk/src/common/util.c
   tor/trunk/src/common/util.h
Log:
Document some dmalloc stuff and some  stupid C tricks.

Modified: tor/trunk/src/common/compat.h
===================================================================
--- tor/trunk/src/common/compat.h	2008-10-27 15:04:45 UTC (rev 17160)
+++ tor/trunk/src/common/compat.h	2008-10-27 16:30:52 UTC (rev 17161)
@@ -137,10 +137,20 @@
 #define ATTR_NONNULL(x)
 
 /** Macro: Evaluates to <b>exp</b> and hints the compiler that the value
- * of <b>exp</b> will probably be true. */
+ * of <b>exp</b> will probably be true.
+ *
+ * In other words, "if (PREDICT_LIKELY(foo))" is the same as "if (foo)",
+ * except that it tells the compiler that the branch will be taken most of the
+ * time.  This can generate slightly better code with some CPUs.
+ */
 #define PREDICT_LIKELY(exp) __builtin_expect((exp), 1)
 /** Macro: Evaluates to <b>exp</b> and hints the compiler that the value
- * of <b>exp</b> will probably be false. */
+ * of <b>exp</b> will probably be false.
+ *
+ * In other words, "if (PREDICT_UNLIKELY(foo))" is the same as "if (foo)",
+ * except that it tells the compiler that the branch will usually not be
+ * taken.  This can generate slightly better code with some CPUs.
+ */
 #define PREDICT_UNLIKELY(exp) __builtin_expect((exp), 0)
 #else
 #define ATTR_NORETURN
@@ -153,9 +163,12 @@
 #define PREDICT_UNLIKELY(exp) (exp)
 #endif
 
-/* Ways to declare macros. */
+/** Expands to a syntactically valid empty statement.  */
 #define STMT_NIL (void)0
+
 #ifdef __GNUC__
+/** STMT_BEGIN and STMT_END are used to wrap blocks inside macros so that
+ * the macro can be used as if it were a single C statement. */
 #define STMT_BEGIN (void) ({
 #define STMT_END })
 #elif defined(sun) || defined(__sun__)
@@ -180,8 +193,13 @@
 #endif
 
 #ifdef _MSC_VER
+/** Casts the uint64_t value in <b>a</b> to the right type for an argument
+ * to printf. */
 #define U64_PRINTF_ARG(a) (a)
+/** Casts the uint64_t* value in <b>a</b> to the right type for an argument
+ * to scanf. */
 #define U64_SCANF_ARG(a) (a)
+/** Expands to a literal uint64_t-typed constant for the value <b>n</b>. */
 #define U64_LITERAL(n) (n ## ui64)
 #else
 #define U64_PRINTF_ARG(a) ((long long unsigned int)(a))
@@ -190,6 +208,8 @@
 #endif
 
 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
+/** The formatting string used to put a uint64_t value in a printf() or
+ * scanf() function.  See also U64_PRINTF_ARG and U64_SCANF_ARG. */
 #define U64_FORMAT "%I64u"
 #else
 #define U64_FORMAT "%llu"
@@ -220,6 +240,9 @@
   return tor_memmem(haystack, hlen, needle, strlen(needle));
 }
 
+/* This cast-to-uchar, then-cast-to-int business is needed to compile and
+ * run properly on some Solarises. */
+
 #define TOR_ISALPHA(c)   isalpha((int)(unsigned char)(c))
 #define TOR_ISALNUM(c)   isalnum((int)(unsigned char)(c))
 #define TOR_ISSPACE(c)   isspace((int)(unsigned char)(c))

Modified: tor/trunk/src/common/util.c
===================================================================
--- tor/trunk/src/common/util.c	2008-10-27 15:04:45 UTC (rev 17160)
+++ tor/trunk/src/common/util.c	2008-10-27 16:30:52 UTC (rev 17161)
@@ -83,6 +83,7 @@
 #ifdef USE_DMALLOC
  #undef strndup
  #include <dmalloc.h>
+ /* Macro to pass the extra dmalloc args to another function. */
  #define DMALLOC_FN_ARGS , file, line
 
  #if defined(HAVE_DMALLOC_STRDUP)
@@ -95,9 +96,7 @@
  #endif
 
 #else /* not using dmalloc */
- #define DMALLOC_FUNC_MALLOC 0
 
- #define DMALLOC_FUNC_REALLOC 0
  #define DMALLOC_FN_ARGS
 #endif
 
@@ -114,7 +113,7 @@
   void *result;
 
 #ifndef MALLOC_ZERO_WORKS
-  /* Some libcs don't do the right thing on size==0. Override them. */
+  /* Some libc mallocs don't work when size==0. Override them. */
   if (size==0) {
     size=1;
   }
@@ -143,6 +142,12 @@
 void *
 _tor_malloc_zero(size_t size DMALLOC_PARAMS)
 {
+  /* You may ask yourself, "wouldn't it be smart to use calloc instead of
+   * malloc+memset?  Perhaps libc's calloc knows some nifty optimization trick
+   * we don't!"  Indeed it does, but its optimizations are only a big win when
+   * we're allocating something very big (it knows if it just got the memory
+   * from the OS in a pre-zeroed state).  We don't want to use tor_malloc_zero
+   * for big stuff, so we don't bother with calloc. */
   void *result = _tor_malloc(size DMALLOC_FN_ARGS);
   memset(result, 0, size);
   return result;
@@ -182,7 +187,7 @@
 
 #ifdef USE_DMALLOC
   dup = dmalloc_strdup(file, line, s, 0);
-#else 
+#else
   dup = strdup(s);
 #endif
   if (PREDICT_UNLIKELY(dup == NULL)) {
@@ -213,8 +218,8 @@
   return dup;
 }
 
-/** Allocate a chunk of <b>len</b> bytes, with the same contents starting at
- * <b>mem</b>. */
+/** Allocate a chunk of <b>len</b> bytes, with the same contents as the
+ * <b>len</b> bytes starting at <b>mem</b>. */
 void *
 _tor_memdup(const void *mem, size_t len DMALLOC_PARAMS)
 {

Modified: tor/trunk/src/common/util.h
===================================================================
--- tor/trunk/src/common/util.h	2008-10-27 15:04:45 UTC (rev 17160)
+++ tor/trunk/src/common/util.h	2008-10-27 16:30:52 UTC (rev 17161)
@@ -39,8 +39,11 @@
  * security-critical properties.
  */
 #error "Sorry; we don't support building with NDEBUG."
-#elif defined(__GNUC__)
-/* Give an int-valued version of !x that won't confuse PREDICT_UNLIKELY. */
+#endif
+
+#if defined(__GNUC__)
+/* Give an int-valued version of !x that won't confuse PREDICT_UNLIKELY,
+ * which does poorly with pointer types on some versions of glibc. */
 #define IS_FALSE_AS_INT(x) ((x) == ((typeof(x)) 0))
 #else
 #define IS_FALSE_AS_INT(x) !(x)
@@ -57,6 +60,11 @@
       abort();                                                          \
     } STMT_END
 
+/* If we're building with dmalloc, we want all of our memory allocation
+ * functions to take an extra file/line pair of arguments.  If not, not.
+ * We define DMALLOC_PARAMS to the extra parameters to insert in the
+ * function prototypes, and DMALLOC_ARGS to the extra arguments to add
+ * to calls. */
 #ifdef USE_DMALLOC
 #define DMALLOC_PARAMS , const char *file, const int line
 #define DMALLOC_ARGS , _SHORT_FILE_, __LINE__
@@ -91,6 +99,13 @@
     }                                               \
   STMT_END
 #else
+/** Release memory allocated by tor_malloc, tor_realloc, tor_strdup, etc.
+ * Unlike the free() function, tor_free() will still work on NULL pointers,
+ * and it sets the pointer value to NULL after freeing it.
+ *
+ * This is a macro.  If you need a function pointer to release memory from
+ * tor_malloc(), use _tor_free().
+ */
 #define tor_free(p) STMT_BEGIN                                 \
     if (PREDICT_LIKELY((p)!=NULL)) {                           \
       free(p);                                                 \