#include "orconfig.h"
#include <stdlib.h>
#include "memarea.h"
#include "util.h"
#include "compat.h"
#include "log.h"
Data Structures | |
struct | memarea_chunk_t |
struct | memarea_t |
Defines | |
#define | USE_SENTINELS |
#define | MEMAREA_ALIGN SIZEOF_VOID_P |
#define | MEMAREA_ALIGN_MASK 7lu |
#define | SENTINEL_VAL 0x90806622u |
#define | SENTINEL_LEN sizeof(uint32_t) |
#define | SET_SENTINEL(chunk) |
#define | CHECK_SENTINEL(chunk) |
#define | CHUNK_HEADER_SIZE STRUCT_OFFSET(memarea_chunk_t, u) |
#define | CHUNK_SIZE 4096 |
#define | MAX_FREELIST_LEN 4 |
Functions | |
static INLINE void * | realign_pointer (void *ptr) |
static memarea_chunk_t * | alloc_chunk (size_t sz, int freelist_ok) |
static void | chunk_free_unchecked (memarea_chunk_t *chunk) |
memarea_t * | memarea_new (void) |
void | memarea_drop_all (memarea_t *area) |
void | memarea_clear (memarea_t *area) |
void | memarea_clear_freelist (void) |
int | memarea_owns_ptr (const memarea_t *area, const void *p) |
void * | memarea_alloc (memarea_t *area, size_t sz) |
void * | memarea_alloc_zero (memarea_t *area, size_t sz) |
void * | memarea_memdup (memarea_t *area, const void *s, size_t n) |
char * | memarea_strdup (memarea_t *area, const char *s) |
char * | memarea_strndup (memarea_t *area, const char *s, size_t n) |
void | memarea_get_stats (memarea_t *area, size_t *allocated_out, size_t *used_out) |
void | memarea_assert_ok (memarea_t *area) |
Variables | |
static int | freelist_len = 0 |
static memarea_chunk_t * | freelist = NULL |
#define CHECK_SENTINEL | ( | chunk | ) |
Value:
STMT_BEGIN \ uint32_t sent_val = get_uint32(&(chunk)->u.mem[chunk->mem_size]); \ tor_assert(sent_val == SENTINEL_VAL); \ STMT_END
#define MAX_FREELIST_LEN 4 |
How many chunks will we put into the freelist before freeing them?
Referenced by chunk_free_unchecked().
#define MEMAREA_ALIGN SIZEOF_VOID_P |
All returned pointers should be aligned to the nearest multiple of this value.
#define SET_SENTINEL | ( | chunk | ) |
Value:
STMT_BEGIN \ set_uint32( &(chunk)->u.mem[chunk->mem_size], SENTINEL_VAL ); \ STMT_END
#define USE_SENTINELS |
If true, we try to detect any attempts to write beyond the length of a memarea.
static memarea_chunk_t* alloc_chunk | ( | size_t | sz, | |
int | freelist_ok | |||
) | [static] |
Helper: allocate a new memarea chunk of around chunk_size bytes.
References freelist_len, memarea_chunk_t::mem, memarea_chunk_t::mem_size, memarea_chunk_t::next_chunk, memarea_chunk_t::next_mem, realign_pointer(), tor_assert, and memarea_chunk_t::u.
Referenced by memarea_alloc(), and memarea_new().
static void chunk_free_unchecked | ( | memarea_chunk_t * | chunk | ) | [static] |
Release chunk from a memarea, either by adding it to the freelist or by freeing it if the freelist is already too big.
References freelist_len, MAX_FREELIST_LEN, memarea_chunk_t::mem, memarea_chunk_t::next_chunk, memarea_chunk_t::next_mem, tor_free, and memarea_chunk_t::u.
Referenced by buf_clear(), buf_pullup(), buf_remove_from_front(), memarea_clear(), and memarea_drop_all().
void* memarea_alloc | ( | memarea_t * | area, | |
size_t | sz | |||
) |
Return a pointer to a chunk of memory in area of at least sz bytes. sz should be significantly smaller than the area's chunk size, though we can deal if it isn't.
References alloc_chunk(), memarea_t::first, memarea_chunk_t::mem, memarea_chunk_t::mem_size, memarea_chunk_t::next_chunk, memarea_chunk_t::next_mem, realign_pointer(), tor_assert, and memarea_chunk_t::u.
Referenced by memarea_alloc_zero(), memarea_memdup(), and memarea_strndup().
void* memarea_alloc_zero | ( | memarea_t * | area, | |
size_t | sz | |||
) |
As memarea_alloc(), but clears the memory it returns.
References memarea_alloc().
void memarea_assert_ok | ( | memarea_t * | area | ) |
Assert that area is okay.
References memarea_t::first, memarea_chunk_t::mem, memarea_chunk_t::mem_size, memarea_chunk_t::next_chunk, memarea_chunk_t::next_mem, realign_pointer(), tor_assert, and memarea_chunk_t::u.
void memarea_clear | ( | memarea_t * | area | ) |
Forget about having allocated anything in area, and free some of the backing storage associated with it, as appropriate. Invalidates all pointers returned from memarea_alloc() for this area.
References chunk_free_unchecked(), memarea_t::first, memarea_chunk_t::mem, memarea_chunk_t::next_chunk, memarea_chunk_t::next_mem, and memarea_chunk_t::u.
Referenced by microdescs_parse_from_string(), networkstatus_v2_parse_from_string(), rend_parse_client_keys(), rend_parse_introduction_points(), router_parse_directory(), and routerstatus_parse_entry_from_string().
void memarea_clear_freelist | ( | void | ) |
Remove all unused memarea chunks from the internal freelist.
References freelist_len, memarea_chunk_t::next_chunk, and tor_free.
Referenced by tor_free_all().
void memarea_drop_all | ( | memarea_t * | area | ) |
Free area, invalidating all pointers returned from memarea_alloc() and friends for this area
References chunk_free_unchecked(), memarea_t::first, memarea_chunk_t::next_chunk, and tor_free.
Referenced by authority_cert_parse_from_string(), extrainfo_parse_entry_from_string(), find_dir_signing_key(), microdescs_parse_from_string(), networkstatus_parse_vote_from_string(), networkstatus_v2_parse_from_string(), rend_parse_client_keys(), rend_parse_introduction_points(), rend_parse_v2_service_descriptor(), router_parse_addr_policy_item_from_string(), router_parse_directory(), router_parse_entry_from_string(), and router_parse_runningrouters().
void memarea_get_stats | ( | memarea_t * | area, | |
size_t * | allocated_out, | |||
size_t * | used_out | |||
) |
Set allocated_out to the number of bytes allocated in area, and used_out to the number of bytes currently used.
References memarea_t::first, memarea_chunk_t::mem, memarea_chunk_t::mem_size, memarea_chunk_t::next_chunk, memarea_chunk_t::next_mem, tor_assert, and memarea_chunk_t::u.
void* memarea_memdup | ( | memarea_t * | area, | |
const void * | s, | |||
size_t | n | |||
) |
As memdup, but returns the memory from area.
References memarea_alloc().
Referenced by get_token_arguments(), and memarea_strdup().
memarea_t* memarea_new | ( | void | ) |
Allocate and return new memarea.
References alloc_chunk(), and memarea_t::first.
Referenced by authority_cert_parse_from_string(), extrainfo_parse_entry_from_string(), find_dir_signing_key(), microdescs_parse_from_string(), networkstatus_parse_detached_signatures(), networkstatus_parse_vote_from_string(), networkstatus_v2_parse_from_string(), rend_parse_client_keys(), rend_parse_introduction_points(), rend_parse_v2_service_descriptor(), router_parse_addr_policy_item_from_string(), router_parse_directory(), router_parse_entry_from_string(), and router_parse_runningrouters().
int memarea_owns_ptr | ( | const memarea_t * | area, | |
const void * | p | |||
) |
Return true iff p is in a range that has been returned by an allocation from area.
References memarea_t::first, memarea_chunk_t::mem, memarea_chunk_t::next_chunk, and memarea_chunk_t::u.
char* memarea_strdup | ( | memarea_t * | area, | |
const char * | s | |||
) |
As strdup, but returns the memory from area.
References memarea_memdup().
char* memarea_strndup | ( | memarea_t * | area, | |
const char * | s, | |||
size_t | n | |||
) |
As strndup, but returns the memory from area.
References memarea_alloc().
Referenced by get_token_arguments().
static INLINE void* realign_pointer | ( | void * | ptr | ) | [static] |
Increment ptr until it is aligned to MEMAREA_ALIGN.
References tor_assert.
Referenced by alloc_chunk(), memarea_alloc(), and memarea_assert_ok().
memarea_chunk_t* freelist = NULL [static] |
A linked list of unused memory area chunks. Used to prevent us from spinning in malloc/free loops.
Referenced by chunk_free_unchecked(), and chunk_new_with_alloc_size().
int freelist_len = 0 [static] |
The number of memarea chunks currently in our freelist.
Referenced by alloc_chunk(), chunk_free_unchecked(), and memarea_clear_freelist().