@thi.ng/malloc
Version:
ArrayBuffer based malloc() impl for hybrid JS/WASM use cases, based on thi.ng/tinyalloc
197 lines • 6.49 kB
TypeScript
import type { IRelease, Maybe, Type, TypedArray, TypedArrayTypeMap } from "@thi.ng/api";
import type { Pow2 } from "@thi.ng/binary";
export interface MemPoolOpts {
/**
* Backing ArrayBuffer (or SharedArrayBuffer). If not given, a new
* one will be created with given `size`.
*/
buf: ArrayBufferLike;
/**
* Byte size for newly created ArrayBuffers (if `buf` is not given).
*
* @defaultValue 0x1000 (4KB)
*/
size: number;
/**
* Anchor index (byte address) inside the array buffer. The MemPool
* stores its internal state from the given address and heap space
* starts at least 32 bytes later (depending on chosen `align`
* value). Unlike allocator state variables, `start`` cannot be
* saved inside the array buffer itself. If the ArrayBuffer is
* passed to other consumers they must use the same start value.
* MUST be multiple of 4.
*
* @defaultValue 0
*/
start: number;
/**
* Byte address (+1) of the end of the memory region managed by the
* {@link MemPool}.
*
* @defaultValue end of the backing ArrayBuffer
*/
end: number;
/**
* Number of bytes to align memory blocks to. MUST be a power of 2
* and >= 8. Use 16 if the pool is being used for allocating memory
* used in SIMD operations.
*
* @defaultValue 8
*/
align: Pow2;
/**
* Flag to configure memory block compaction. If true,
* adjoining free blocks (in terms of address space) will be merged
* to minimize fragementation.
*
* @defaultValue true
*/
compact: boolean;
/**
* Flag to configure memory block splitting. If true, and when the
* allocator is re-using a previously freed block larger than the
* requested size, the block will be split to minimize wasted/unused
* memory. The splitting behavior can further customized via the
* `minSplit` option.
*
* @defaultValue true
*/
split: boolean;
/**
* Only used if `split` behavior is enabled. Defines min number of
* excess bytes available in a block for memory block splitting to
* occur.
*
* @defaultValue 16, MUST be > 8
*/
minSplit: number;
/**
* Only needed when sharing the underlying ArrayBuffer. If true, the
* {@link MemPool} constructor will NOT initialize its internal state and
* assume the underlying ArrayBuffer has already been initialized by
* another {@link MemPool} instance. If this option is used, `buf` MUST be
* given.
*
* @defaultValue false
*/
skipInitialization: boolean;
}
export interface MemPoolStats {
/**
* Free block stats.
*/
free: {
count: number;
size: number;
};
/**
* Used block stats.
*/
used: {
count: number;
size: number;
};
/**
* Current top address.
*/
top: number;
/**
* Bytes available
*/
available: number;
/**
* Total pool size.
*/
total: number;
}
export interface IMemPoolArray extends IRelease {
/**
* Takes a [`Type`](https://docs.thi.ng/umbrella/api/types/Type.html) enum
* and element count `num` (in units of given type). Similar to
* {@link IMemPool.malloc} and if successful returns typed array of given
* `type`. Returns undefined if allocation failed.
*
* @param type -
* @param num -
*/
mallocAs<T extends Type>(type: T, num: number): Maybe<TypedArrayTypeMap[T]>;
/**
* Similar to {@link IMemPoolArray.mallocAs}, but if allocation was
* successful also clears the allocated block w/ `fill` value (default: 0).
*
* @param type -
* @param num -
* @param fill -
*/
callocAs<T extends Type>(type: T, num: number, fill?: number): Maybe<TypedArrayTypeMap[T]>;
/**
* Similar to {@link IMemPool.realloc}, but takes a typed array (one
* previously allocated with {@link IMemPoolArray.mallocAs} or
* {@link IMemPoolArray.callocAs}) and if successul returns new typed array
* of same type. Implementation is free to return `arr` if new size is same
* as original. Returns undefined on failure.
*
* @param arr -
* @param num -
*/
reallocArray<T extends TypedArray>(arr: T, num: number): Maybe<T>;
/**
* Frees mem block associated with given typed array
*
* @param arr -
*/
free(arr: TypedArray): boolean;
/**
* Frees all previously allocated blocks and resests allocator state.
*/
freeAll(): void;
}
export interface IMemPool extends IMemPoolArray {
/**
* Attempts to allocate a new memory block of given `size` (in
* bytes). Returns block address or zero if unsuccessful
* (insufficient memory).
*
* @param size -
*/
malloc(size: number): number;
/**
* Similar to {@link IMemPool.malloc}, but if allocation was successful also
* clears the allocated block w/ `fill` value (default: 0).
*
* @param size -
* @param fill -
*/
calloc(size: number, fill?: number): number;
/**
* Attempts to reallocate given memory block to new `size` (in
* bytes). If new `size` is larger than the original, attempts to
* grow block or else allocates new one and moves contents to new
* address. If new size is smaller than original, the existing block
* might be split (depending on `split` & `minSplit` config options)
* and the unused part freed. Returns new address if successful or
* zero if re-allocation failed (insufficient menory).
*
* @param ptr -
* @param size -
*/
realloc(ptr: number, size: number): number;
/**
* Takes a memory block address and attempts to return the block to
* the pool. Depending on `compact` config option, this operation
* might cause compaction of consecutive free memory blocks to help
* counter fragmentation. Returns true if block has been freed.
*
* It's the user's responsibility to ensure that freed blocks are
* not used any further after calling {@link IMemPool.free}.
* Undefined behavior, or worse, pool corruption might ensue!
*
* @param ptr -
*/
free(ptr: number | TypedArray): boolean;
/**
* Returns an information object of the pool's state.
*/
stats(): Readonly<MemPoolStats>;
}
//# sourceMappingURL=api.d.ts.map