diff --git a/src/bench/page-init.sh b/src/bench/page-init.sh index f54df627b..54712250b 100755 --- a/src/bench/page-init.sh +++ b/src/bench/page-init.sh @@ -10,5 +10,7 @@ hyperfine \ --warmup 10 \ -n alloc \ - "./zig-out/bin/bench-page-init --mode=alloc${ARGS} 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(); } } diff --git a/src/terminal/new/PageList.zig b/src/terminal/new/PageList.zig index e605f26e7..2f3d407dc 100644 --- a/src/terminal/new/PageList.zig +++ b/src/terminal/new/PageList.zig @@ -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, diff --git a/src/terminal/new/Screen.zig b/src/terminal/new/Screen.zig index 4d899a1fd..7f6552675 100644 --- a/src/terminal/new/Screen.zig +++ b/src/terminal/new/Screen.zig @@ -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); } diff --git a/src/terminal/new/main.zig b/src/terminal/new/main.zig index cac9fa6ab..312dafc16 100644 --- a/src/terminal/new/main.zig +++ b/src/terminal/new/main.zig @@ -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;