mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Document some dmalloc stuff and some stupid C tricks.
svn:r17161
This commit is contained in:
parent
c53f1f83e7
commit
0ab45fee73
@ -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))
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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); \
|
||||
|
Loading…
Reference in New Issue
Block a user