rlib
Convenience library for useful things
Loading...
Searching...
No Matches
Refcounted memory chunks and pluggable allocators

Abstract memory-chunk type (RMem) with a pluggable backend (RMemAllocator). Inspired by GStreamer's GstMemory / GstAllocator design. More...

Files

file  rmemallocator.h
 Refcounted memory-chunk abstraction with allocator vtables.
 

Data Structures

struct  RMemAllocationParams
 Allocation-time constraints passed to r_mem_allocator_alloc and the merge / take helpers. More...
 
struct  RMemMapInfo
 Scope object carried by an active mapping. More...
 
struct  RMem
 Concrete layout of an RMem chunk. More...
 
struct  RMemAllocator
 Concrete layout of an RMemAllocator. More...
 

Macros

#define R_MEM_MAP_RW   (R_MEM_MAP_READ | R_MEM_MAP_WRITE)
 Convenience: read + write access.
 
#define R_MEM_ALLOCATOR_SYSTEM   "system"
 Name of the built-in system / heap allocator.
 
#define R_MEM_MAP_INFO_INIT   { NULL, 0, 0, 0, NULL }
 Zero-init for an RMemMapInfo declared on the stack.
 
#define r_mem_ref   r_ref_ref
 Acquire a new reference to an RMem.
 
#define r_mem_unref   r_ref_unref
 Release a reference; frees the chunk when the last drops.
 
#define r_mem_is_readonly(mem)   (mem->flags & R_MEM_FLAG_READONLY)
 TRUE if mem carries R_MEM_FLAG_READONLY.
 
#define r_mem_is_writable(mem)   ((mem->flags & R_MEM_FLAG_READONLY) == 0)
 TRUE if mem can accept writes.
 
#define r_mem_is_zero_prefixed(mem)   (mem->flags & R_MEM_FLAG_ZERO_PREFIXED)
 TRUE if mem carries R_MEM_FLAG_ZERO_PREFIXED.
 
#define r_mem_is_zero_padded(mem)   (mem->flags & R_MEM_FLAG_ZERO_PADDED)
 TRUE if mem carries R_MEM_FLAG_ZERO_PADDED.
 
#define r_mem_allocator_default()   r_mem_allocator_find (R_MEM_ALLOCATOR_SYSTEM)
 Convenience for the built-in system / heap allocator.
 
#define r_mem_allocator_ref   r_ref_ref
 Acquire a new reference to an RMemAllocator.
 
#define r_mem_allocator_unref   r_ref_unref
 Release a reference to an RMemAllocator.
 

Typedefs

typedef ruint32 RMemFlags
 Bitmask of RMemFlag values.
 
typedef ruint32 RMemMapFlags
 Bitmask of RMemMapFlag values.
 

Enumerations

enum  RMemFlag {
  R_MEM_FLAG_NONE = 0 , R_MEM_FLAG_READONLY = (1 << 0) , R_MEM_FLAG_NO_VIEWS = (1 << 1) , R_MEM_FLAG_ZERO_PREFIXED = (1 << 2) ,
  R_MEM_FLAG_ZERO_PADDED = (1 << 3)
}
 Per-chunk flags carried on every RMem. More...
 
enum  RMemMapFlag { R_MEM_MAP_READ = (1 << 0) , R_MEM_MAP_WRITE = (1 << 1) , R_MEM_MAP_FLAG_LAST = (1 << 8) }
 Mapping-access flags passed to r_mem_map. More...
 

Functions

RMemr_mem_new_wrapped (RMemFlags flags, rpointer data, rsize allocsize, rsize size, rsize offset, rpointer user, RDestroyNotify usernotify) R_ATTR_WARN_UNUSED_RESULT
 Wrap an existing pointer in an RMem without copying.
 
static RMemr_mem_new_take (RMemFlags flags, rpointer data, rsize allocsize, rsize size, rsize offset)
 Wrap an existing heap allocation in an RMem and transfer ownership.
 
rboolean r_mem_resize (RMem *mem, rsize offset, rsize size)
 Adjust the visible window inside mem.
 
rboolean r_mem_map (RMem *mem, RMemMapInfo *info, RMemMapFlags flags)
 Open a scoped mapping over mem's bytes.
 
rboolean r_mem_unmap (RMem *mem, RMemMapInfo *info)
 Close a mapping previously opened with r_mem_map.
 
RMemr_mem_copy (RMem *mem, rssize offset, rssize size) R_ATTR_WARN_UNUSED_RESULT
 Deep-copy a byte range from mem into a fresh RMem.
 
RMemr_mem_view (RMem *mem, rssize offset, rssize size) R_ATTR_WARN_UNUSED_RESULT
 Create an aliased view onto a byte range of mem.
 
RMemr_mem_merge (const RMemAllocationParams *params, RMem *a,...) R_ATTR_WARN_UNUSED_RESULT
 Concatenate two or more chunks into a fresh RMem.
 
RMemr_mem_mergev (const RMemAllocationParams *params, RMem *a, va_list args) R_ATTR_WARN_UNUSED_RESULT
 va_list variant of r_mem_merge.
 
RMemr_mem_merge_array (const RMemAllocationParams *params, RMem **mems, ruint count) R_ATTR_WARN_UNUSED_RESULT
 Array variant of r_mem_merge - mems is a count-long array of chunk pointers.
 
RMemr_mem_take (const RMemAllocationParams *params, RMem *a,...) R_ATTR_WARN_UNUSED_RESULT
 Concatenate chunks (as r_mem_merge) but unref the inputs.
 
RMemr_mem_takev (const RMemAllocationParams *params, RMem *a, va_list args) R_ATTR_WARN_UNUSED_RESULT
 va_list variant of r_mem_take.
 
RMemr_mem_take_array (const RMemAllocationParams *params, RMem **mems, ruint count) R_ATTR_WARN_UNUSED_RESULT
 Array variant of r_mem_take - consumes references in mems on success.
 
void r_mem_init (RMem *mem, RDestroyNotify notify, RMemFlags flags, RMemAllocator *allocator, RMem *parent, rsize allocsize, rsize size, rsize alignmask, rsize offset)
 Allocator-implementation helper: populate an RMem's common fields and arm its destructor.
 
void r_mem_clear (RMem *mem)
 Allocator-implementation helper: release the references an RMem holds (parent, allocator).
 
RMemAllocatorr_mem_allocator_find (const rchar *name) R_ATTR_WARN_UNUSED_RESULT
 Look up a registered allocator by name.
 
void r_mem_allocator_register (RMemAllocator *allocator)
 Register an allocator so it can be looked up by name.
 
RMemr_mem_allocator_alloc_full (RMemAllocator *allocator, rsize size, const RMemAllocationParams *params) R_ATTR_WARN_UNUSED_RESULT
 Allocate a new RMem chunk via allocator.
 
static RMemr_mem_allocator_alloc (RMemAllocator *allocator, RMemFlags flags, rsize size, rsize prefix, rsize padding, rsize alignmask)
 Convenience for r_mem_allocator_alloc_full with the params spelled out as individual arguments.
 

Detailed Description

Abstract memory-chunk type (RMem) with a pluggable backend (RMemAllocator). Inspired by GStreamer's GstMemory / GstAllocator design.

Macro Definition Documentation

◆ r_mem_allocator_default

#define r_mem_allocator_default ( )    r_mem_allocator_find (R_MEM_ALLOCATOR_SYSTEM)

Convenience for the built-in system / heap allocator.

Equivalent to r_mem_allocator_find(R_MEM_ALLOCATOR_SYSTEM).

Enumeration Type Documentation

◆ RMemFlag

enum RMemFlag

Per-chunk flags carried on every RMem.

Combined as a bitmask in RMemFlags. Honoured by the high-level helpers (read-only chunks reject r_mem_resize and write mappings; view-prohibited chunks reject r_mem_view).

Enumerator
R_MEM_FLAG_NONE 

No flags.

R_MEM_FLAG_READONLY 

Underlying bytes are immutable.

R_MEM_FLAG_NO_VIEWS 

r_mem_view will refuse to create aliased subviews.

R_MEM_FLAG_ZERO_PREFIXED 

The bytes before offset are known to be zero.

R_MEM_FLAG_ZERO_PADDED 

The bytes after offset+size are known to be zero.

◆ RMemMapFlag

Mapping-access flags passed to r_mem_map.

Choose R_MEM_MAP_READ for read-only access, R_MEM_MAP_WRITE for write-only, or R_MEM_MAP_RW for both. Allocator-specific extensions may use bits up to R_MEM_MAP_FLAG_LAST.

Enumerator
R_MEM_MAP_READ 

Caller will read from the mapping.

R_MEM_MAP_WRITE 

Caller will write to the mapping.

R_MEM_MAP_FLAG_LAST 

Reserved cutoff; allocator-specific bits live below.

Function Documentation

◆ r_mem_allocator_alloc_full()

RMem * r_mem_allocator_alloc_full ( RMemAllocator allocator,
rsize  size,
const RMemAllocationParams params 
)

Allocate a new RMem chunk via allocator.

Parameters
allocatorAllocator to use (must be non-NULL).
sizeVisible window size in bytes.
paramsAllocation constraints (alignment, prefix / padding, initial flags).
Returns
New chunk reference, or NULL on failure.

◆ r_mem_allocator_find()

RMemAllocator * r_mem_allocator_find ( const rchar name)

Look up a registered allocator by name.

Returns a new reference on success (caller releases with r_mem_allocator_unref).

Parameters
nameAllocator name (e.g. R_MEM_ALLOCATOR_SYSTEM).
Returns
New allocator reference, or NULL if no allocator with that name is registered.

◆ r_mem_allocator_register()

void r_mem_allocator_register ( RMemAllocator allocator)

Register an allocator so it can be looked up by name.

Adds allocator to the process-wide registry, looked up by its mem_type. The registry stores the pointer but does not take a reference, so the caller must keep allocator alive for as long as it may be looked up (do not drop the last reference).

Parameters
allocatorAllocator to register (must have a non-NULL mem_type).

◆ r_mem_clear()

void r_mem_clear ( RMem mem)

Allocator-implementation helper: release the references an RMem holds (parent, allocator).

Intended only for use inside an RMemAllocator's free callback before it releases the chunk's backing storage.

Parameters
memMemory chunk being torn down.

◆ r_mem_copy()

RMem * r_mem_copy ( RMem mem,
rssize  offset,
rssize  size 
)

Deep-copy a byte range from mem into a fresh RMem.

Negative offset / size are interpreted relative to the chunk's bounds (allocator-specific convention; commonly size < 0 means "to end").

Parameters
memSource chunk.
offsetOffset within mem (signed).
sizeLength (signed; negative often means "to end").
Returns
Newly-allocated chunk, or NULL on failure.

◆ r_mem_init()

void r_mem_init ( RMem mem,
RDestroyNotify  notify,
RMemFlags  flags,
RMemAllocator allocator,
RMem parent,
rsize  allocsize,
rsize  size,
rsize  alignmask,
rsize  offset 
)

Allocator-implementation helper: populate an RMem's common fields and arm its destructor.

Intended only for use inside an RMemAllocator's alloc callback. Not part of the public client API.

Parameters
memMemory chunk to initialise.
notifyDestroy callback invoked when the last reference drops.
flagsInitial RMemFlags.
allocatorOwning allocator (must be ref-counted).
parentParent chunk for view aliases, NULL otherwise.
allocsizeUnderlying allocation length.
sizeVisible window length.
alignmaskAlignment guarantee on the visible region.
offsetVisible window offset within allocsize.

◆ r_mem_map()

rboolean r_mem_map ( RMem mem,
RMemMapInfo info,
RMemMapFlags  flags 
)

Open a scoped mapping over mem's bytes.

Acquires an extra reference on mem (released by r_mem_unmap) and populates info with a pointer the caller may read from / write to per flags. Write mappings are refused on read-only chunks.

Parameters
memChunk to map.
infoOutput RMemMapInfo - typically stack-allocated and initialised with R_MEM_MAP_INFO_INIT.
flagsAccess flags (R_MEM_MAP_READ, R_MEM_MAP_WRITE, or R_MEM_MAP_RW).
Returns
TRUE on success, FALSE on conflicting flags or allocator-level mapping failure.

◆ r_mem_merge()

RMem * r_mem_merge ( const RMemAllocationParams params,
RMem a,
  ... 
)

Concatenate two or more chunks into a fresh RMem.

Variadic args are RMem* terminated by NULL. The inputs are left unchanged (their refcounts are unaffected). Use r_mem_take for the equivalent that consumes the inputs.

Parameters
paramsAllocation constraints for the result (may be NULL for defaults).
aFirst chunk (must be non-NULL).
...Remaining chunks, terminated by NULL.
Returns
Newly-allocated, fully-populated chunk, or NULL.

◆ r_mem_new_take()

static RMem * r_mem_new_take ( RMemFlags  flags,
rpointer  data,
rsize  allocsize,
rsize  size,
rsize  offset 
)
inlinestatic

Wrap an existing heap allocation in an RMem and transfer ownership.

Convenience for the common case where the wrapped buffer was obtained from r_malloc: when the last reference drops the wrapper calls r_free on data. Equivalent to r_mem_new_wrapped (flags, data, allocsize, size, offset, data, r_free). Ownership transfers unconditionally — data is r_free'd even if creation fails, so the caller must not free it on a NULL return.

◆ r_mem_new_wrapped()

RMem * r_mem_new_wrapped ( RMemFlags  flags,
rpointer  data,
rsize  allocsize,
rsize  size,
rsize  offset,
rpointer  user,
RDestroyNotify  usernotify 
)

Wrap an existing pointer in an RMem without copying.

Used to hand raw bytes to a system that expects RMem-shaped input (e.g. zero-copy ingestion of a parsed file). The usernotify callback runs (with user as argument) when the last reference drops, so the caller controls cleanup.

Parameters
flagsInitial RMemFlags (typically R_MEM_FLAG_READONLY for borrowed buffers).
dataPointer to the first byte.
allocsizeUnderlying allocation length in bytes.
sizeVisible window length in bytes.
offsetVisible window offset within data.
userCookie passed to usernotify on free.
usernotifyDestroy callback (may be NULL for borrowed memory).
Returns
New RMem reference, or NULL on allocation failure.

Ownership of data transfers on entry: usernotify is invoked exactly once whether the wrapper is created (when the last reference drops) or creation fails (before returning NULL). Callers must therefore not free data themselves on a NULL return.

◆ r_mem_resize()

rboolean r_mem_resize ( RMem mem,
rsize  offset,
rsize  size 
)

Adjust the visible window inside mem.

Moves offset and / or shrinks / grows size within the underlying allocation. Refuses to operate on read-only chunks or to expand past the allocation bounds. Clears R_MEM_FLAG_ZERO_PREFIXED / R_MEM_FLAG_ZERO_PADDED when the window moves over the corresponding zero region.

Parameters
memChunk to resize (must be writable).
offsetNew visible-window offset (bytes from start of allocation).
sizeNew visible-window size in bytes.
Returns
TRUE on success, FALSE on read-only chunk or out-of-bounds offset + size.

◆ r_mem_take()

RMem * r_mem_take ( const RMemAllocationParams params,
RMem a,
  ... 
)

Concatenate chunks (as r_mem_merge) but unref the inputs.

Transfers ownership: on success the supplied chunks are r_mem_unref'd. Convenient pattern for assembling a buffer from intermediate scratch chunks the caller doesn't want to keep.

Parameters
paramsAllocation constraints for the result (may be NULL).
aFirst chunk.
...Remaining chunks, terminated by NULL.
Returns
Newly-allocated chunk, or NULL (in which case input refcounts are untouched).

◆ r_mem_unmap()

rboolean r_mem_unmap ( RMem mem,
RMemMapInfo info 
)

Close a mapping previously opened with r_mem_map.

Calls the allocator's unmap callback and releases the RMem reference recorded in info.

Parameters
memChunk that was mapped (must match info->mem).
infoThe same RMemMapInfo that r_mem_map populated.
Returns
TRUE on successful release, FALSE if the allocator refused (rare; typically a programming error).

◆ r_mem_view()

RMem * r_mem_view ( RMem mem,
rssize  offset,
rssize  size 
)

Create an aliased view onto a byte range of mem.

The view shares the underlying allocation with mem (no copy). Refused if mem has R_MEM_FLAG_NO_VIEWS.

Parameters
memSource chunk.
offsetOffset within mem (signed).
sizeLength (signed; negative often means "to end").
Returns
New RMem reference aliasing mem, or NULL.