mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-09-14 18:01:58 +00:00
This replaces the `std.heap.MemoryPool` used for page buffers with a custom pool called `UntouchedPool`. This keeps its free list in a side array and never reads/writes items until `create()`. This means that demand-driven allocations (like mmaped pages) don't incur physical costs until they're actually used. The standard `std.heap.MemoryPool` uses an intrusive linked list for its items which causes every item to be touched, which forces a full page-in of memory. It turns out we also had a lot of assertions and logic to work around this in various ways (size of rows, asserting we overwrite the free list entry, etc.) that we can now remove because of this. For an 80x24 terminal on macOS (16 KB pages): | Per terminal | Before | After | |------------------------------|----------|----------| | Page-list memory dirty | 128 KiB | 48 KiB | | Process phys_footprint delta | 143 KiB | 62 KiB | | Page-list virtual size | 2208 KiB | 1600 KiB | The remaining 48 KB is the active page, because we sprinkle metadata around the page which forces every page to be paged in. I'm going to follow this up with some work trying to move all our metadata to the front of the page so we only page one in until the rest is needed, but not sure if its achievable. Micro-benchmarks on the pool show that its twice the speed (slower) to create/free due to the side list, but in an actual `+terminal-stream` benchmark churning through pages, there is no measurable difference. I think its a good trade.
25 lines
1007 B
Zig
25 lines
1007 B
Zig
//! The datastruct package contains data structures or anything closely
|
|
//! related to data structures.
|
|
|
|
const blocking_queue = @import("blocking_queue.zig");
|
|
const cache_table = @import("cache_table.zig");
|
|
const circ_buf = @import("circ_buf.zig");
|
|
const intrusive_linked_list = @import("intrusive_linked_list.zig");
|
|
const split_tree = @import("split_tree.zig");
|
|
|
|
pub const BlockingQueue = blocking_queue.BlockingQueue;
|
|
pub const CacheTable = cache_table.CacheTable;
|
|
pub const CircBuf = circ_buf.CircBuf;
|
|
pub const IntrusiveDoublyLinkedList = intrusive_linked_list.DoublyLinkedList;
|
|
pub const LimitedAllocator = @import("limited_allocator.zig").LimitedAllocator;
|
|
pub const MessageData = @import("message_data.zig").MessageData;
|
|
pub const SplitTree = split_tree.SplitTree;
|
|
pub const UntouchedPool = @import("untouched_pool.zig").UntouchedPool;
|
|
pub const WasmPagePool = @import("wasm_page_pool.zig").WasmPagePool;
|
|
|
|
test {
|
|
@import("std").testing.refAllDecls(@This());
|
|
|
|
_ = @import("comparison.zig");
|
|
}
|