15 lines
3.8 KiB
C
15 lines
3.8 KiB
C
#include "kernel.h"
|
|
#include "../substrate/substrate_engine.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
void kernel_init(Kernel *k) { memset(k, 0, sizeof(Kernel)); k->next_gvm_id = 1; k->sched_policy = SCHED_ROUND_ROBIN; k->timeslice = KERNEL_TIMESLICE; k->running = true; hal_init(&k->hal); }
|
|
void kernel_shutdown(Kernel *k) { for (uint32_t i = 0; i < k->gvm_count; i++) { GVM *g = &k->gvms[i]; if (g->state != GVM_STATE_EMPTY) { for (uint32_t r = 0; r < g->region_count; r++) free(g->regions[r].bytes); free(g->code); free(g->ext_ops); g->state = GVM_STATE_DEAD; } } }
|
|
int kernel_gvm_create(Kernel *k, uint32_t *code, uint32_t code_len, ExtSlot *ext_ops, uint32_t ext_ops_count) { if (k->gvm_count >= KERNEL_MAX_GVMS) return -1; GVM *g = &k->gvms[k->gvm_count++]; memset(g, 0, sizeof(GVM)); g->id = k->next_gvm_id++; g->state = GVM_STATE_READY; g->code = code; g->code_len = code_len; g->ext_ops = ext_ops; g->ext_ops_count = ext_ops_count; g->resonance_score = 1.0f; return (int)g->id; }
|
|
int kernel_load_gobj(Kernel *k, const char *path) { FILE *f = fopen(path, "rb"); if (!f) return -1; GobjHeader hdr; if (fread(&hdr, sizeof(GobjHeader), 1, f) != 1) { fclose(f); return -1; } if (memcmp(hdr.magic, GOBJ_MAGIC, 8) != 0) { fclose(f); return -1; } uint32_t *code = malloc(hdr.code_len * sizeof(uint32_t)); fread(code, sizeof(uint32_t), hdr.code_len, f); ExtSlot *ext = NULL; if (hdr.ext_len > 0) { ext = calloc(hdr.ext_len, sizeof(ExtSlot)); fread(ext, sizeof(ExtSlot), hdr.ext_len, f); } fclose(f); return kernel_gvm_create(k, code, hdr.code_len, ext, hdr.ext_len); }
|
|
void kernel_set_policy(Kernel *k, SchedPolicy policy) { k->sched_policy = policy; }
|
|
void kernel_set_timeslice(Kernel *k, uint32_t instructions) { k->timeslice = instructions; }
|
|
uint32_t kernel_schedule_next(Kernel *k) { if (k->gvm_count == 0) return -1; if (k->sched_policy == SCHED_RESONANCE) { float best = -1.0; uint32_t idx = -1; for(uint32_t i=0; i<k->gvm_count; i++) { if(k->gvms[i].state == GVM_STATE_READY && k->gvms[i].resonance_score > best) { best = k->gvms[i].resonance_score; idx = i; } } return idx; } for (uint32_t i = 1; i <= k->gvm_count; i++) { uint32_t idx = (k->current_gvm + i) % k->gvm_count; if (k->gvms[idx].state == GVM_STATE_READY) return idx; } return -1; }
|
|
uint32_t kernel_exec_timeslice(Kernel *k, uint32_t gvm_idx) { GVM *g = &k->gvms[gvm_idx]; g->state = GVM_STATE_RUNNING; uint32_t executed = 0; for (uint32_t i = 0; i < k->timeslice; i++) { if (g->pc >= g->code_len) { g->state = GVM_STATE_DEAD; return executed; } uint32_t word = g->code[g->pc++]; GlyphInstr ins = glyph_decode(word); g->tick++; g->total_instructions++; executed++; if (ins.family_id == 20 && ins.sub_id == 0) { g->state = GVM_STATE_DEAD; return executed; } if (ins.family_id == 5 && ins.sub_id == 2) { MemoryRegion *r = NULL; uint8_t op_a, op_b; glyph_decode_ops(ins.opcode_local, &op_a, &op_b); for(uint32_t r_idx=0; r_idx<g->region_count; r_idx++) if(g->regions[r_idx].id == op_a) r = &g->regions[r_idx]; if(!r) { r = &g->regions[g->region_count++]; r->id = op_a; r->size = 256; r->bytes = calloc(256, 1); r->stability = 1.0f; } for(uint32_t fi=0; fi<r->size; fi++) r->bytes[fi] = fi & 0xFF; r->mutation_count += r->size; r->stability = substrate_stability_from_mutations(r->mutation_count); } if (ins.family_id == 4 && ins.sub_id == 0) { uint8_t op_a, op_b; glyph_decode_ops(ins.opcode_local, &op_a, &op_b); MemoryRegion *r = &g->regions[g->region_count++]; r->id = op_a; r->size = 256; r->bytes = calloc(256, 1); r->stability = 1.0f; } } g->state = GVM_STATE_READY; return executed; }
|
|
void kernel_run(Kernel *k) { while (k->running) { bool any_alive = false; for (uint32_t i = 0; i < k->gvm_count; i++) if (k->gvms[i].state == GVM_STATE_READY) { any_alive = true; break; } if (!any_alive) break; uint32_t next = kernel_schedule_next(k); if (next == (uint32_t)-1) break; k->current_gvm = next; kernel_exec_timeslice(k, next); } }
|