add fork
This commit is contained in:
parent
96355d1d42
commit
4af8e581fe
2
am/am.h
2
am/am.h
|
@ -93,7 +93,7 @@ extern _Screen _screen;
|
|||
void _asye_init();
|
||||
void _listen(_RegSet* (*l)(_Event ev, _RegSet *regs));
|
||||
_RegSet *_make(_Area kstack, void *entry);
|
||||
void _trap();
|
||||
int _trap(int num, int check, u32 args1, u32 args2);
|
||||
void _idle();
|
||||
void _ienable();
|
||||
void _idisable();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
extern "C" { int printk(const char *, ...); }
|
||||
|
||||
static _RegSet* (*H)(_Event, _RegSet*) = nullptr;
|
||||
static u32 args[4];
|
||||
|
||||
extern "C" {
|
||||
void irq0();
|
||||
|
@ -60,7 +61,14 @@ void irq_handle(TrapFrame *tf) {
|
|||
ev.event = _EVENT_NULL;
|
||||
if (tf->irq == 32) ev.event = _EVENT_IRQ_TIME;
|
||||
else if (tf->irq == 33) ev.event = _EVENT_IRQ_IODEV;
|
||||
else if (tf->irq == 0x80) ev.event = _EVENT_SYSCALL;
|
||||
else if (tf->irq == 0x80) {
|
||||
ev.event = _EVENT_SYSCALL;
|
||||
args[0] = regs.eax;
|
||||
args[1] = regs.edx;
|
||||
args[2] = regs.ecx;
|
||||
args[3] = regs.ebx;
|
||||
ev.cause = args;
|
||||
}
|
||||
else if (tf->irq < 32) ev.event = _EVENT_ERROR;
|
||||
|
||||
_RegSet *ret = ®s;
|
||||
|
@ -216,8 +224,9 @@ _RegSet *_make(_Area stack, void *entry) {
|
|||
return regs;
|
||||
}
|
||||
|
||||
void _trap() {
|
||||
asm volatile("int $0x80");
|
||||
int _trap(int num, int check, u32 args1, u32 args2) {
|
||||
asm volatile("int $0x80"::"a"(num),"d"(check),"c"(args1),"b"(args2));
|
||||
return args[0];
|
||||
}
|
||||
|
||||
void _idisable() {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef __IRQ_H__
|
||||
#define __IRQ_H__
|
||||
|
||||
_RegSet* handle(_Event ev, _RegSet *r);
|
||||
|
||||
#endif
|
|
@ -5,7 +5,7 @@
|
|||
#include <klib.h>
|
||||
#include "list.h"
|
||||
|
||||
#define NR_PCBS 3
|
||||
#define NR_PCBS 10
|
||||
#define SLEEP 1
|
||||
#define READY 0
|
||||
#define FREE 2
|
||||
|
@ -31,6 +31,7 @@ extern u16 pcb_avls;
|
|||
|
||||
void init_idle();
|
||||
PCB *create_kthread(size_t entry);
|
||||
void schedule();
|
||||
int sys_fork();
|
||||
void sys_sleep();
|
||||
void sys_wakeup(u32 time);
|
||||
|
|
|
@ -1,8 +1,40 @@
|
|||
#include <am.h>
|
||||
#include <klib.h>
|
||||
|
||||
/*void do_child() {
|
||||
int i;
|
||||
for(i = 0; i < 10; i++){
|
||||
printf("Pang ");
|
||||
printf("now sleep for %ds\n",1);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void do_father() {
|
||||
int i;
|
||||
for(i = 0; i < 10; i++){
|
||||
printf("Ping ");
|
||||
printf("now sleep for %ds\n",1);
|
||||
sleep(1);
|
||||
}
|
||||
}*/
|
||||
|
||||
int umain(){
|
||||
printk("jump into umain");
|
||||
printf("jump into umain\n");
|
||||
unsigned int fpid = 0;
|
||||
fpid = fork();
|
||||
if(fpid < 0)
|
||||
printf("error in fork\n");
|
||||
if(fpid == 0){
|
||||
printf("father = %d\n",fpid);
|
||||
//do_father();
|
||||
}
|
||||
else{
|
||||
printf("child = %d\n",fpid);
|
||||
//do_child();
|
||||
}
|
||||
printf("main end , return to idle\n");
|
||||
//exit(0);
|
||||
while(1);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#include <am.h>
|
||||
#include <klib.h>
|
||||
#include "irq.h"
|
||||
#include "pcb.h"
|
||||
|
||||
void do_syscall(_Event ev, _RegSet *r){
|
||||
int *args = ev.cause;
|
||||
switch(args[0]){
|
||||
case 20:args[0] = sys_fork();break;
|
||||
default:_halt(args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
_RegSet* handle(_Event ev, _RegSet *r){
|
||||
switch(ev.event){
|
||||
case _EVENT_IRQ_TIME: {
|
||||
memcpy(current->sf, r, sizeof(struct _RegSet));
|
||||
if(current->time_count == 0){
|
||||
schedule();
|
||||
}
|
||||
else{
|
||||
_putc('-');
|
||||
current->time_count--;
|
||||
}
|
||||
return current->sf;
|
||||
}
|
||||
case _EVENT_SYSCALL:do_syscall(ev, r);return r;
|
||||
default:_halt(ev.event);return r;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#include <am.h>
|
||||
#include <klib.h>
|
||||
#include "pcb.h"
|
||||
#include "irq.h"
|
||||
|
||||
PCB PCBs[NR_PCBS];
|
||||
PCB *current;
|
||||
|
@ -10,25 +11,6 @@ LIST_HEAD(blockq_h);
|
|||
u16 pcb_avls = 0; //pcb available index
|
||||
_Area stack;
|
||||
|
||||
extern void schedule();
|
||||
|
||||
_RegSet* handle(_Event ev, _RegSet *r){
|
||||
switch(ev.event){
|
||||
case _EVENT_IRQ_TIME: {
|
||||
memcpy(current->sf, r, sizeof(struct _RegSet));
|
||||
if(current->time_count == 0){
|
||||
schedule();
|
||||
}
|
||||
else{
|
||||
_putc('-');
|
||||
current->time_count--;
|
||||
}
|
||||
return current->sf;
|
||||
}
|
||||
default:_halt(ev.event);return r;
|
||||
}
|
||||
}
|
||||
|
||||
void init_idle(){
|
||||
PCB *pcb = &(PCBs[pcb_avls]);
|
||||
current = pcb;
|
||||
|
@ -58,8 +40,26 @@ PCB *create_kthread(size_t entry){
|
|||
pcb->sleep_time = 0;
|
||||
|
||||
pcb->state = READY;
|
||||
strcpy(pcb->name,"PCB");
|
||||
strcpy(pcb->name,"PCB0");
|
||||
pcb_avls++;
|
||||
list_add(&(pcb->state_list),&readyq_h);
|
||||
return pcb;
|
||||
}
|
||||
|
||||
int sys_fork(){
|
||||
assert(pcb_avls < NR_PCBS);
|
||||
PCB *pcb = &(PCBs[pcb_avls]);
|
||||
pcb->pid = pcb_avls; //use index to define pid
|
||||
pcb->lock_depth = 0;
|
||||
|
||||
pcb->sf = (void *)pcb->p_stack;
|
||||
memcpy(pcb->sf,current->sf,sizeof(struct _RegSet));
|
||||
pcb->time_count = time_chips;
|
||||
pcb->sleep_time = 0;
|
||||
|
||||
pcb->state = READY;
|
||||
strcpy(pcb->name,"PCB1");
|
||||
pcb_avls++;
|
||||
list_add(&(pcb->state_list),&readyq_h);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ void schedule() {
|
|||
int i;
|
||||
for(i = 0; PCBs[i].state_list.next != tmp->next && PCBs[i].state_list.prev != tmp->prev; i++);
|
||||
PCB *next = (void *)&(PCBs[i]);
|
||||
printk("next = %s",next->name);
|
||||
//fresh new pcb time count
|
||||
if(current->pid != 0){
|
||||
current->time_count = time_chips;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
NAME = klib
|
||||
SRCS = printk.c string.c stdlib.c cpp.c
|
||||
SRCS = printk.c string.c stdlib.c cpp.c unistd.c
|
||||
include $(AM_HOME)/Makefile.lib
|
||||
|
|
|
@ -51,6 +51,11 @@ int sscanf(const char *str, const char *format, ...);
|
|||
|
||||
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
|
||||
|
||||
//unistd.h
|
||||
int fork(void);
|
||||
void sleep(ulong time);
|
||||
void exit(int status);
|
||||
|
||||
#define printk printf
|
||||
|
||||
// assert.h
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#include "klib.h"
|
||||
|
||||
int fork(void){
|
||||
return _trap(20,0,0,0);
|
||||
}
|
||||
|
||||
void sleep(ulong time){
|
||||
_trap(21,0,0,0);
|
||||
}
|
||||
|
||||
void exit(int status){
|
||||
_trap(22,status,0,0);
|
||||
}
|
Loading…
Reference in New Issue