NOTE: This code hasn't actually been tested so I have no idea if it's even syntactically correct, but you can kind of understand what I'm trying to show here, it handles runs code from a process, then pushes the current state of the registers and stack into the struct for that process ID.
Code: Select all
#define MAX_STACK_SIZE_PROC 16384 /* 16K of stack for each process */
#define MAX_PROCESSES 1024
typedef struct {
#if ARCH=="x86_64"
uint64_t ...... /* x64 regs */
#elif ARCH=="x86"
uint32_t ...... /* x86 regs */
...... /* other architectures */
#endif
} regs_t;
typedef struct {
uint8_t stack[MAX_STACK_SIZE_PROC]; /* The raw bytes of the stack of the process */
regs_t registers;
uint16_t processID;
} processState_t;
processState_t procStates[MAX_PROCESSES];
processState_t runProcess(uint16_t id) {
processState_t ret;
ret.processID = id;
/* Somehow run *x* number of CPU cycles for that process, then stop, likely using timers & interrupts. */
ret.stack = somehowGetPointerToStackOfProc(id); /* This seems like it wouldn't work with the array above but you can understand the idea */
ret.registers = getStoredRegistersFromEndOfExecutingProcess(id);
return ret;
}
void handleProcess(uint8_t id) {
/* Somehow restore registers to the state they were at the end of the last cycle of execution with procStates[id].registers */
procStates[id] = runProcess(id); /* Run the process, and push the state of everything returned by runProcess() back into the array */
return;
}
int handleAllProcesses() {
/* Calculate the load that the system is currently under, and if it's so much that we won't have time to manage system stuff like drivers and memory should we try to run the processes more, then return -1 to indicate that we need to start handling the system stuff now and if we still have time later, then handle the processes */
if (systemLoad() >= 80) {
return -1;
}
for (uint8_t i = 0; i > somehowGetNumberOfRunningProcesses(); i++) {
handleProcess(i);
}
return 0;
}