Commit 5e25224b authored by benkma's avatar benkma

Lab 13 Completed

parent e329501c
......@@ -18,9 +18,12 @@ std::atomic<unsigned long> ticks;
std::atomic<int> kdisplay;
static void tick();
static proc* create_init_process();
static void boot_process_start(pid_t pid, const char* program_name);
void find_mapped_memory();
const pid_t INIT_PID = 1;
// kernel_start(command)
// Initialize the hardware and processes and start running. The `command`
......@@ -36,13 +39,32 @@ void kernel_start(const char* command) {
ptable[i] = nullptr;
}
// Start Init Process
proc* initProc = create_init_process();
// start first process
boot_process_start(1, CHICKADEE_FIRST_PROCESS);
boot_process_start(2, CHICKADEE_FIRST_PROCESS);
// start running processes
cpus[0].schedule(nullptr);
// run the init process
while(true) {
initProc->yield();
}
assert(false);
}
proc* create_init_process() {
proc *initProc = knew<proc>();
assert(initProc);
initProc->init_user(INIT_PID, early_pagetable);
initProc->ppid_ = INIT_PID;
{
spinlock_guard guard(ptable_lock);
assert(!ptable[INIT_PID]);
ptable[INIT_PID] = initProc;
}
return initProc;
}
// boot_process_start(pid, name)
// Load application program `name` as process number `pid`.
......@@ -62,6 +84,7 @@ void boot_process_start(pid_t pid, const char* name) {
proc* p = knew<proc>();
p->init_user(pid, ld.pagetable_);
p->regs_->reg_rip = ld.entry_rip_;
p->ppid_ = INIT_PID;
void* stkpg = kalloc(PAGESIZE);
assert(stkpg);
......@@ -194,6 +217,9 @@ uintptr_t proc::syscall(regstate* regs) {
case SYSCALL_GETPID:
return id_;
case SYSCALL_GET_PPID:
return ppid_;
case SYSCALL_YIELD:
yield();
return 0;
......@@ -244,9 +270,7 @@ uintptr_t proc::syscall(regstate* regs) {
return syscall_map_console(regs->reg_rdi);
case SYSCALL_EXIT:
set_pagetable(early_pagetable);
pstate_ = ps_exit;
yield_noreturn();
syscall_exit(regs->reg_rdi);
assert(false); // will not be reached
case SYSCALL_SLEEP:
......@@ -263,6 +287,21 @@ uintptr_t proc::syscall(regstate* regs) {
#pragma GCC push_options
#pragma GCC optimize("O0")
int proc::syscall_exit(uint64_t exitCode) {
set_pagetable(early_pagetable);
pstate_ = ps_exit;
{
spinlock_guard guard(ptable_lock);
for(int i = 1; i < NPROC; ++i) {
proc* otherProc = ptable[i];
if(otherProc && otherProc->ppid_ == id_) {
otherProc->ppid_ = INIT_PID;
}
}
}
yield_noreturn();
}
int proc::syscall_sleep(uint64_t msec){
unsigned long now = ticks;
unsigned long end = round_up(now,10) + msec;
......@@ -290,10 +329,11 @@ int proc::syscall_fork(regstate* regs) {
log_printf("\nBegin syscall_fork()");
pid_t pid = 0;
proc *child = knew<proc>();
x86_64_pagetable* pt = kalloc_pagetable();
if(!child){
return E_NOSYS;
}
child->ppid_ = id_;
x86_64_pagetable* pt = kalloc_pagetable();
{
spinlock_guard guard(ptable_lock);
for(int i = 1; i < NPROC; ++i) {
......
......@@ -33,6 +33,8 @@ struct __attribute__((aligned(4096))) proc {
yieldstate* yields_ = nullptr; // Process's current yield state
std::atomic<int> pstate_ = ps_blank; // Process state
pid_t ppid_ = 0; // Parent Process ID
x86_64_pagetable* pagetable_ = nullptr; // Process's page table
uintptr_t recent_user_rip_ = 0; // Most recent user-mode %rip
#if HAVE_SANITIZERS
......@@ -67,6 +69,7 @@ struct __attribute__((aligned(4096))) proc {
int syscall_fork(regstate* regs);
int syscall_map_console(uintptr_t addr);
int syscall_sleep(uint64_t msec);
int syscall_exit(uint64_t exitCode);
uintptr_t syscall_read(regstate* reg);
uintptr_t syscall_write(regstate* reg);
......
......@@ -272,6 +272,7 @@ struct bitset_view {
// Your numbers should be >=128 to avoid conflicts.
#define SYSCALL_MAP_CONSOLE 128
#define SYSCALL_SLEEP 129
#define SYSCALL_GET_PPID 130
// System call error return values
......
......@@ -36,7 +36,7 @@ void process_main() {
sys_msleep(50);
if (sys_getpid() == original) {
console_printf("ppid tests without exit succeed\n");
console_printf("\n\n\n\n\nppid tests without exit succeed\n");
} else {
sys_exit(0);
}
......
......@@ -139,7 +139,7 @@ inline int sys_msleep(unsigned msec) {
// sys_getppid()
// Return parent process ID.
inline pid_t sys_getppid() {
return E_NOSYS;
return make_syscall(SYSCALL_GET_PPID);
}
// sys_waitpid(pid, status, options)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment