diff options
author | Nick Mathewson <nickm@torproject.org> | 2008-10-27 16:30:52 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2008-10-27 16:30:52 +0000 |
commit | 0ab45fee73812a90c8714a6a3d99d5727a6733f3 (patch) | |
tree | 8349164ed5a3b19612e580012b7dab79c0990ebf /src/common | |
parent | c53f1f83e78ceca9dc798f8dcc129405e4427c55 (diff) | |
download | tor-0ab45fee73812a90c8714a6a3d99d5727a6733f3.tar.gz tor-0ab45fee73812a90c8714a6a3d99d5727a6733f3.zip |
Document some dmalloc stuff and some stupid C tricks.
svn:r17161
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/compat.h | 29 | ||||
-rw-r--r-- | src/common/util.c | 17 | ||||
-rw-r--r-- | src/common/util.h | 19 |
3 files changed, 54 insertions, 11 deletions
diff --git a/src/common/compat.h b/src/common/compat.h index 2e1c14b7e1..f0036d7764 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -137,10 +137,20 @@ extern INLINE double U64_TO_DBL(uint64_t x) { #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 @@ extern INLINE double U64_TO_DBL(uint64_t x) { #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 @@ size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2)); #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 @@ size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2)); #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 @@ tor_memstr(const void *haystack, size_t hlen, const char *needle) 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)) diff --git a/src/common/util.c b/src/common/util.c index 093a3b1530..cc94ccd00a 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -83,6 +83,7 @@ const char util_c_id[] = "$Id$"; #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 @@ const char util_c_id[] = "$Id$"; #endif #else /* not using dmalloc */ - #define DMALLOC_FUNC_MALLOC 0 - #define DMALLOC_FUNC_REALLOC 0 #define DMALLOC_FN_ARGS #endif @@ -114,7 +113,7 @@ _tor_malloc(size_t size DMALLOC_PARAMS) 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 @@ _tor_malloc(size_t size DMALLOC_PARAMS) 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 @@ _tor_strdup(const char *s DMALLOC_PARAMS) #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 @@ _tor_strndup(const char *s, size_t n DMALLOC_PARAMS) 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) { diff --git a/src/common/util.h b/src/common/util.h index dafeb25c1d..0474f0fcf3 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -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 @@ extern int dmalloc_free(const char *file, const int line, void *pnt, } \ 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); \ |