aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-02-23 13:13:17 +0530
committerBobby <[email protected]>2026-02-23 13:13:17 +0530
commit2e2235ad7d1828054461da08cc4ba7f0e27bc012 (patch)
tree5b5b2a003654103e43337a0cd575d81f93d3147c
parent052c2cff84904bf0aaf5e90770ba2229f760a7d8 (diff)
downloadakiba-2e2235ad7d1828054461da08cc4ba7f0e27bc012.tar.xz
akiba-2e2235ad7d1828054461da08cc4ba7f0e27bc012.zip
fix: dynamic attachments in kata
-rw-r--r--mirai/common/limits/attachment.zig2
-rw-r--r--mirai/common/limits/kata.zig2
-rw-r--r--mirai/invocations/io/attach.zig26
-rw-r--r--mirai/invocations/io/mark.zig12
-rw-r--r--mirai/invocations/io/seal.zig5
-rw-r--r--mirai/invocations/io/view.zig12
-rw-r--r--mirai/invocations/kata/exit.zig6
-rw-r--r--mirai/kata/attachment.zig26
-rw-r--r--mirai/kata/pool.zig20
-rw-r--r--mirai/kata/types.zig2
-rw-r--r--mirai/utils/kata/attachment.zig8
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;
}