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.
3.3 KiB
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):
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 toBuild_Options.import_path: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:
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 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/).