terminal/new: clean up

This commit is contained in:
Mitchell Hashimoto
2024-02-23 12:58:48 -08:00
parent 1088176f94
commit de3d1e4df7
5 changed files with 40 additions and 36 deletions

View File

@ -10,5 +10,7 @@
hyperfine \
--warmup 10 \
-n alloc \
"./zig-out/bin/bench-page-init --mode=alloc${ARGS} </tmp/ghostty_bench_data"
"./zig-out/bin/bench-page-init --mode=alloc${ARGS} </tmp/ghostty_bench_data" \
-n pool \
"./zig-out/bin/bench-page-init --mode=pool${ARGS} </tmp/ghostty_bench_data"

View File

@ -14,7 +14,7 @@ const Args = struct {
mode: Mode = .alloc,
/// The number of pages to create sequentially.
count: usize = 208_235,
count: usize = 10_000,
/// This is set by the CLI parser for deinit.
_arena: ?ArenaAllocator = null,
@ -28,6 +28,9 @@ const Args = struct {
const Mode = enum {
/// The default allocation strategy of the structure.
alloc,
/// Use a memory pool to allocate pages from a backing buffer.
pool,
};
pub const std_options: std.Options = .{
@ -50,11 +53,26 @@ pub fn main() !void {
// Handle the modes that do not depend on terminal state first.
switch (args.mode) {
.alloc => try benchAlloc(args.count),
.pool => try benchPool(alloc, args.count),
}
}
noinline fn benchAlloc(count: usize) !void {
for (0..count) |_| {
_ = try terminal.new.Page.init(terminal.new.Page.std_capacity);
_ = try terminal.new.Page.init(terminal.new.page.std_capacity);
}
}
noinline fn benchPool(alloc: Allocator, count: usize) !void {
var list = try terminal.new.PageList.init(
alloc,
terminal.new.page.std_capacity.cols,
terminal.new.page.std_capacity.rows,
0,
);
defer list.deinit();
for (0..count) |_| {
_ = try list.grow();
}
}

View File

@ -20,20 +20,6 @@ const Page = pagepkg.Page;
/// window to scroll into quickly.
const page_preheat = 4;
/// The default number of unique styles per page we expect. It is currently
/// "32" because anecdotally amongst a handful of beta testers, no one
/// under normal terminal use ever used more than 32 unique styles in a
/// single page. We found outliers but it was rare enough that we could
/// allocate those when necessary.
const page_default_styles = 32;
/// Minimum rows we ever initialize a page with. This is wasted memory if
/// too large, but saves us from allocating too many pages when a terminal
/// is small. It also lets us scroll more before we have to allocate more.
/// Tne number 100 is arbitrary. I'm open to changing it if we find a
/// better number.
const page_min_rows: size.CellCountInt = 100;
/// The list of pages in the screen. These are expected to be in order
/// where the first page is the topmost page (scrollback) and the last is
/// the bottommost page (the current active page).
@ -43,8 +29,14 @@ const List = std.DoublyLinkedList(Page);
const Pool = std.heap.MemoryPool(List.Node);
const std_capacity = pagepkg.std_capacity;
const std_layout = Page.layout(std_capacity);
const PagePool = std.heap.MemoryPoolAligned([std_layout.total_size]u8, std.mem.page_size);
/// The memory pool we use for page memory buffers. We use a separate pool
/// so we can allocate these with a page allocator. We have to use a page
/// allocator because we need memory that is zero-initialized and page-aligned.
const PagePool = std.heap.MemoryPoolAligned(
[Page.layout(std_capacity).total_size]u8,
std.mem.page_size,
);
/// The allocator to use for pages.
alloc: Allocator,
@ -81,6 +73,9 @@ pub const Viewport = union(enum) {
active,
};
/// Initialize the page. The top of the first page in the list is always the
/// top of the active area of the screen (important knowledge for quickly
/// setting up cursors in Screen).
pub fn init(
alloc: Allocator,
cols: size.CellCountInt,
@ -99,35 +94,24 @@ pub fn init(
errdefer page_pool.deinit();
var page = try pool.create();
// no errdefer because the pool deinit will clean up the page
const page_buf = try page_pool.create();
if (comptime std.debug.runtime_safety) @memset(page_buf, 0);
// no errdefer because the pool deinit will clean these up
// Initialize the first set of pages to contain our viewport so that
// the top of the first page is always the active area.
page.* = .{
.data = Page.initBuf(
OffsetBuf.init(page_buf),
Page.layout(try std_capacity.adjust(.{ .cols = cols })),
),
};
errdefer page.data.deinit(alloc);
assert(page.data.capacity.rows >= rows); // todo: handle this
page.data.size.rows = rows;
var page_list: List = .{};
page_list.prepend(page);
// for (0..1) |_| {
// const p = try pool.create();
// p.* = .{
// .data = try Page.init(alloc, .{
// .cols = cols,
// .rows = @max(rows, page_min_rows),
// .styles = page_default_styles,
// }),
// };
// p.data.size.rows = 0;
// page_list.append(p);
// }
return .{
.alloc = alloc,
.cols = cols,

View File

@ -246,5 +246,5 @@ test "Screen read and write" {
try s.testWriteString("hello, world");
const str = try s.dumpStringAlloc(alloc, .{ .screen = .{} });
defer alloc.free(str);
//try testing.expectEqualStrings("hello, world", str);
try testing.expectEqualStrings("hello, world", str);
}

View File

@ -1,6 +1,6 @@
const builtin = @import("builtin");
const page = @import("page.zig");
pub const page = @import("page.zig");
pub const PageList = @import("PageList.zig");
pub const Terminal = @import("Terminal.zig");
pub const Page = page.Page;