---
source_path: "api/library-config.md"
canonical_url: "https://doc.sensory.com/tnl/7.8/api/library-config/"
---

# Library configuration

This section describes functions and settings that control overall
TrulyNatural SDK library behavior.

These are most useful on small platforms with limited memory, and relevant
to the native C API only. Library configuration is not available in Java or
Python; the Python binding follows the Java binding here and exposes no
`snsrConfig` wrapper.

Most-used library configuration (C API only):

| API | Summary |
|-----|---------|
| [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config) | Set global behavior: heap, clock, license, panic handler, and more. |
| [CONFIG_ALLOC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_alloc) | Install a custom [heap allocator](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators) before any other library call. |
| [allocTLSF](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloctlsf) | TLSF allocator backed by a fixed memory pool (recommended). |
| [allocStdlib](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocstdlib) | Allocator that wraps the platform `malloc` / `free`. |
| [allocLock](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloclock) | Thread-safe wrapper around another allocator VMT. |
| [CONFIG_ALLOC_ADD_POOL](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_alloc_add_pool) | Add a memory segment to an existing custom allocator. |
| [CONFIG_LICENSE](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_license) | Apply an SDK license key at startup. |
| [CONFIG_CLOCK_FUNC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_clock_func) | Register a monotonic real-time [clock](https://doc.sensory.com/tnl/7.8/api/library-config.md#clock) for bare-metal targets. |
| [CONFIG_PANIC_FUNC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_panic_func) | Register a fatal [panic](https://doc.sensory.com/tnl/7.8/api/library-config.md#panic) handler for out-of-memory failures. |
| [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt) | Vtable for implementing a fully custom heap allocator. |

To release library-wide configuration allocations, call [tearDown](https://doc.sensory.com/tnl/7.8/api/heap.md#teardown) (see
[Memory management](https://doc.sensory.com/tnl/7.8/api/heap.md#memory-management)).

## Configuration

Use the [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config) function to replace the [heap memory allocator](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators),
specify a [real-time clock](https://doc.sensory.com/tnl/7.8/api/library-config.md#clock) function, or register an [out-of-memory handler](https://doc.sensory.com/tnl/7.8/api/library-config.md#panic).

### config
<!-- tab: c -->

**C/C++**

```c
SNSR_API SnsrRC
snsrConfig(SnsrConfig config, ...);
```

**Parameters and return value:**

**Input parameter:** `config`

* [Config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config-enum) configuration type. This determines the rest of the argument list.

**Return value:** * [OK](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_ok) for success, any other value indicates failure.

Global library configuration changes.

Use this variadic function to change the overall behavior of the TrulyNatural SDK.
The required [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config-enum) parameter specifies which aspect to change.

**Warning:**

- Unless noted otherwise in the description of the `config` setting,
  you must call this function only when no library handles exist:
  Before any other API function at start-up, or after a call
  to [tearDown](https://doc.sensory.com/tnl/7.8/api/heap.md#teardown).
- This function is **not** thread-safe.
- The number of additional parameters expected depend entirely on the `config`
  parameter. Failure to provide all the expected arguments with the
  expected types will lead to [undefined behavior][undefined-behavior].

**Also see these related items:** [Config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config-enum)

<!-- /tab -->

### chipComms
<!-- tab: c -->

**C/C++**

```c
typedef uint32_t *(*SnsrChipComms)(uint32_t *in);
```

Security and licensing chip function.

**Warning:**

Do not use this or [CONFIG_SECURITY_CHIP](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_security_chip) unless recommended by Sensory.

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [CONFIG_SECURITY_CHIP](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_security_chip)

<!-- /tab -->

### clock
<!-- tab: c -->

**C/C++**

```c
typedef uint64_t (*SnsrClock)(void);
```

Custom clock function.

This should return the number of real-time monotonically-increasing
clock ticks since an arbitrary start time.

**Note:**

You'll typically only need to provide this clock function on small platforms that
run on bare metal or very lightweight operating systems. The TrulyNatural SDK
provides clock implementations on Linux, macOS, iOS, Android, and Windows.

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [CONFIG_CLOCK_FUNC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_clock_func)

<!-- /tab -->

### panic
<!-- tab: c -->

**C/C++**

```c
typedef void (*SnsrPanic)(const char *format, va_list a);
```

**Parameters and return value:**

**Input parameter:** `format`

* [printf()][] format string.

**Input parameter:** `a`

* List of arguments that match the format specifiers in `format`.

Fatal error function.

When set with [CONFIG_PANIC_FUNC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_panic_func), a function matching this signature
will be called if the TrulyNatural SDK fails to allocate memory.

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [CONFIG_PANIC_FUNC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_panic_func)
<!-- /tab -->

### Config
<!-- tab: c -->

**C/C++**

```c
typedef enum {
    SNSR_CONFIG_{name},
    ...
} SnsrConfig;

// Where {name} is from the table below, e.g.: SNSR_CONFIG_ALLOC
```
<!-- /tab -->

Values in this `enum` are used as the first argument to [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config) and specify which additional arguments `snsrConfig()` expects.

**`ALLOC`**

Replace the heap allocator used in the TrulyNatural SDK.

This replaces the standard C heap allocator with a custom library-specific
[allocator](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators).

This function will fail if any previous TrulyNatural heap allocations have
been made. Best practice is to configure the heap manager before
calling any other library functions.

**snsrConfig() parameters**

  ```c
  SNSR_API SnsrRC
  snsrConfig(
    SNSR_CONFIG_ALLOC,
    SnsrAlloc_Vmt *vmt
  );
  ```
  - **Input parameter:** `vmt`: Pointer to [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt). This struct must remain valid at least until [tearDown](https://doc.sensory.com/tnl/7.8/api/heap.md#teardown) is called.

**Example**

```c
#define SIZE_IN_BYTES 512000
static size_t segment[SIZE_IN_BYTES / sizeof(size_t)];

// in main()
snsrConfig(SNSR_CONFIG_ALLOC, snsrAllocTLSF(segment, sizeof(segment)));
```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt), [CONFIG_ALLOC_ADD_POOL](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_alloc_add_pool)

**`ALLOC_ADD_POOL`**

Add a memory pool to a custom heap allocator.

This adds an additional memory segment to use as backing store
for the custom heap allocator configured with [CONFIG_ALLOC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_alloc).

**snsrConfig() parameters**

  ```c
  SNSR_API SnsrRC
  snsrConfig(
    SNSR_CONFIG_ALLOC_ADD_POOL,
    void *poolStart,
    size_t poolSizeInBytes
  );
  ```
  - **Input parameter:** `poolStart`: Pointer to start of a read-write memory segment to add to the allocator store. This must be aligned to the words size of the CPU.

**Example**

Example:

```c
#define POOL_SIZE 128000
static size_t pool[POOL_SIZE / sizeof(size_t)];
snsrConfig(SNSR_CONFIG_ALLOC_ADD_POOL, pool, sizeof(pool));
```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [CONFIG_ALLOC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_alloc)

**`PANIC_FUNC`**

Set the fatal error function.

This panic function is called in the event of an unrecoverable error,
such as the inability to allocate sufficient RAM.

</p>The default behavior if `panicFunc` is `NULL` is to print an
error message to `stderr` and then abort the process. This is
undesirable on small embedded platforms with either no OS, or a very
lightweight RTOS, that run from a single memory image.</p>

If `panicFunc` is called, all TrulyNatural SDK handles are invalid and must
be discarded. An effective way to do this is to use a custom [heap allocator](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators),
which allows all open handles to be abandoned by reclaiming the heap segment.

**snsrConfig() parameters**

  ```c
  SNSR_API SnsrRC
  snsrConfig(
    SNSR_CONFIG_PANIC_FUNC,
    SnsrPanic panic
  );
  ```
  - **Input parameter:** `panic`: [panic](https://doc.sensory.com/tnl/7.8/api/library-config.md#panic) callback function.

**Example**

Example:
```c
#include <snsr.h>
#include <setjmp.h>
#include <stdio.h>

static jmp_buf PanicJmp;

static void
panicFunc(const char *format, va_list a)
{
  fprintf(stderr, "\nPANIC: ");
  vfprintf(stderr, format, a);
  fprintf(stderr, "\n\n");
  longjmp(PanicJmp, SNSR_RC_NO_MEMORY);
}

// In main() before any API calls that are not snsrConfig()
int r;
snsrConfig(SNSR_CONFIG_PANIC_FUNC, panicFunc);
if ((r = setjmp(PanicJmp))) {
  snsrTearDown();
  // handle out-of-memory case. Abandon heap, re-initialize.
}
```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [heap allocators](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators)

**`STT_SUPPORT`**

Library Speech-To-Text support.

[config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config) returns [OK](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_ok) if the SDK supports Speech-To-Text
models, or [NOT_SUPPORTED](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_not_supported) if STT support is not available.

You may retrieve this value even if active library handles exist.

**Note**

You must call [new](https://doc.sensory.com/tnl/7.8/api/inference.md#new) at least once before calling `snsrConfig(SNSR_CONFIG_STT_SUPPORT)`.
If you do not, this function will return [NOT_SUPPORTED](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_not_supported) even if the SDK
does include support for Speech-To-Text.

**snsrConfig() parameters**

  ```c
  SNSR_API SnsrRC
  snsrConfig(
    SNSR_CONFIG_STT_SUPPORT
  );
  ```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [stt-support](https://doc.sensory.com/tnl/7.8/api/setting-keys/library-information.md#stt-support)

**`THREAD_SUPPORT`**

Library multithreading support.

[config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config) returns [OK](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_ok) if the SDK supports running multi-threaded models,
or [NOT_SUPPORTED](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_not_supported) if thread support is not available.

You may retrieve this value even if active library handles exist.

**snsrConfig() parameters**

  ```c
  SNSR_API SnsrRC
  snsrConfig(
    SNSR_CONFIG_THREAD_SUPPORT
  );
  ```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [thread-support](https://doc.sensory.com/tnl/7.8/api/setting-keys/library-information.md#thread-support)

**`SECURITY_CHIP`**

Hardware security device communication.

Use iff recommended by Sensory.

**snsrConfig() parameters**

  ```c
  SNSR_API SnsrRC
  snsrConfig(
    SNSR_CONFIG_SECURITY_CHIP,
    SnsrChipComms commsFunc
  );
  ```
  - **Input parameter:** `commsFunc`: [chipComms](https://doc.sensory.com/tnl/7.8/api/library-config.md#chipcomms) callback function.

**Example**

Example:
```c
uint32_t *chipComms(uint32_t *in) {
  // communicate with hardware
}

// ...
snsrConfig(SNSR_CONFIG_SECURITY_CHIP, chipComms);
```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config)

**`CLOCK_FUNC`**

Set high-resolution monotonic time function and resolution.

Sets a function that must return a high-resolution monotonically-increasing
value that measures clock time. This is used to limit the maximum amount
of time spent in any one call to [push](https://doc.sensory.com/tnl/7.8/api/inference.md#push) with [push-duration-limit](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#push-duration-limit),
and for recognition pipeline profiling.

**snsrConfig() parameters**

  ```c
  SNSR_API SnsrRC
  snsrConfig(
    SNSR_CONFIG_CLOCK_FUNC,
    SnsrClock clockFunc,
    double resolution
  );
  ```
  - **Input parameter:** `clockFunc`: [clock](https://doc.sensory.com/tnl/7.8/api/library-config.md#clock) function, returns number of clock ticks.
- **Input parameter:** `resolution`: The number of ticks per second.

**Example**

Example:
```c
#include <snsr.h>
#include <time.h>

static uint64_t clockFunc(void) {
  struct timespec t;
  clock_gettime(CLOCK_MONOTONIC, &t);
  return (uint64_t)t.tv_sec * 1e9 + (uint64_t)t.tv_nsec;
}

int main(int argc, char *argv[]) {
  snsrConfig(SNSR_CONFIG_CLOCK_FUNC, clockFunc, 1e9);
  // ...
}
```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [profile](https://doc.sensory.com/tnl/7.8/api/inference.md#profile), [push](https://doc.sensory.com/tnl/7.8/api/inference.md#push)

**`LICENSE`**

 Apply a software license key.

This overrides the software license key embedded in the
TrulyNatural SDK library. Use this to extend the expiration date
or to enable additional features.

[config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config) returns [OK](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_ok) if the SDK supports overriding
license keys and the license key format is valid,
[LICENSE_OVERRIDE_NOT_SUPPORTED](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_license_override_not_supported) if the SDK port does not
support override keys,
and [LICENSE_OVERRIDE_NOT_ENABLED](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_license_override_not_enabled) if the existing library
license key does not enable the override feature.

**snsrConfig() parameters**

  ```c
  SNSR_API SnsrRC
  snsrConfig(
    SNSR_CONFIG_LICENSE,
    const char *key,
    const char *secret
  );
  ```
  - **Input parameter:** `key`: This a cryptographically signed license key provided by Sensory. Use `NULL` to disable an existing key.
- **Input parameter:** `secret`: Secret string required to validate the key signature. Can be `NULL`. Provided by Sensory.

**Example**

This key expired on 2026-01-01 and disables all features. Do not use it your own code.

```c
const char *key =
  "eyJ2ZXIiOjEsInBsZCI6ImV5SnNhV05sYm5ObFpTSTZJbE5"
  "sYm5OdmNua2dRMjl1Wm1sa1pXNTBhV0ZzSUNBZ0lDSXNJbT"
  "F2WkhWc1pYTWlPaUl3SWl3aVpYaHdJam9pTmprMU5qSTVPR"
  "EFpTENKamJHbGxiblJKWkNJNklqQWlMQ0ppZFdsc1pDSTZP"
  "VFo5Iiwic2lnIjoiNjJLa0I2K2Nvdi9Fd2Y2eGppdDNlSWg"
  "xZDVrR1BCYmo3N3BLUWVqU3ZQSkg1Z0RqVGd6VWtOSCtBak"
  "diMTcwS2VUNThNN1laQmkwcG1lTEtGNWswRFE9PSJ9";
const char *secret =
  "019bb450-caa7-7c2a-b796-960f7d61dc2a";

snsrConfig(SNSR_CONFIG_LICENSE, key, secret);
```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [license keys](https://doc.sensory.com/tnl/7.8/reference/overview.md#license-keys)

**`LICENSE_INFO`**

 Inspect an override license key field.

Returns the string value for the specified override software
license key field.**Private function**

Do not use this without explicit instructions from Sensory.

<p markdown>[config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config) returns [OK](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_ok) if the SDK supports overriding
license keys and the license key format is valid,
[LICENSE_OVERRIDE_NOT_VALID](https://doc.sensory.com/tnl/7.8/api/inference.md#rc) if the override key does
not exist or did not pass validation,
[LICENSE_OVERRIDE_NOT_SUPPORTED](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_license_override_not_supported) if the SDK port does not
support override keys,
and [LICENSE_OVERRIDE_NOT_ENABLED](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_license_override_not_enabled) if the existing library
license key does not enable the override feature.

The returned string value is reference-counted. You must call
[release](https://doc.sensory.com/tnl/7.8/api/heap.md#release) on it before it goes out of scope or a memory leak will result.
The returned value will be `NULL` if the named field does not exist in the license key.<p>

**snsrConfig() parameters**

  ```c
  SNSR_API SnsrRC
  snsrConfig(
    SNSR_CONFIG_LICENSE,
    const char *field,
    const char *value
  );
  ```
  - **Input parameter:** `field`: The name of an override license key field.
- **Output parameter:** `value`: The string value for `field`. Reference-counted. Must be [release](https://doc.sensory.com/tnl/7.8/api/heap.md#release)d.

**Example**

```c
const char *expires;
SnsrRC r = snsrConfig(SNSR_CONFIG_LICENSE_INFO,
                      "exp", &expires);
```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [LICENSE](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_license), [license keys](https://doc.sensory.com/tnl/7.8/reference/overview.md#license-keys)

**`LICENSE_SUPPORT`**

<p markdown>  Software license key override support.

[config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config) returns [OK](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_ok) if the SDK supports overriding
license keys, [LICENSE_OVERRIDE_NOT_SUPPORTED](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_license_override_not_supported)
if the SDK port does not include support for overriding keys,
and [LICENSE_OVERRIDE_NOT_ENABLED](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_license_override_not_enabled) if the
existing library license key does not enable the override feature.

<p>You may retrieve this value even if active library handles exist.

**snsrConfig() parameters**

  ```c
  SNSR_API SnsrRC
  snsrConfig(
    SNSR_CONFIG_LICENSE_SUPPORT
  );
  ```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [LICENSE](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_license), [library-info](https://doc.sensory.com/tnl/7.8/api/setting-keys/library-information.md#library-info)

## Heap allocators

You can replace the heap memory allocator (`malloc()`, `realloc()`, `free()`)
used by the TrulyNatural SDK with alternate implementations. This is most useful
on small platforms where a standard library implementation is either not available,
or not recommended, or RAM use must be strictly constrained.

By default this library uses the dynamic memory allocation functions defined in `stdlib.h`.

Built-in allocators include [allocBuddy](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocbuddy), [allocStdlib](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocstdlib), [allocTLSF](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloctlsf)
(recommended), and an API for [creating your own](https://doc.sensory.com/tnl/7.8/api/library-config.md#user-defined-allocator).

### allocBuddy
<!-- tab: c -->

**C/C++**

```c
SNSR_API const SnsrAlloc_Vmt *
snsrAllocBuddy(void *poolStart, size_t poolSizeInBytes);
```

**Parameters and return value:**

**Input parameter:** `poolStart`

* Points to the start of a read-write memory segment to use as the allocator backing store. This address **must** be aligned to the word size of the CPU.

**Input parameter:** `poolSizeInBytes`

* the number of bytes available at `poolStart`.

**Return value:** * A new custom allocator definition.

Buddy allocator.

This is an implementation of the [Buddy memory allocation][bmem] heap
allocation algorithm. The size of returned blocks is the smallest
power-of-two in which the requested block size fits. This allocator
is fast and has low external fragmentation, but this comes at the expense
of significant internal fragmentation (e.g. a 1025 byte request requires
allocation of a 2048 byte block, wasting 1023 bytes).

This is a customization of the
[memsys5 allocator from SQLite][mem5] that is in the Public Domain.

**Example:**

```c
#define POOL_SIZE 128000
static size_t pool[POOL_SIZE / sizeof(size_t)];

// in main, before any other snsr* calls
snsrConfig(SNSR_CONFIG_ALLOC, snsrAllocBuddy(pool, sizeof(pool)));
```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [CONFIG_ALLOC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_alloc)

<!-- /tab -->

### allocLock
<!-- tab: c -->

**C/C++**

```c
SNSR_API const SnsrAlloc_Vmt *
snsrAllocLock(const SnsrAlloc_Vmt *vmt);
```

**Parameters and return value:**

**Input parameter:** `vmt`

* A custom allocator definition.

**Return value:** * A new custom allocator definition that is thread-safe.

Thread-safe allocator wrapper.

This takes a [heap allocator](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators) and adds mutual exclusion locks
to make it thread-safe.

This wrapper has no effect if the TrulyNatural SDK does not have
thread support on the target platform: The function adds the
lock wrapper only if `snsrConfig(SNSR_CONFIG_THREAD_SUPPORT) == SNSR_RC_OK`.

**Example:**

```c
#define POOL_SIZE 128000
static size_t pool[POOL_SIZE / sizeof(size_t)];

// in main, before any other snsr* calls
snsrConfig(SNSR_CONFIG_ALLOC, snsrAllocLock(snsrAllocTLSF(pool, sizeof(pool))));
```

**Also see these related items:** [allocBuddy](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocbuddy), [allocStdlib](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocstdlib), [allocTLSF](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloctlsf)

<!-- /tab -->

### allocPerf
<!-- tab: c -->

**C/C++**

```c
SNSR_API const SnsrAlloc_Vmt *
snsrAllocPerf(const SnsrAlloc_Vmt *vmt);
```

**Parameters and return value:**

**Input parameter:** `vmt`

* A custom allocator definition.

**Return value:** * A new custom allocator definition that gathers allocation statistics.

 Statistics-gathering allocator wrapper.

 Adds instrumentation to an allocator to determine the heap
 high-water mark, number of allocations, internal fragmentation overhead, etc.

**Warning:**

This wrapper adds mutual exclusion locks to the wrapped
allocator. Do not use with [allocLock](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloclock), as that will result in deadlock or undefined behavior.

**Note:**

     type: example
```c
// in main, before any other snsr* calls
snsrConfig(SNSR_CONFIG_ALLOC, snsrAllocPerf(snsrAllocStdlib()));

// application code
snsrTearDown();
snsrAllocPerfStats(snsrStreamFromFILE(stdout, SNSR_ST_MODE_WRITE));
```

**Also see these related items:** [allocBuddy](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocbuddy), [allocStdlib](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocstdlib), [allocTLSF](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloctlsf), [allocPerfStats](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocperfstats)

<!-- /tab -->

### allocPerfStats
<!-- tab: c -->

**C/C++**

```c
SNSR_API size_t
snsrAllocPerfStats(SnsrStream out);
```

**Parameters and return value:**

**Input parameter:** `out`

* A writable [Stream](https://doc.sensory.com/tnl/7.8/api/io.md#stream) to receive allocator statistics, or `NULL` to produce no output.

**Return value:** * The smallest heap pool size required to repeat the instrumented allocation run.

Show allocator statistics

Returns the smallest heap pool size that could be sufficient to
repeat the instrumented allocation run. To reduce the chance of
out-of-heap errors, allocate a pool that is at least 10% larger
than this minimum.

If the `out` [Stream](https://doc.sensory.com/tnl/7.8/api/io.md#stream) not `NULL`, this function writes heap allocator statistics
in human-readable form to this stream.

**Note:**

Requires use of [allocPerf](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocperf) to gather statistics.

**Also see these related items:** [allocPerf](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocperf)

<!-- /tab -->

### allocStdlib
<!-- tab: c -->

**C/C++**

```c
SNSR_API const SnsrAlloc_Vmt *
snsrAllocStdlib(void);
```

**Parameters and return value:**

**Return value:** * A new custom allocator definition.

Standard C library allocator.

This is the standard library allocator: `malloc()`, `realloc()`, and
`free()`. It is the default heap allocator used unless overridden with
[config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config).

**Warning:**

This allocator is not thread-safe. If your application runs
TrulyNatural SDK code from more than one execution thread you must add mutual
exclusion locking by wrapping this allocator with [allocLock](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloclock).

Whether this allocator works with [allocPerf](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocperf) depends on
whether the standard C library for the platform has a
`malloc_usable_size()` or `malloc_size()` implementation available.
If in doubt, use [allocTLSF](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloctlsf) for performance measurement instead.

**Example:**

```c
// in main, before any other snsr* calls
snsrConfig(SNSR_CONFIG_ALLOC, snsrAllocStdlib());
```

**Also see these related items:** [allocLock](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloclock), [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [CONFIG_ALLOC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_alloc)

<!-- /tab -->

### allocTLSF
- recommended
<!-- tab: c -->

**C/C++**

```c
SNSR_API const SnsrAlloc_Vmt *
snsrAllocTLSF(void *poolStart, size_t poolSizeInBytes);
```

**Parameters and return value:**

**Input parameter:** `poolStart`

* Points to the start of a read-write memory segment to use as the allocator backing store. This address **must** be aligned to the word size of the CPU.

**Input parameter:** `poolSizeInBytes`

* the number of bytes available at `poolStart`.

**Return value:** * A new custom allocator definition.

TLSF allocator.

The [Two-level Segregated Fit][tlsf] allocator is recommended
for embedded systems. It has `O(1)` cost for most operations,
low overhead, low internal fragmentation, and supports multiple
backing store pools for the heap.

This a customization of a [TLSF library][tlsfv3] that is in the Public Domain.

**Warning:**

This allocator is not thread-safe. If your application runs
TrulyNatural SDK code from more than one execution thread you must add mutual
exclusion locking by wrapping this allocator with [allocLock](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloclock).

**Example:**

```c
#define POOL_SIZE 128000
static size_t pool[POOL_SIZE / sizeof(size_t)];

// in main, before any other snsr* calls
snsrConfig(SNSR_CONFIG_ALLOC, snsrAllocTLSF(pool, sizeof(pool)));
```

**Also see these related items:** [allocLock](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloclock), [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [CONFIG_ALLOC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_alloc)

<!-- /tab -->

## User-defined allocator

You can create your own custom [heap allocator](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators) by implementing the
functions defined in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt), and then calling [`snsrConfig(SNSR_CONFIG_ALLOC, &vmt)`](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_alloc).

### alloc_Vmt

<!-- tab: c -->

**C/C++**

```c
typedef struct {
  void  *(*malloc)(void *ctx, size_t size); // (1)!
  void   (*free)(void *ctx, void *ptr); // (2)!
  void  *(*realloc)(void *ctx, void *ptr, size_t size); // (3)!
  size_t (*size)(void *ctx, void *ptr); // (4)!
  size_t (*roundUp)(void *ctx, size_t size); // (5)!
  size_t (*minPoolSize)(void *ctx, size_t maxAlloc, size_t maxCount); // (6)!
  SnsrAllocRC (*addPool)(void *ctx, void *pool, size_t size); // (7)!
  SnsrAllocRC (*setUp)(void *ctx); // (8)!
  SnsrAllocRC (*tearDown)(void *ctx); // (9)!
  void    *ctx; // Allocator context (10)
} SnsrAlloc_Vmt;
```

1. _(required)_ **Also see these related items:** [malloc](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-malloc)
2. _(required)_ **Also see these related items:** [free](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-free)
3. _(required)_ **Also see these related items:** [realloc](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-realloc)
4. _(optional)_ **Also see these related items:** [size](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-size)
5. _(optional)_ **Also see these related items:** [roundUp](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-roundUp)
6. _(optional)_ **Also see these related items:** [minPoolSize](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-minPoolSize)
7. _(optional)_ **Also see these related items:** [addPool](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-addPool)
8. _(optional)_ **Also see these related items:** [setUp](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-setUp)
9. _(optional)_ **Also see these related items:** [tearDown](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-tearDown)
10. _(required)_ `ctx` should point to the custom allocator data structure. It is passed to each implementation method as the first argument.

User-defined allocator virtual method table.

This method table defines a heap allocator to use in place of
`malloc()`, `realloc()`, and `free()` from `stdlib.h`.

The struct must remain valid until a call to [tearDown](https://doc.sensory.com/tnl/7.8/api/heap.md#teardown), or the application ends.

**Example:**

This minimal example wraps the standard C library allocator.

```c
static void *
vmtMalloc(void *ctx, size_t size) {
  return malloc(size);
}

static void *
vmtRealloc(void *ctx, void *ptr, size_t size) {
  return realloc(ptr, size);
}

static void
vmtFree(void *ctx, void *ptr)
{
  free(ptr);
}

static const SnsrAlloc_Vmt CustomAlloc = {
  vmtMalloc, vmtFree, vmtRealloc,
  NULL, NULL, NULL, NULL, NULL, NULL, NULL
};

// In main, before any other snsr* calls
snsrConfig(SNSR_CONFIG_ALLOC, &CustomAlloc);
```

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config), [CONFIG_ALLOC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_alloc), [AllocRC](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocrc), [malloc](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-malloc), [free](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-free), [realloc](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-realloc),
[size](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-size), [roundUp](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-roundUp), [minPoolSize](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-minPoolSize), [addPool](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-addPool),
[setUp](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-setUp), [tearDown](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-tearDown)

<!-- /tab -->

#### malloc
- required
<!-- tab: c -->

**C/C++**

```c
void *(*malloc)(void *ctx, size_t size);
```

**Parameters and return value:**

**Input parameter:** `ctx`

* The value of the `ctx` member in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt).

**Input parameter:** `size`

* Number of bytes to allocate. `size > 0`.

**Return value:** * A pointer to an aligned segment of writable memory, or `NULL` if memory could not be allocated.

Allocate memory from the heap.

This method should work like the standard library's `malloc()` function.
It should return a pointer to at least `size` bytes of writable memory,
aligned to at least the word size of the CPU.

**Also see these related items:** [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt)

<!-- /tab -->

#### free
- required
<!-- tab: c -->

**C/C++**

```c
void (*free)(void *ctx, void *ptr);
```

**Parameters and return value:**

**Input parameter:** `ctx`

* The value of the `ctx` member in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt).

**Input parameter:** `ptr`

* Pointer to previously allocated heap segment, as returned by [malloc](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-malloc), or [realloc](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-realloc).

Free memory allocated with the malloc or realloc methods.

This method should work like the standard library's `free()` function.

**Also see these related items:** [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt)

<!-- /tab -->

#### realloc
- required
<!-- tab: c -->

**C/C++**

```c
void *(*realloc)(void *ctx, void *ptr, size_t size);
```

**Parameters and return value:**

**Input parameter:** `ctx`

* The value of the `ctx` member in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt).

**Input parameter:** `ptr`

* Pointer to previously allocated heap segment, as returned by [malloc](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-malloc), or [realloc](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-realloc).

**Input parameter:** `size`

* Number of bytes to allocate.

**Return value:** * A pointer to an aligned segment of writable memory, or `NULL` if memory could not be allocated.

Allocate memory from the heap.

This method should work like the standard library's `malloc()` function.
It should return a pointer to at least `size` bytes of writable memory,
aligned to at least the word size of the CPU.

**Also see these related items:** [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt)

<!-- /tab -->

#### size
- optional
<!-- tab: c -->

**C/C++**

```c
size_t (*size)(void *ctx, void *ptr);
```

**Parameters and return value:**

**Input parameter:** `ctx`

* The value of the `ctx` member in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt).

**Input parameter:** `ptr`

* Pointer to previously allocated heap segment, as returned by [malloc](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-malloc), or [realloc](https://doc.sensory.com/tnl/7.8/api/library-config.md#vmt-realloc).

**Return value:** * The size of the memory block `ptr` points to.

Return the size of the ptr allocation.

This method should work like `malloc_size()` or `malloc_usable_size()`.
It should return the actual size of the block of memory allocated for
`ptr`. This will typically be a bit larger than the requested size.

**Note:**

This method is optional and used only by [allocPerf](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocperf).
If the allocation size is not available, set this method to `NULL`
and avoid using [allocPerf](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocperf).

**Also see these related items:** [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt)

<!-- /tab -->

#### roundUp
- optional
<!-- tab: c -->

**C/C++**

```c
size_t (*roundUp)(void *ctx, size_t size);
```

**Parameters and return value:**

**Input parameter:** `ctx`

* The value of the `ctx` member in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt).

**Input parameter:** `size`

* Request size in bytes.

**Return value:** * The size of the block that would be allocated for request `size`.

Return the allocation size for a given request size.

This returns the size of the block that would be allocated
when requesting a `size` byte segment.

**Note:**

This method is optional. If set to `NULL`, the block size
will be the requested `size` rounded up to the next multiple of 8.

**Also see these related items:** [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt)

<!-- /tab -->

#### minPoolSize
- optional
<!-- tab: c -->

**C/C++**

```c
size_t (*minPoolSize)(void *ctx, size_t maxAlloc, size_t maxCount);
```

**Parameters and return value:**

**Input parameter:** `ctx`

* The value of the `ctx` member in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt).

**Input parameter:** `maxAlloc`

* The high water mark of bytes allocated by the instrumented application.

**Input parameter:** `maxCount`

* The high water mark of the number of allocations made by the application.

**Return value:** * An estimate of the smallest backing store pool that could satisfy `maxAlloc` and `maxCount`.

Return an estimate of the pool size required.

This method returns an estimate of the smallest allocator pool
required to repeat an instrumented run.

**Note:**

This method is optional. If set to `NULL`, the estimated pool
size will not be available in [allocPerfStats](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocperfstats)

**Also see these related items:** [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt)

<!-- /tab -->

#### addPool
- optional
<!-- tab: c -->

**C/C++**

```c
SnsrAllocRC (*addPool)(void *ctx, void *pool, size_t size);
```

**Parameters and return value:**

**Input parameter:** `ctx`

* The value of the `ctx` member in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt).

**Input parameter:** `pool`

* `void *` to the start of a read-write memory segment to use as additional allocator store. This address must be aligned to the word size of the CPU.

**Input parameter:** `size`

* The number of bytes available at `pool`.

**Return value:** * [ALLOC_RC_OK](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_rc_ok) upon success, any other [AllocRC](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocrc) on failure.

Add a new backing store pool to the allocator.

This method adds a new pool to the backing store used for the heap.

**Note:**

This method is optional. If set to `NULL`, the allocator does
not support adding pools to the heap store.

**Also see these related items:** [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt), [AllocRC](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocrc)

<!-- /tab -->

#### setUp
- optional
<!-- tab: c -->

**C/C++**

```c
SnsrAllocRC (*setUp)(void *ctx);
```

**Parameters and return value:**

**Input parameter:** `ctx`

* The value of the `ctx` member in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt).

**Return value:** * [ALLOC_RC_OK](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_rc_ok) upon success, any other [AllocRC](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocrc) on failure.

Initialize the memory allocator.

This method is called before any other to initialize the allocator.

**Note:**

This method is optional. If set to `NULL`, no additional initialization is done.

**Also see these related items:** [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt), [AllocRC](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocrc)

<!-- /tab -->

#### tearDown
- optional
<!-- tab: c -->

**C/C++**

```c
SnsrAllocRC (*tearDown)(void *ctx);
```

**Parameters and return value:**

**Input parameter:** `ctx`

* The value of the `ctx` member in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt).

**Return value:** * [ALLOC_RC_OK](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_rc_ok) upon success, any other [AllocRC](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocrc) on failure.

Shut down the memory allocator.

This method should deallocate any resources this allocator initialized.

**Note:**

This method is optional. If set to `NULL`, no additional deallocation is done.

**Also see these related items:** [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt), [AllocRC](https://doc.sensory.com/tnl/7.8/api/library-config.md#allocrc)

<!-- /tab -->

### AllocRC
<!-- tab: c -->

**C/C++**

```c
typedef enum {
    SNSR_ALLOC_RC_{name},
    ...
} SnsrAllocRC;

// Where {name} is from the table below, e.g.: SNSR_ALLOC_RC_OK
```
<!-- /tab -->

This is the return code used by the implementation methods in [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt).

**Also see these related items:** [alloc_Vmt](https://doc.sensory.com/tnl/7.8/api/library-config.md#alloc_vmt)

**`OK`**

Success.

**`ERROR`**

Unspecified failure.

**`ALLOCATOR_EXISTS`**

Allocator already configured.

**`ALLOC_FAILED`**

Out of heap memory.

**`NO_FUNC`**

Required implementation method is `NULL`.

**`NOT_SUPPORTED`**

Not supported by this allocator.

<!-- template

### name
<!-- tab: c -->

**C/C++**

```c
```

**Parameters and return value:**

**Input parameter:** `s`

* [Session](https://doc.sensory.com/tnl/7.8/api/inference.md#session) handle.

**Return value:** * [OK](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_ok) for success, any other value indicates failure.

<!-- /tab -->

<!-- tab: java -->

**Java**

```java
```

**Parameters and return value:**

**Return value:** * The same [Session](https://doc.sensory.com/tnl/7.8/api/inference.md#session) instance, for method chaining.

<!-- /tab -->

-->

<!-- Reference definitions from includes/links.md -->
[bmem]: https://en.wikipedia.org/wiki/Buddy_memory_allocation "Buddy memory allocation"
[mem5]: https://www.sqlite.org/malloc.html#memsys5 "Zero-malloc memory allocator"
[printf()]: https://en.cppreference.com/w/c/io/fprintf "printf() standard C library function"
[tlsf]: http://www.gii.upv.es/tlsf/main/docs "Two-level Segregated Fit allocator"
[tlsfv3]: https://github.com/OlegHahm/tlsf/tree/27c65c2966dfc6f7055fbeaf63141ce39cc1f16c "TLSF library v3"
[undefined-behavior]: https://en.wikipedia.org/wiki/Undefined_behavior "Undefined program behavior"

<!-- Abbreviation definitions from includes/abbreviations.md -->
*[API]: Application Programming Interface
*[iff]: if, and only if
*[RAM]: Random Access Memory
*[RTOS]: Real-Time Operating System
*[SDK]: Software Development Kit
*[STT]: Speech To Text: transformers with language model and CTC decoding
*[TNL]: TrulyNatural, Sensory's large-vocabulary speech recognition technology
