aboutsummaryrefslogtreecommitdiff
path: root/mirai.old/kata/pool.zig
blob: 08814d8766385b744b7e7b905f28cc10f793cd27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//! Kata pool management

const attachment = @import("attachment.zig");
const attachment_const = @import("../common/constants/attachment.zig");
const heap = @import("../memory/heap.zig");
const kata_const = @import("../common/constants/kata.zig");
const kata_limits = @import("../common/limits/kata.zig");
const memory = @import("memory.zig");
const types = @import("types.zig");
const waker = @import("sensei/waker.zig");

pub var pool: [kata_limits.MAX_KATAS]types.Kata = undefined;
pub var used: [kata_limits.MAX_KATAS]bool = [_]bool{false} ** kata_limits.MAX_KATAS;
var next_id: u32 = 1;

pub fn init() void {
    for (&pool, 0..) |*kata, i| {
        kata.* = create_empty();
        used[i] = false;
    }
}

pub fn create() !*types.Kata {
    for (&pool, 0..) |*kata, i| {
        if (!used[i]) {
            used[i] = true;

            const kata_id = next_id;
            next_id += 1;

            kata.* = create_empty();
            kata.id = kata_id;
            kata.state = .Alive;

            kata.current_location[0] = '/';

            const stdin = attachment.alloc() orelse return error.OutOfMemory;
            stdin.* = .{
                .attachment_type = .Device,
                .device_type = .Source,
                .flags = attachment_const.VIEW_ONLY,
            };
            kata.attachments[0] = stdin;

            const stdout = attachment.alloc() orelse return error.OutOfMemory;
            stdout.* = .{
                .attachment_type = .Device,
                .device_type = .Stream,
                .flags = attachment_const.MARK_ONLY,
            };
            kata.attachments[1] = stdout;

            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;
        }
    }

    return error.TooManyKata;
}

pub fn get(id: u32) ?*types.Kata {
    for (&pool, 0..) |*kata, i| {
        if (used[i] and kata.id == id) {
            return kata;
        }
    }
    return null;
}

pub fn dissolve(kata_id: u32) void {
    for (&pool, 0..) |*kata, i| {
        if (used[i] and kata.id == kata_id) {
            // Mark as dying
            kata.state = .Dying;

            // Clean up attachments
            for (&kata.attachments) |*slot| {
                if (slot.*) |ptr| {
                    attachment.free(ptr);
                    slot.* = null;
                }
            }

            // Clean up letter data
            if (kata.letter_data) |data| {
                heap.free(@ptrCast(data), kata.letter_capacity);
                kata.letter_data = null;
                kata.letter_capacity = 0;
            }

            // Try to clean up memory
            memory.cleanup(kata);

            // Check if page table was destroyed or needs Shinigami
            if (kata.page_table != 0) {
                // Page table still exists - become zombie for Shinigami to reap
                kata.state = .Zombie;
                // Keep used[i] = true so slot isn't reused yet
            } else {
                // Fully cleaned up
                kata.state = .Dissolved;
                used[i] = false;
            }

            waker.wake_waiting(kata_id);
            return;
        }
    }
}

fn create_empty() types.Kata {
    return types.Kata{
        .id = 0,
        .state = .Dissolved,
        .mode = .Persona,
        .context = types.Context.init(),
        .page_table = 0,
        .stack_top = 0,
        .user_stack_top = 0,
        .user_stack_bottom = 0,
        .user_stack_committed = 0,
        .attachments = [_]?*attachment.Attachment{null} ** kata_limits.MAX_ATTACHMENTS,
        .current_location = undefined,
        .current_location_len = 1,
        .current_cluster = 0,
        .parent_id = 0,
        .letter_type = 0,
        .letter_data = null,
        .letter_len = 0,
        .letter_capacity = 0,
        .vruntime = 0,
        .weight = kata_const.DEFAULT_WEIGHT,
        .last_run = 0,
        .next = null,
        .waiting_for = 0,
        .exit_code = 0,
    };
}