mcap/modules/Default_Allocator/README.md
Musa Mahmood 22cad98500 [0.1.15] Startup: a catalog cache, the catalog on the background threads, rpmalloc, and [startup] timings
The catalog is kept in .catalog-cache in the library, each entry with the size and modified time of
the file it was read from; a start takes the entries whose file is unchanged from it and reads only
the rest. It is saved once the catalog is complete and has changed (at most every 30 s) and at
shutdown. After a reboot the catalog was complete 145 ms after launch, against 3.5 s reading every
file.

The catalog loads on the background Thread_Group, every worker of it, instead of the four preview
workers. rpmalloc (modules/Default_Allocator, 2.0.1-jai.16) takes the place of Jai's single locked
heap: entries from the cache 380 -> 50 ms, and reading the files now scales with threads.
thread_idle is called where workers idle. check_targets.jai checks other OSes with Jai's own
allocator, as rpmalloc runs at compile time with the target's OS layer.

-cold drops the library from the system's file cache first; -no-catalog-cache and -catalog-threads N
are for measuring. [startup] log lines time the listing, the first frame, the cache, the first
preview and the complete catalog.
2026-10-13 07:26:42 +01:00

60 lines
3.3 KiB
Markdown

# Default_Allocator (rpmalloc 2.0.1 port)
A drop-in replacement for Jai's `modules/Default_Allocator`: the rpmalloc 2.0.1 port, wrapped in the interface Jai's runtime expects. This directory holds only what differs from the port's other flavour. `install.jai` at the repository root puts it together with the shared allocator files.
## Installing it
From the repository root (`my_modules/rpmalloc`):
```sh
jai install.jai - Default_Allocator PROJECT/modules
```
Run the same command again to update the copy when the repository has a newer `VERSION_REVISION`. Add `check` to see what it would do. The repository's `README.md` describes every case.
## Using it
Jai picks its default allocator by module name: `Runtime_Support.jai` imports `"Default_Allocator"`. `PROJECT/modules` has to come ahead of Jai's own `modules` directory on the import path:
- Jai searches the working directory's `modules/` folder first, so building from the project's root is enough: `jai main.jai`.
- From elsewhere, or to be explicit: `jai main.jai -import_dir PROJECT/modules`, or in a build program prepend the directory to `Build_Options.import_path`:
```jai
paths: [..] string;
array_add(*paths, "PROJECT/modules");
array_add(*paths, ..options.import_path);
options.import_path = paths;
```
Every allocation the program makes then goes through this allocator, from the first one, and at compile time too. Nothing needs to set `context.allocator`.
**Thread pools:** call `Default_Allocator.thread_idle()` where a pool thread waits for work. Each thread has its own heap, and an idle thread makes no allocator calls, so without it the memory other threads free into that heap stays committed until the thread wakes (DIFFERENCES.md, section 4).
To check which allocator, and which version, a program is using:
```jai
name: string;
context.allocator.proc(.CAPS, 0, 0, *name, context.allocator.data);
// "rpmalloc 2.0.1-jai.N (Jai port) as Default_Allocator", N being VERSION_REVISION
```
`Default_Allocator.VERSION` holds the same version (`version.jai` in the installed copy).
**Supported:** 64-bit Windows and macOS (tested), and Linux (type-checked only). Other targets stop with an `#assert`; build them without this module on the import path.
**Read [DIFFERENCES.md](DIFFERENCES.md) before switching a project.** In particular, RESIZE relies on `old_size`, memory retention differs, and huge-block churn is slower.
## Files
| File | In the repository | Installed copy |
|---|---|---|
| `module.jai` | `Default_Allocator/module.jai`: Jai's `Default_Allocator` interface (`allocator`, `allocator_proc`, `unsafe_reset`, `initialize_if_needed`, …) and the port's public types | `module.jai` |
| `README.md`, `DIFFERENCES.md` | `Default_Allocator/` | the same names |
| `rpmalloc.jai`, `os_windows.jai`, `os_posix.jai`, `version.jai`, `LICENSE`, `LICENSES/` | the repository root, shared with the `rpmalloc2` flavour | the same names |
`module.jai` loads the shared files from its own directory, so it builds only in an installed copy. In the repository, `tests/` checks it with `jai build.jai - swap`, which installs this flavour into a scratch directory and runs a program on it.
When the port's `module.jai` changes the protocol procedure or the public types, bring this `module.jai` up to date by hand. It has its own copy of both.
License: rpmalloc is dual licensed Unlicense / MIT (`LICENSE`, `LICENSES/`).