sched.h: create_new_process - correct function to create a new process in an available spot

master
Anton Lydike 3 years ago
parent ef854fba54
commit 61017db51c

@ -5,10 +5,12 @@
#include "io.h" #include "io.h"
#include "malloc.h" #include "malloc.h"
void create_processes_from_bin_table(); void read_binary_table();
extern ProcessControlBlock processes[PROCESS_COUNT]; extern ProcessControlBlock processes[PROCESS_COUNT];
// this array is populated when the memory image is built, therefore it should
// resign in a section which is not overwritten with zeros on startup
loaded_binary binary_table[NUM_BINARIES] __attribute__ ((section (".data"))); loaded_binary binary_table[NUM_BINARIES] __attribute__ ((section (".data")));
extern void memset(unsigned int, void*, void*); extern void memset(unsigned int, void*, void*);
@ -19,20 +21,20 @@ extern void init()
dbgln("Kernel started!", 15); dbgln("Kernel started!", 15);
create_processes_from_bin_table(); read_binary_table();
scheduler_run_next(); scheduler_run_next();
} }
void create_processes_from_bin_table() void read_binary_table()
{ {
char msg[28] = "found bin with id 0 at pos 0"; char msg[28] = "found bin with id 0 at pos 0";
ProcessControlBlock* next_process = processes;
malloc_info info; malloc_info info;
info.allocate_memory_end = (void*) 0xFF0000; info.allocate_memory_end = (void*) 0xFF0000;
info.allocate_memory_start = (void*) 0; info.allocate_memory_start = (void*) 0;
// calculate the end of loaded binaries
for (int i = 0; i < NUM_BINARIES; i++) { for (int i = 0; i < NUM_BINARIES; i++) {
if (binary_table[i].binid == 0) if (binary_table[i].binid == 0)
break; break;
@ -50,21 +52,9 @@ void create_processes_from_bin_table()
if (binary_table[i].binid == 0) if (binary_table[i].binid == 0)
break; break;
// create a new process for each binary found
optional_voidptr stack_top = malloc_stack(1<<12); // allocate 4Kib stack // it should have around 4kb stack
if (has_error(stack_top)) { create_new_process(binary_table+i, 1<<12);
dbgln("Error while allocating stack for initial process", 48);
continue;
}
next_process->status = PROC_RDY;
next_process->pid = binary_table[i].binid;
next_process->pc = binary_table[i].entrypoint;
next_process->regs[1] = (int) stack_top.value; // set stack top, put 32 bytes of zeros there
next_process++;
dbgln("enabled process from table", 26);
} }
} }

@ -11,23 +11,6 @@
// scheduler settings // scheduler settings
#define TIME_SLICE_LEN 100 // number of cpu time ticks per slice #define TIME_SLICE_LEN 100 // number of cpu time ticks per slice
/* This struct holds information about binaries which are currently loaded into
* memory. Currently the kernel is not able to load binaries into memory, as
* no file system layer is implemented. When the memory image is built, the
* list of loaded binaries is populated aswell.
*/
typedef struct loaded_binary {
int binid;
int entrypoint;
void* bounds[2];
} loaded_binary;
// create a global table holding all loaded binaries.
// this is either populated at runtime when binaries are loaded dynamically
// or when a memory image is created.
extern loaded_binary binary_table[NUM_BINARIES];
// init function // init function
extern __attribute__((__noreturn__)) void init(); extern __attribute__((__noreturn__)) void init();

@ -25,6 +25,8 @@ enum process_status {
// process structure: // process structure:
typedef struct ProcessControlBlock ProcessControlBlock; typedef struct ProcessControlBlock ProcessControlBlock;
struct loaded_binary;
struct ProcessControlBlock { struct ProcessControlBlock {
int pid; int pid;
int pc; int pc;
@ -33,9 +35,23 @@ struct ProcessControlBlock {
// scheduling information // scheduling information
enum process_status status; enum process_status status;
ProcessControlBlock* waiting_for_process; ProcessControlBlock* waiting_for_process;
struct loaded_binary* binary;
unsigned long long int asleep_until; unsigned long long int asleep_until;
}; };
/* This struct holds information about binaries which are currently loaded into
* memory. Currently the kernel is not able to load binaries into memory, as
* no file system layer is implemented. When the memory image is built, the
* list of loaded binaries is populated aswell.
*/
typedef struct loaded_binary {
int binid;
int entrypoint;
void* bounds[2];
} loaded_binary;
/* /*
* Optionals * Optionals
* *

@ -2,6 +2,7 @@
#include "sched.h" #include "sched.h"
#include "csr.h" #include "csr.h"
#include "io.h" #include "io.h"
#include "malloc.h"
// scheduling data: // scheduling data:
@ -9,6 +10,7 @@ ProcessControlBlock processes[PROCESS_COUNT];
ProcessControlBlock* current_process; ProcessControlBlock* current_process;
unsigned long long int scheduling_interrupted_start; unsigned long long int scheduling_interrupted_start;
unsigned long long int next_interrupt_scheduled_for; unsigned long long int next_interrupt_scheduled_for;
int next_process_id = 1;
void scheduler_run_next () void scheduler_run_next ()
{ {
@ -154,3 +156,54 @@ void mark_ecall_entry()
{ {
scheduling_interrupted_start = read_time(); scheduling_interrupted_start = read_time();
} }
optional_pcbptr find_available_pcb_slot() {
static int index = 0;
int start_index = index;
ProcessControlBlock* pcb = processes + index;
while (pcb->status != PROC_DEAD) {
index = (index + 1) % PROCESS_COUNT;
if (index == start_index)
return (optional_pcbptr) { .error = ENOBUFS };
pcb = processes + index;
}
return (optional_pcbptr) { .value = pcb };
}
int create_new_process(loaded_binary* bin, int stack_size)
{
// try to get a position in the processes list
optional_pcbptr slot_or_err = find_available_pcb_slot();
// if that failed, we cannot creat a new process
if (has_error(slot_or_err)) {
dbgln("No more process structs!", 24);
return slot_or_err.error;
}
// allocate stack for the new process
optional_voidptr stack_top_or_err = malloc_stack(stack_size); // allocate 4Kib stack
// if that failed, we also can't create a new process
if (has_error(stack_top_or_err)) {
dbgln("Error while allocating stack for process", 40);
return stack_top_or_err.error;
}
ProcessControlBlock* pcb = slot_or_err.value;
// determine next pid
int pid = next_process_id++;
// mark process as ready
pcb->status = PROC_RDY;
pcb->pid = pid;
pcb->pc = bin->entrypoint;
pcb->binary = bin;
// load stack top into stack pointer register
pcb->regs[1] = (int) stack_top_or_err.value;
// load pid into a0 register
pcb->regs[9] = pid;
dbgln("Created new process!", 20);
}

@ -18,4 +18,7 @@ int scheduler_index_from_pid(int pid);
int* get_current_process_registers(); int* get_current_process_registers();
ProcessControlBlock* get_current_process(); ProcessControlBlock* get_current_process();
void mark_ecall_entry(); void mark_ecall_entry();
int create_new_process(loaded_binary* bin, int stack_size);
#endif #endif
Loading…
Cancel
Save