[tor-commits] [tor/master] Edit 01a-memory.md

nickm at torproject.org nickm at torproject.org
Mon Oct 14 19:56:57 UTC 2019


commit 77accf937e2272b6e46a1486301d87b4df8f9bab
Author: Nick Mathewson <nickm at torproject.org>
Date:   Mon Oct 14 15:02:26 2019 -0400

    Edit 01a-memory.md
---
 doc/HACKING/design/01a-memory.md | 62 +++++++++++++++++++++++-----------------
 1 file changed, 36 insertions(+), 26 deletions(-)

diff --git a/doc/HACKING/design/01a-memory.md b/doc/HACKING/design/01a-memory.md
index 9a2078296..4c6bb0901 100644
--- a/doc/HACKING/design/01a-memory.md
+++ b/doc/HACKING/design/01a-memory.md
@@ -1,7 +1,7 @@
 
 ## Memory management
 
-### Heap-allocation functions
+### Heap-allocation functions: lib/malloc/malloc.h
 
 Tor imposes a few light wrappers over C's native malloc and free
 functions, to improve convenience, and to allow wholescale replacement
@@ -12,63 +12,71 @@ own; always use the variants prefixed with 'tor_'.
 They are the same as the standard C functions, with the following
 exceptions:
 
-   * tor_free(NULL) is a no-op.
-   * tor_free() is a macro that takes an lvalue as an argument and sets it to
-     NULL after freeing it.  To avoid this behavior, you can use tor_free_()
+   * `tor_free(NULL)` is a no-op.
+   * `tor_free()` is a macro that takes an lvalue as an argument and sets it to
+     NULL after freeing it.  To avoid this behavior, you can use `tor_free_()`
      instead.
    * tor_malloc() and friends fail with an assertion if they are asked to
      allocate a value so large that it is probably an underflow.
-   * It is always safe to tor_malloc(0), regardless of whether your libc
+   * It is always safe to `tor_malloc(0)`, regardless of whether your libc
      allows it.
-   * tor_malloc(), tor_realloc(), and friends are never allowed to fail.
+   * `tor_malloc()`, `tor_realloc()`, and friends are never allowed to fail.
      Instead, Tor will die with an assertion.  This means that you never
      need to check their return values.  See the next subsection for
      information on why we think this is a good idea.
 
 We define additional general-purpose memory allocation functions as well:
 
-   * tor_malloc_zero(x) behaves as calloc(1, x), except the it makes clear
+   * `tor_malloc_zero(x)` behaves as `calloc(1, x)`, except the it makes clear
      the intent to allocate a single zeroed-out value.
-   * tor_reallocarray(x,y) behaves as the OpenBSD reallocarray function.
+   * `tor_reallocarray(x,y)` behaves as the OpenBSD reallocarray function.
      Use it for cases when you need to realloc() in a multiplication-safe
      way.
 
 And specific-purpose functions as well:
 
-   * tor_strdup() and tor_strndup() behaves as the underlying libc functions,
-     but use tor_malloc() instead of the underlying function.
-   * tor_memdup() copies a chunk of memory of a given size.
-   * tor_memdup_nulterm() copies a chunk of memory of a given size, then
+   * `tor_strdup()` and `tor_strndup()` behaves as the underlying libc
+     functions, but use `tor_malloc()` instead of the underlying function.
+   * `tor_memdup()` copies a chunk of memory of a given size.
+   * `tor_memdup_nulterm()` copies a chunk of memory of a given size, then
      NUL-terminates it just to be safe.
 
-#### Why assert on failure?
+#### Why assert on allocation failure?
 
-Why don't we allow tor_malloc() and its allies to return NULL?
+Why don't we allow `tor_malloc()` and its allies to return NULL?
 
 First, it's error-prone.  Many programmers forget to check for NULL return
-values, and testing for malloc() failures is a major pain.
+values, and testing for `malloc()` failures is a major pain.
 
 Second, it's not necessarily a great way to handle OOM conditions. It's
 probably better (we think) to have a memory target where we dynamically free
 things ahead of time in order to stay under the target.  Trying to respond to
-an OOM at the point of tor_malloc() failure, on the other hand, would involve
+an OOM at the point of `tor_malloc()` failure, on the other hand, would involve
 a rare operation invoked from deep in the call stack.  (Again, that's
 error-prone and hard to debug.)
 
 Third, thanks to the rise of Linux and other operating systems that allow
 memory to be overcommitted, you can't actually ever rely on getting a NULL
-from malloc() when you're out of memory; instead you have to use an approach
+from `malloc()` when you're out of memory; instead you have to use an approach
 closer to tracking the total memory usage.
 
 #### Conventions for your own allocation functions.
 
 Whenever you create a new type, the convention is to give it a pair of
-x_new() and x_free() functions, named after the type.
+`x_new()` and `x_free_()` functions, named after the type.
 
-Calling x_free(NULL) should always be a no-op.
+Calling `x_free(NULL)` should always be a no-op.
 
+There should additionally be an `x_free()` macro, defined in terms of
+`x_free_()`.  This macro should set its lvalue to NULL.  You can define it
+using the FREE_AND_NULL macro, as follows:
 
-### Grow-only memory allocation: memarea.c
+```
+#define x_free(ptr) FREE_AND_NULL(x_t, x_free_, (ptr))
+```
+
+
+### Grow-only memory allocation: lib/memarea
 
 It's often handy to allocate a large number of tiny objects, all of which
 need to disappear at the same time.  You can do this in tor using the
@@ -82,12 +90,14 @@ objects of similar size.  But if you use tor_malloc() for the long-lived ones
 and a memarea for the temporary object, the malloc implementation is likelier
 to do better.
 
-To create a new memarea, use memarea_new().  To drop all the storage from a
-memarea, and invalidate its pointers, use memarea_drop_all().
+To create a new memarea, use `memarea_new()`.  To drop all the storage from a
+memarea, and invalidate its pointers, use `memarea_drop_all()`.
 
-The allocation functions memarea_alloc(), memarea_alloc_zero(),
-memarea_memdup(), memarea_strdup(), and memarea_strndup() are analogous to
-the similarly-named malloc() functions.  There is intentionally no
-memarea_free() or memarea_realloc().
+The allocation functions `memarea_alloc()`, `memarea_alloc_zero()`,
+`memarea_memdup()`, `memarea_strdup()`, and `memarea_strndup()` are analogous
+to the similarly-named malloc() functions.  There is intentionally no
+`memarea_free()` or `memarea_realloc()`.
 
+### Special allocation: lib/malloc/map_anon.h
 
+TODO: WRITEME.





More information about the tor-commits mailing list