UNPKG

@thi.ng/malloc

Version:

ArrayBuffer based malloc() impl for hybrid JS/WASM use cases, based on thi.ng/tinyalloc

197 lines 6.49 kB
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