lib/gpalloc/src/root.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 //! `GpAllocator` provides a general-purpose heap over a caller-supplied
 2 //! `std.mem.Allocator` stored at init and asked for pages and large blocks, the
 3 //! *backing allocator*. A request up to 32 KiB takes the first class at least
 4 //! as large as itself from a fixed list of 40 block sizes, its *size class*,
 5 //! with blocks carved from a 64 KiB span, a *page*. Each thread keeps its own
 6 //! array of free blocks per size class in thread-local storage, the *thread
 7 //! cache*. With the thread cache on, an allocation pops a block from the
 8 //! running thread's bin for that class and a free pushes one back, so the
 9 //! common path takes no lock.
10 //!
11 //! Per-size-class state guarded by that class's mutex, the *bin*, holds that
12 //! class's pages. The bounded list inside the bin that collects blocks drained
13 //! from thread caches and refills them in batches is the *transfer list*. An
14 //! empty thread bin refills from it, drawing a batch of blocks from the
15 //! transfer list under the class mutex. A full thread bin drains a batch back
16 //! to that transfer list under the same mutex, and a block freed by a thread
17 //! other than the one that allocated it goes back the same way. Batching keeps
18 //! the class mutex out of the common path, because one lock covers a whole
19 //! batch of blocks.
20 //!
21 //! A request above the small range goes to the backing allocator through a
22 //! cache of retained blocks per class, the *large cache*, bounded by a byte
23 //! limit.
24 //!
25 //! Small pages come from the *page provider*, which is the backing allocator by
26 //! default, and `.page_provider = .os` maps them from the operating system.
27 //!
28 //! Counters are off by default, and turning them on with
29 //! `.collect_stats = true` also turns off the thread cache and the large cache,
30 //! so a run that collects counters measures a different path from the one that
31 //! runs without them.
32 //!
33 //! A thread that exits hands its cache back to the heap, and a thread the
34 //! runtime cannot hook does the same by calling
35 //! `flushThreadCacheForCurrentThread`.
36 
37 const allocator_mod = @import("allocator.zig");
38 pub const cache = @import("cache/root.zig");
39 pub const class = @import("class.zig");
40 pub const config = @import("config.zig");
41 pub const large = @import("large/root.zig");
42 pub const page = @import("page/root.zig");
43 pub const stats = @import("stats.zig");
44 
45 pub const Config = config.Config;
46 pub const PageProvider = config.PageProvider;
47 pub const RetainedEmptyPagePolicy = config.RetainedEmptyPagePolicy;
48 pub const Stats = stats.Stats;
49 pub const GpAllocator = allocator_mod.GpAllocator;
50 pub const class_sizes = config.class_sizes;
51 pub const max_small_size = config.max_small_size;
52 pub const min_alignment = config.min_alignment;
53 pub const page_size = config.page_size;