diff options
| author | Bobby <[email protected]> | 2026-02-23 13:13:17 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-02-23 13:13:17 +0530 |
| commit | 2e2235ad7d1828054461da08cc4ba7f0e27bc012 (patch) | |
| tree | 5b5b2a003654103e43337a0cd575d81f93d3147c | |
| parent | 052c2cff84904bf0aaf5e90770ba2229f760a7d8 (diff) | |
| download | akiba-2e2235ad7d1828054461da08cc4ba7f0e27bc012.tar.xz akiba-2e2235ad7d1828054461da08cc4ba7f0e27bc012.zip | |
fix: dynamic attachments in kata
| -rw-r--r-- | mirai/common/limits/attachment.zig | 2 | ||||
| -rw-r--r-- | mirai/common/limits/kata.zig | 2 | ||||
| -rw-r--r-- | mirai/invocations/io/attach.zig | 26 | ||||
| -rw-r--r-- | mirai/invocations/io/mark.zig | 12 | ||||
| -rw-r--r-- | mirai/invocations/io/seal.zig | 5 | ||||
| -rw-r--r-- | mirai/invocations/io/view.zig | 12 | ||||
| -rw-r--r-- | mirai/invocations/kata/exit.zig | 6 | ||||
| -rw-r--r-- | mirai/kata/attachment.zig | 26 | ||||
| -rw-r--r-- | mirai/kata/pool.zig | 20 | ||||
| -rw-r--r-- | mirai/kata/types.zig | 2 | ||||
| -rw-r--r-- | mirai/utils/kata/attachment.zig | 8 |
11 files changed, 82 insertions, 39 deletions
diff --git a/mirai/common/limits/attachment.zig b/mirai/common/limits/attachment.zig index 844f15a..511ba9d 100644 --- a/mirai/common/limits/attachment.zig +++ b/mirai/common/limits/attachment.zig @@ -1,3 +1,3 @@ //! Attachment limits -pub const MAX_LOCATION_LENGTH: usize = 128; +pub const MAX_LOCATION_LENGTH: usize = 256; diff --git a/mirai/common/limits/kata.zig b/mirai/common/limits/kata.zig index d5f59fa..6f827f3 100644 --- a/mirai/common/limits/kata.zig +++ b/mirai/common/limits/kata.zig @@ -4,5 +4,5 @@ pub const MAX_KATAS: usize = 64; pub const MAX_ATTACHMENTS: usize = 16; pub const MAX_PARAMETERS: usize = 64; pub const MAX_ENV_VARS: usize = 64; -pub const MAX_LOCATION_LENGTH: usize = 128; +pub const MAX_LOCATION_LENGTH: usize = 256; pub const MAX_LETTER_LENGTH: usize = 256; diff --git a/mirai/invocations/io/attach.zig b/mirai/invocations/io/attach.zig index 24dc154..4923eb0 100644 --- a/mirai/invocations/io/attach.zig +++ b/mirai/invocations/io/attach.zig @@ -48,11 +48,13 @@ fn open_device(kata: *kata_mod.Kata, location: []const u8, flags: u32) !u32 { if (compare.equals(name, "source")) .Source else if (compare.equals(name, "stream")) .Stream else if (compare.equals(name, "trace")) .Trace else if (compare.equals(name, "void")) .Void else if (compare.equals(name, "chaos")) .Chaos else if (compare.equals(name, "zero")) .Zero else if (compare.equals(name, "console")) .Console else return error.UnknownDevice; const fd = try attachment_util.allocate(kata); - kata.attachments[fd] = kata_attachment.Attachment{ + const entry = kata_attachment.alloc() orelse return error.OutOfMemory; + entry.* = .{ .attachment_type = .Device, .device_type = device_type, .flags = flags, }; + kata.attachments[fd] = entry; return fd; } @@ -64,29 +66,38 @@ fn open_unit(kata: *kata_mod.Kata, location: []const u8, flags: u32) !u32 { const full_location = location_util.resolve(kata, location, &full_location_buf); const fd = try attachment_util.allocate(kata); + const entry = kata_attachment.alloc() orelse return error.OutOfMemory; var unit_buffer: [1024 * 1024]u8 = undefined; const bytes_read = fs.view_unit_at(full_location, &unit_buffer) catch { if (flags & attachment_const.CREATE != 0) { - fs.create_unit(full_location) catch return error.CannotCreate; + fs.create_unit(full_location) catch { + kata_attachment.free(entry); + return error.CannotCreate; + }; - kata.attachments[fd] = kata_attachment.Attachment{ + entry.* = .{ .attachment_type = .Unit, .unit_size = 0, .position = 0, .flags = flags, .location_len = location.len, }; - copy.bytes(kata.attachments[fd].location[0..location.len], location); + copy.bytes(entry.location[0..location.len], location); + kata.attachments[fd] = entry; return fd; } + kata_attachment.free(entry); return error.UnitNotFound; }; - const unit_data = heap.alloc(bytes_read) orelse return error.OutOfMemory; + const unit_data = heap.alloc(bytes_read) orelse { + kata_attachment.free(entry); + return error.OutOfMemory; + }; copy.bytes(unit_data[0..bytes_read], unit_buffer[0..bytes_read]); - kata.attachments[fd] = kata_attachment.Attachment{ + entry.* = .{ .attachment_type = .Unit, .buffer = unit_data[0..bytes_read], .unit_size = bytes_read, @@ -94,7 +105,8 @@ fn open_unit(kata: *kata_mod.Kata, location: []const u8, flags: u32) !u32 { .flags = flags, .location_len = location.len, }; - copy.bytes(kata.attachments[fd].location[0..location.len], location); + copy.bytes(entry.location[0..location.len], location); + kata.attachments[fd] = entry; return fd; } diff --git a/mirai/invocations/io/mark.zig b/mirai/invocations/io/mark.zig index 9568749..2566d83 100644 --- a/mirai/invocations/io/mark.zig +++ b/mirai/invocations/io/mark.zig @@ -6,7 +6,6 @@ const handler = @import("../handler.zig"); const int = @import("../../utils/types/int.zig"); const io_limits = @import("../../common/limits/io.zig"); const kata_limits = @import("../../common/limits/kata.zig"); -const kata_mod = @import("../../kata/kata.zig"); const memory_limits = @import("../../common/limits/memory.zig"); const result = @import("../../utils/types/result.zig"); const sensei = @import("../../kata/sensei/sensei.zig"); @@ -20,20 +19,17 @@ pub fn invoke(ctx: *handler.InvocationContext) void { const count = ctx.rdx; const color = int.u32_of(ctx.r10); - if (fd >= kata_limits.MAX_ATTACHMENTS or kata.attachments[fd].attachment_type == .Closed) { - return result.set_error(ctx); - } + if (fd >= kata_limits.MAX_ATTACHMENTS) return result.set_error(ctx); + const entry = kata.attachments[fd] orelse return result.set_error(ctx); - const bytes = mark_to_attachment(kata, fd, buffer_ptr, count, color) catch return result.set_error(ctx); + const bytes = mark_to_attachment(entry, buffer_ptr, count, color) catch return result.set_error(ctx); result.set_value(ctx, bytes); } -fn mark_to_attachment(kata: *kata_mod.Kata, fd: u32, buffer_ptr: u64, count: u64, color: u32) !u64 { +fn mark_to_attachment(entry: *fd_mod.Attachment, buffer_ptr: u64, count: u64, color: u32) !u64 { if (count == 0) return 0; if (count > io_limits.MAX_MARK_SIZE) return error.MarkTooLarge; - const entry = &kata.attachments[fd]; - if (entry.attachment_type == .Device) { const device = entry.device_type orelse return error.InvalidDevice; return mark_to_device(device, buffer_ptr, count, color); diff --git a/mirai/invocations/io/seal.zig b/mirai/invocations/io/seal.zig index 7b9daa7..d798752 100644 --- a/mirai/invocations/io/seal.zig +++ b/mirai/invocations/io/seal.zig @@ -20,9 +20,8 @@ pub fn invoke(ctx: *handler.InvocationContext) void { const fd = int.u32_of(ctx.rdi); - if (fd >= kata_limits.MAX_ATTACHMENTS or kata.attachments[fd].attachment_type == .Closed) { - return result.set_error(ctx); - } + if (fd >= kata_limits.MAX_ATTACHMENTS) return result.set_error(ctx); + if (kata.attachments[fd] == null) return result.set_error(ctx); attachment.seal(kata, fd, afs_instance); result.set_ok(ctx); diff --git a/mirai/invocations/io/view.zig b/mirai/invocations/io/view.zig index 7edae8f..349af7a 100644 --- a/mirai/invocations/io/view.zig +++ b/mirai/invocations/io/view.zig @@ -5,7 +5,6 @@ const handler = @import("../handler.zig"); const int = @import("../../utils/types/int.zig"); const kata_attachment = @import("../../kata/attachment.zig"); const kata_limits = @import("../../common/limits/kata.zig"); -const kata_mod = @import("../../kata/kata.zig"); const keyboard = @import("../../drivers/keyboard/keyboard.zig"); const random = @import("../../utils/random/xorshift.zig"); const result = @import("../../utils/types/result.zig"); @@ -19,17 +18,14 @@ pub fn invoke(ctx: *handler.InvocationContext) void { const buffer_ptr = ctx.rsi; const count = ctx.rdx; - if (fd >= kata_limits.MAX_ATTACHMENTS or kata.attachments[fd].attachment_type == .Closed) { - return result.set_error(ctx); - } + if (fd >= kata_limits.MAX_ATTACHMENTS) return result.set_error(ctx); + const entry = kata.attachments[fd] orelse return result.set_error(ctx); - const bytes = view_from_attachment(kata, fd, buffer_ptr, count) catch return result.set_error(ctx); + const bytes = view_from_attachment(entry, buffer_ptr, count) catch return result.set_error(ctx); result.set_value(ctx, bytes); } -fn view_from_attachment(kata: *kata_mod.Kata, fd: u32, buffer_ptr: u64, count: u64) !u64 { - const entry = &kata.attachments[fd]; - +fn view_from_attachment(entry: *kata_attachment.Attachment, buffer_ptr: u64, count: u64) !u64 { if (entry.attachment_type == .Device) { const device = entry.device_type orelse return error.InvalidDevice; return view_from_device(device, buffer_ptr, count); diff --git a/mirai/invocations/kata/exit.zig b/mirai/invocations/kata/exit.zig index 4799eb8..fd9ec9d 100644 --- a/mirai/invocations/kata/exit.zig +++ b/mirai/invocations/kata/exit.zig @@ -20,8 +20,10 @@ pub fn invoke(ctx: *handler.InvocationContext) void { var i: u32 = 0; while (i < kata_limits.MAX_ATTACHMENTS) : (i += 1) { - if (kata.attachments[i].attachment_type == .Unit) { - attachment.seal(kata, i, afs_instance); + if (kata.attachments[i]) |entry| { + if (entry.attachment_type == .Unit) { + attachment.seal(kata, i, afs_instance); + } } } diff --git a/mirai/kata/attachment.zig b/mirai/kata/attachment.zig index 05bea8a..9d9ed35 100644 --- a/mirai/kata/attachment.zig +++ b/mirai/kata/attachment.zig @@ -1,6 +1,7 @@ //! Attachment management const attachment_limits = @import("../common/limits/attachment.zig"); +const kata_limits = @import("../common/limits/kata.zig"); pub const Type = enum { Unit, @@ -31,3 +32,28 @@ pub const Attachment = struct { device_type: ?DeviceType = null, }; + +const POOL_SIZE = kata_limits.MAX_KATAS * kata_limits.MAX_ATTACHMENTS; +var pool: [POOL_SIZE]Attachment = undefined; +var pool_used: [POOL_SIZE]bool = [_]bool{false} ** POOL_SIZE; + +pub fn alloc() ?*Attachment { + for (&pool, 0..) |*entry, i| { + if (!pool_used[i]) { + pool_used[i] = true; + entry.* = Attachment{}; + return entry; + } + } + return null; +} + +pub fn free(ptr: *Attachment) void { + const addr = @intFromPtr(ptr); + const base = @intFromPtr(&pool[0]); + const size = @sizeOf(Attachment); + if (addr >= base and addr < base + POOL_SIZE * size) { + const idx = (addr - base) / size; + pool_used[idx] = false; + } +} diff --git a/mirai/kata/pool.zig b/mirai/kata/pool.zig index 8c057f9..3d7d014 100644 --- a/mirai/kata/pool.zig +++ b/mirai/kata/pool.zig @@ -31,23 +31,29 @@ pub fn create() !*types.Kata { kata.current_location[0] = '/'; - kata.attachments[0] = attachment.Attachment{ + const stdin = attachment.alloc() orelse return error.OutOfMemory; + stdin.* = .{ .attachment_type = .Device, .device_type = .Source, .flags = attachment_const.VIEW_ONLY, }; + kata.attachments[0] = stdin; - kata.attachments[1] = attachment.Attachment{ + const stdout = attachment.alloc() orelse return error.OutOfMemory; + stdout.* = .{ .attachment_type = .Device, .device_type = .Stream, .flags = attachment_const.MARK_ONLY, }; + kata.attachments[1] = stdout; - kata.attachments[2] = attachment.Attachment{ + const stderr = attachment.alloc() orelse return error.OutOfMemory; + stderr.* = .{ .attachment_type = .Device, .device_type = .Trace, .flags = attachment_const.MARK_ONLY, }; + kata.attachments[2] = stderr; return kata; } @@ -71,6 +77,12 @@ pub fn dissolve(kata_id: u32) void { for (&pool, 0..) |*kata, i| { if (used[i] and kata.id == kata_id) { + for (&kata.attachments) |*slot| { + if (slot.*) |ptr| { + attachment.free(ptr); + slot.* = null; + } + } memory.cleanup(kata); kata.state = .Dissolved; used[i] = false; @@ -88,7 +100,7 @@ fn create_empty() types.Kata { .page_table = 0, .stack_top = 0, .user_stack_top = 0, - .attachments = [_]attachment.Attachment{.{}} ** kata_limits.MAX_ATTACHMENTS, + .attachments = [_]?*attachment.Attachment{null} ** kata_limits.MAX_ATTACHMENTS, .current_location = undefined, .current_location_len = 1, .current_cluster = 0, diff --git a/mirai/kata/types.zig b/mirai/kata/types.zig index cd1af51..8779449 100644 --- a/mirai/kata/types.zig +++ b/mirai/kata/types.zig @@ -69,7 +69,7 @@ pub const Kata = struct { stack_top: u64, user_stack_top: u64, - attachments: [kata_limits.MAX_ATTACHMENTS]attachment.Attachment, + attachments: [kata_limits.MAX_ATTACHMENTS]?*attachment.Attachment, current_location: [kata_limits.MAX_LOCATION_LENGTH]u8, current_location_len: usize, diff --git a/mirai/utils/kata/attachment.zig b/mirai/utils/kata/attachment.zig index 2798fc7..592b2c8 100644 --- a/mirai/utils/kata/attachment.zig +++ b/mirai/utils/kata/attachment.zig @@ -3,7 +3,6 @@ const afs = @import("../../fs/afs/afs.zig"); const ahci = @import("../../drivers/ahci/ahci.zig"); const attachment = @import("../../kata/attachment.zig"); -const fd_mod = @import("../../kata/attachment.zig"); const heap = @import("../../memory/heap.zig"); const kata_limits = @import("../../common/limits/kata.zig"); const kata_mod = @import("../../kata/kata.zig"); @@ -12,7 +11,7 @@ const location_util = @import("../fs/location.zig"); pub fn allocate(kata: *kata_mod.Kata) !u32 { var i: u32 = 3; while (i < kata_limits.MAX_ATTACHMENTS) : (i += 1) { - if (kata.attachments[i].attachment_type == .Closed) { + if (kata.attachments[i] == null) { return i; } } @@ -20,7 +19,7 @@ pub fn allocate(kata: *kata_mod.Kata) !u32 { } pub fn seal(kata: *kata_mod.Kata, fd: u32, fs: ?*afs.AFS(ahci.BlockDevice)) void { - const entry = &kata.attachments[fd]; + const entry = kata.attachments[fd] orelse return; if (entry.attachment_type == .Unit and entry.dirty) { if (entry.buffer) |buffer| { @@ -33,5 +32,6 @@ pub fn seal(kata: *kata_mod.Kata, fd: u32, fs: ?*afs.AFS(ahci.BlockDevice)) void } } - entry.* = attachment.Attachment{}; + attachment.free(entry); + kata.attachments[fd] = null; } |
