The SimpleFork system call
/* simplified version of fork() */
pid_t SimpleFork () {
pid_t pid, caller_pid;
extern process_descriptor_t pd[MAX_PID];
/* look for a free process descriptor */
for (pid = 1; pid < MAX_PID; ++pid) {
if (pd[pid].allocted == FALSE)
break;
}
if (pid >= MAX_PID) {
/* no free slots */
return -1;
}
/*
* Find out which process invoked SimpleFork;
* assumes SimpleFork was invoked directly by a syscall,
* otherwise, getpid() would not return correct pid
*/
caller_pid = getpid();
/* now set up control registers */
pd[pid].allocted = TRUE; /* mark descriptor as allocated */
pd[pid].state = READY; /* process is ready to run */
/* assume for simplicity that each process gets equal piece of pie */
pd[pid].cr.base = pid * PROCESS_SIZE;
pd[pid].cr.bound = PROCESS_SIZE;
/*
* look at register for return address from system call
* NOTE: This is not a variable but the actual CPU register
*/
pd[pid].cr.pc = register[return_address];
/* make sure child begins life with normal USER priviledges */
pd[pid].cr.psw = USER_MODE | INTERRUPTS_ENABLED;
/* return value from function call is 0 for child */
pd[pid].gp.ret_val = 0;
/* now copy address space from parent */
memcpy (pd[pid].base, pd[caller_pid].base, PROCESS_SIZE);
/* we're done... give parent the pid of child */
return (pid);
}