mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
terminal/new: clean up
This commit is contained in:
@ -10,5 +10,7 @@
|
|||||||
hyperfine \
|
hyperfine \
|
||||||
--warmup 10 \
|
--warmup 10 \
|
||||||
-n alloc \
|
-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"
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ const Args = struct {
|
|||||||
mode: Mode = .alloc,
|
mode: Mode = .alloc,
|
||||||
|
|
||||||
/// The number of pages to create sequentially.
|
/// The number of pages to create sequentially.
|
||||||
count: usize = 208_235,
|
count: usize = 10_000,
|
||||||
|
|
||||||
/// This is set by the CLI parser for deinit.
|
/// This is set by the CLI parser for deinit.
|
||||||
_arena: ?ArenaAllocator = null,
|
_arena: ?ArenaAllocator = null,
|
||||||
@ -28,6 +28,9 @@ const Args = struct {
|
|||||||
const Mode = enum {
|
const Mode = enum {
|
||||||
/// The default allocation strategy of the structure.
|
/// The default allocation strategy of the structure.
|
||||||
alloc,
|
alloc,
|
||||||
|
|
||||||
|
/// Use a memory pool to allocate pages from a backing buffer.
|
||||||
|
pool,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const std_options: std.Options = .{
|
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.
|
// Handle the modes that do not depend on terminal state first.
|
||||||
switch (args.mode) {
|
switch (args.mode) {
|
||||||
.alloc => try benchAlloc(args.count),
|
.alloc => try benchAlloc(args.count),
|
||||||
|
.pool => try benchPool(alloc, args.count),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
noinline fn benchAlloc(count: usize) !void {
|
noinline fn benchAlloc(count: usize) !void {
|
||||||
for (0..count) |_| {
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,20 +20,6 @@ const Page = pagepkg.Page;
|
|||||||
/// window to scroll into quickly.
|
/// window to scroll into quickly.
|
||||||
const page_preheat = 4;
|
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
|
/// 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
|
/// where the first page is the topmost page (scrollback) and the last is
|
||||||
/// the bottommost page (the current active page).
|
/// the bottommost page (the current active page).
|
||||||
@ -43,8 +29,14 @@ const List = std.DoublyLinkedList(Page);
|
|||||||
const Pool = std.heap.MemoryPool(List.Node);
|
const Pool = std.heap.MemoryPool(List.Node);
|
||||||
|
|
||||||
const std_capacity = pagepkg.std_capacity;
|
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.
|
/// The allocator to use for pages.
|
||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
@ -81,6 +73,9 @@ pub const Viewport = union(enum) {
|
|||||||
active,
|
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(
|
pub fn init(
|
||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
cols: size.CellCountInt,
|
cols: size.CellCountInt,
|
||||||
@ -99,35 +94,24 @@ pub fn init(
|
|||||||
errdefer page_pool.deinit();
|
errdefer page_pool.deinit();
|
||||||
|
|
||||||
var page = try pool.create();
|
var page = try pool.create();
|
||||||
// no errdefer because the pool deinit will clean up the page
|
|
||||||
const page_buf = try page_pool.create();
|
const page_buf = try page_pool.create();
|
||||||
if (comptime std.debug.runtime_safety) @memset(page_buf, 0);
|
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.* = .{
|
page.* = .{
|
||||||
.data = Page.initBuf(
|
.data = Page.initBuf(
|
||||||
OffsetBuf.init(page_buf),
|
OffsetBuf.init(page_buf),
|
||||||
Page.layout(try std_capacity.adjust(.{ .cols = cols })),
|
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;
|
page.data.size.rows = rows;
|
||||||
|
|
||||||
var page_list: List = .{};
|
var page_list: List = .{};
|
||||||
page_list.prepend(page);
|
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 .{
|
return .{
|
||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
.cols = cols,
|
.cols = cols,
|
||||||
|
@ -246,5 +246,5 @@ test "Screen read and write" {
|
|||||||
try s.testWriteString("hello, world");
|
try s.testWriteString("hello, world");
|
||||||
const str = try s.dumpStringAlloc(alloc, .{ .screen = .{} });
|
const str = try s.dumpStringAlloc(alloc, .{ .screen = .{} });
|
||||||
defer alloc.free(str);
|
defer alloc.free(str);
|
||||||
//try testing.expectEqualStrings("hello, world", str);
|
try testing.expectEqualStrings("hello, world", str);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
const page = @import("page.zig");
|
pub const page = @import("page.zig");
|
||||||
pub const PageList = @import("PageList.zig");
|
pub const PageList = @import("PageList.zig");
|
||||||
pub const Terminal = @import("Terminal.zig");
|
pub const Terminal = @import("Terminal.zig");
|
||||||
pub const Page = page.Page;
|
pub const Page = page.Page;
|
||||||
|
Reference in New Issue
Block a user