regexps.com
The programming interfaces described in this chapter provide
some frequently needed functionality built on top of the standard
functions malloc
, realloc
, and free
.
There are functions that work like malloc
and friends, but
that cause the process to exit with an error message and a
non-0 status if an allocation fails. See Allocate or Die.
There are functions that let you keep track of how much memory is used by a particular subsystem of your program, and limit that amount of memory if you choose. You can use these functions to trigger various forms of garbage collection. See Allocation With Limitations.
Finally, There are functions that operate on arrays of bytes.
These do little more than replace standard functions such as
memcpy
, but are included for symmetry and completeness. See
Array-of-Byte Functions.
#include <hackerlab/mem/must-malloc.h>
The functions in this section allocate memory. If an allocation
fails, they call panic
rather than returning. Thus, these
functions may be used without checking for errors.
void * must_calloc (size_t amt);
Return a newly allocated block large enough to hold amt
bytes.
If no such block can be allocated, exit by calling panic
.
Fill the newly allocated memory with 0
bytes.
void * must_malloc (size_t amt);
Return a newly malloced block large enough to hold amt
bytes. If
no such block can be allocated, exit by calling panic
.
void * must_realloc (void * ptr, size_t amt);
Return a malloced block large enough to hold amt
bytes. If ptr
is not 0
, it should point to a previously malloced block. The
contents of the new block are initialized from the contents of
ptr
. If the new block is not the same as ptr
, ptr
is freed.
If no block can be allocated, exit by calling panic
.
void must_free (void * ptr);
Free a block allocated by must_calloc
, must_malloc
, or
must_realloc
.
#include <hackerlab/mem/alloc-limits.h>
In some situations it is desriable for a subsystem of a program
to limit its use of memory, independently of the rest of the program.
The alloc_limits
functions are for such situations.
There are two steps to using the alloc_limits
functions. First,
you create an alloc_limits
object which specifies how much memory
your subsystem should, ideally, use, and how much it is permitted to use.
See make_alloc_limits. Second, use functions like lim_malloc
and lim_free
instead of functions like malloc
and free
in the
subsystem to which the limits apply.
An object of the opaque type alloc_limits
records the rules which
limit memory use in a particular subsystem.
alloc_limits make_alloc_limits (t_uchar * name, size_t threshold, size_t failure_pt, int panic_on_failure, lim_free_memory_fn free_memory, void * closure);
Create a new alloc_limits
object.
name
is the name of the subsystem to which these allocation limits
apply. The name is useful for debugging purposes.
threshold
specifies an ideal limit on the amount of memory used
by your subsystem. If a subsystem attempts to allocate more than
threshold
bytes, the free_memory
function for that subsystem
is invoked (see below). threshold
may be 0
, in which case the
free_memory
function is never invoked.
failure_pt
specifies an absolute limit on the amount of memory
used by your subsystem. Allocations beyond failure_pt
fail
(return 0
).
panic_on_failure
, if non-0, means that if the failure point is
reached, or allocation fails, the program will exit with a
message to the standard error stream and a non-0 status.
If 0
, allocation failures return 0
.
free_memory
is a function pointer:
typedef void (*lim_free_memory_fn)(void * closure, size_t needed);
It is called immediately before an allocation that would exceed
threshold
(if threshold
is not 0
). closure
is as passed
to make_alloc_limits
(see below). needed
is the number of
bytes by which the proposed allocation causes the total amount of
memory used by the subsystem to exceed threshold
. It is completely
safe to call lim_free
from your free_memory
function. It
is possible to call lim_malloc
or lim_realloc
, but if your
program does this, free_memory
must be reentrant.
closure
is an opaque value passed to free_memory
.
If a new alloc_limits
object can not be allocated, this function
calls panic
and does not return.
As an alternative to calling make_alloc_limits
in some situations,
three pre-defined allocation limits are declared in alloc-limits.h
:
extern alloc_limits lim_use_malloc; extern alloc_limits lim_use_must_malloc; extern alloc_limits lim_no_allocations;
Allocations performed with lim_use_malloc
are unlimited and are
effectively like allocations performed with malloc
or realloc
.
Failed allocations return 0
.
Allocations performed with lim_use_must_malloc
are unlimited and
are effectively like allocations performed with must_malloc
or
must_realloc
. Failed allocations cause the process to exit with
a non-0 status.
Allocations performed with lim_no_allocations
always fail and return
0
. lim_free
has no effect when passed lim_no_allocations
.
void free_alloc_limits (alloc_limits limits);
Free an allocation limits object.
size_t lim_set_threshold (alloc_limits it, size_t threshold);
Modify the threshold
of an alloc_limits
object. Return
the old threshold
.
This function does not immediately call free_memory
, even if
the total amount of memory allocated exceeds the new threshold
.
size_t lim_threshold (alloc_limits limits);
Return the current threshold
of allocation limits limits
.
size_t lim_set_failure_pt (alloc_limits limits, size_t failure_pt);
Modify the failure_pt
of an alloc_limits
object. Return
the old failure_pt
.
size_t lim_failure_pt (alloc_limits limits);
Return the failure_pt
of allocation limits limits
.
Function
lim_is_panic_on_failure
int lim_is_panic_on_failure (alloc_limits limits);
Return the value of the panic_on_failure
flag of
allocation limits limits
.
Function
lim_set_panic_on_failure
int lim_set_panic_on_failure (alloc_limits limits, int value);
Set the panic_on_failure
flag of allocation limits limits
.
Return the old value.
size_t lim_in_use (alloc_limits limits);
Return the amount (in bytes) of memory allocation charged
to limits
and not yet freed.
size_t lim_high_water_mark (alloc_limits limits);
Return the largest amount (in bytes) of outstanding memory
allocation charged to limits
during the lifetime of the process.
These functions allocate and free memory, similarly to
malloc
, realloc
, and free
, but with allocation limits.
void * lim_malloc (alloc_limits limits, size_t amt);
Allocate amt
bytes of memory.
If the allocation would exceed the threshold of limits
,
invoke the free_memory
function first.
If the allocation would exceed the failure_pt
of limits
, or if
the underlying malloc
fails, return 0
(if the panic_on_failure
flag of limits
is 0
) or exit the process with a non-0 status (if
panic_on_failure
is non-0).
Adjust the in_use
and high_water_mark
of limits
.
If limits
is 0
, this function works like must_malloc.
void * lim_zalloc (alloc_limits limits, size_t amt);
Use lim_malloc
to attempt to allocate amt
bytes
of memory. If allocation succeeds, initialize that
memory to all zero bytes.
Return the allocated region or 0
if allocation fails.
void * lim_soft_malloc (alloc_limits limits, size_t amt);
Allocate amt
bytes of memory. Return the newly allocated memory.
If the allocation would exceed the failure_pt
of limits
,
or if the underlying malloc
fails, return 0
(if the
panic_on_failure
flag of limits
is 0
) or exit the
process with a non-0 status.
Adjust the in_use
and high_water_mark
of limits
.
This function does not invoke the free_memory
function of
limits
, even if the allocation would exceed the threshold of
limits
.
If limits
is 0
, this function works like must_malloc.
void * lim_realloc (alloc_limits limits, void * prev, size_t amt);
Reallocate prev
as amt
bytes of memory. Copy (up to) amt
bytes
of data from prev
to the newly allocated memory.
If the allocation would exceed the threshold of limits
,
invoke the free_memory
function first.
If the allocation would exceed the failure_pt
of limits
,
or if the underlying malloc
fails, return 0
(if the
panic_on_failure
flag of limits
is 0
) or exit the
process with a non-0 status.
Adjust the in_use
and high_water_mark
of limits
.
If prev
is 0
, this function behaves like lim_malloc
.
If limits
is 0
, this function works like must_realloc.
void * lim_soft_realloc (alloc_limits limits, void * prev, size_t amt);
Reallocate prev
as amt
bytes of memory. Copy (up to) amt
bytes
of data from prev
to the newly allocated memory.
If the allocation would exceed the failure_pt
of limits
, or if
the underlying malloc
fails, return 0
(if the
panic_on_failure
flag of limits
is 0
) or exit the
process with a non-0 status.
Adjust the in_use
and high_water_mark
of limits
.
This function does not invoke the free_memory
function of
limits
, even if the allocation would exceed the threshold of
limits
.
If limits
is 0
, this function works like must_realloc.
void lim_free (alloc_limits limits, void * ptr);
Free ptr
. Adjust the in_use
and high_water_mark
values
of limits
.
If limits
is 0
, this function works like must_free.
int lim_prepare (alloc_limits limits, size_t amt);
Prepare for an allocation of amt
bytes.
If such an allocation would exceed the threshold of limits
,
invoke the free_memory
function first.
If the allocation would exceed the failure_pt
of limits
,
return -1
. Otherwise, return 0
.
If limits
is 0
, this function simply returns 0
.
#include <hackerlab/mem/mem.h>
These functions operate on regions of memory as arrays of unsigned bytes with no further interpretation.
void mem_set (t_uchar * mem, unsigned int c, size_t size);
Store size
bytes of value c
beginning at mem
.
void mem_set0 (t_uchar * mem, size_t n);
Store n
0
bytes beginning at mem
.
void mem_move (t_uchar * to, const t_uchar * from, size_t amt);
Copy amt
bytes from from
to to
. The source and destination
regions may overlap.
int mem_cmp (const t_uchar * m1, const t_uchar * m2, size_t amt);
Compare amt
bytes starting at m1
and m2
. If a difference is
found, immediately return -1
if the differing byte in m1
is less
than the byte in m2
, 1
otherwise. If no difference is found,
return 0
.
size_t mem_occurrences (const t_uchar * mem, unsigned int c, size_t size);
Search size
bytes of data for occurences of byte c
beginning at
mem
. Return the number of occurences found.
regexps.com