提交 989c0584 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

half-working threads

上级 1944e2f1
......@@ -139,7 +139,7 @@ tags: $(OBJS) bootother.S _init
vectors.S: vectors.pl
perl vectors.pl > vectors.S
ULIB = ulib.o usys.o printf.o umalloc.o
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o
_%: %.o $(ULIB)
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
......@@ -172,6 +172,7 @@ UPROGS=\
_wc\
_zombie\
_halt\
_thrtest\
fs.img: mkfs README $(UPROGS)
./mkfs fs.img README $(UPROGS)
......
......@@ -104,7 +104,7 @@ void addrun(struct proc *);
struct proc* copyproc(struct proc*);
void delrun(struct proc*);
void exit(void);
int fork(void);
int fork(int);
int growproc(int);
int kill(int);
void pinit(void);
......@@ -171,7 +171,7 @@ struct vmnode * vmn_allocpg(uint);
void vmn_free(struct vmnode *);
int vmn_load(struct vmnode *, struct inode*, uint, uint);
struct vmap * vmap_alloc(void);
void vmap_free(struct vmap *);
void vmap_decref(struct vmap *);
int vmap_insert(struct vmap *, struct vmnode *n, uint);
struct vma * vmap_lookup(struct vmap *, uint);
struct vmap * vmap_copy(struct vmap *);
......
......@@ -121,7 +121,7 @@ exec(char *path, char **argv)
proc->tf->esp = sp;
switchuvm(proc);
freevm(oldpgdir);
vmap_free(oldvmap);
vmap_decref(oldvmap);
return 0;
......@@ -132,7 +132,7 @@ exec(char *path, char **argv)
if(ip)
iunlockput(ip);
if(vmap)
vmap_free(vmap);
vmap_decref(vmap);
if(vmn)
vmn_free(vmn);
return -1;
......
......@@ -40,7 +40,7 @@ forktest(void)
mtrace_enable_set(1, "xv6-forktest");
for(n=0; n<N; n++){
pid = fork();
pid = fork(0);
if(pid < 0)
break;
if(pid == 0)
......
......@@ -21,7 +21,7 @@ main(void)
for(;;){
printf(1, "init: starting sh\n");
pid = fork();
pid = fork(0);
if(pid < 0){
printf(1, "init: fork failed\n");
exit();
......
......@@ -195,7 +195,7 @@ growproc(int n)
// Sets up stack to return as if from system call.
// Caller must set state of returned proc to RUNNABLE.
int
fork(void)
fork(int flags)
{
int i, pid;
struct proc *np;
......@@ -211,14 +211,20 @@ fork(void)
return -1;
}
// Copy process state from p.
if((np->vmap = vmap_copy(proc->vmap)) == 0){
freevm(np->pgdir);
kfree(np->kstack);
np->kstack = 0;
np->state = UNUSED;
return -1;
if(flags == 0) {
// Copy process state from p.
if((np->vmap = vmap_copy(proc->vmap)) == 0){
freevm(np->pgdir);
kfree(np->kstack);
np->kstack = 0;
np->state = UNUSED;
return -1;
}
} else {
np->vmap = proc->vmap;
__sync_fetch_and_add(&np->vmap->ref, 1);
}
np->brk = proc->brk;
np->parent = proc;
*np->tf = *proc->tf;
......@@ -312,7 +318,7 @@ wait(void)
kfree(p->kstack);
p->kstack = 0;
freevm(p->pgdir);
vmap_free(p->vmap);
vmap_decref(p->vmap);
p->state = UNUSED;
p->pid = 0;
p->parent = 0;
......
......@@ -49,6 +49,7 @@ struct vma {
struct vmap {
struct vma e[16];
struct spinlock lock; // serialize map/lookup/unmap
uint ref;
uint alloc;
};
......
......@@ -184,7 +184,7 @@ fork1(void)
{
int pid;
pid = fork();
pid = fork(0);
if(pid == -1)
panic("fork");
return pid;
......
......@@ -20,7 +20,7 @@ main(int argc, char *argv[])
printf(1, "stressfs starting\n");
for(i = 0; i < 4; i++)
if(fork() > 0)
if(fork(0) > 0)
break;
printf(1, "%d\n", i);
......
......@@ -11,7 +11,11 @@
int
sys_fork(void)
{
return fork();
int flags;
if(argint(0, &flags) < 0)
return -1;
return fork(flags);
}
int
......
struct stat;
// system calls
int fork(void);
int fork(int);
int exit(void) __attribute__((noreturn));
int wait(void);
int pipe(int*);
......@@ -37,3 +37,7 @@ void* memset(void*, int, uint);
void* malloc(uint);
void free(void*);
int atoi(const char*);
// uthread.S
int forkt(void *sp, void *pc);
......@@ -210,7 +210,7 @@ pipe1(void)
printf(1, "pipe() failed\n");
exit();
}
pid = fork();
pid = fork(0);
seq = 0;
if(pid == 0){
close(fds[0]);
......@@ -244,7 +244,7 @@ pipe1(void)
close(fds[0]);
wait();
} else {
printf(1, "fork() failed\n");
printf(1, "fork(0) failed\n");
exit();
}
printf(1, "pipe1 ok\n");
......@@ -258,18 +258,18 @@ preempt(void)
int pfds[2];
printf(1, "preempt: ");
pid1 = fork();
pid1 = fork(0);
if(pid1 == 0)
for(;;)
;
pid2 = fork();
pid2 = fork(0);
if(pid2 == 0)
for(;;)
;
pipe(pfds);
pid3 = fork();
pid3 = fork(0);
if(pid3 == 0){
close(pfds[0]);
if(write(pfds[1], "x", 1) != 1)
......@@ -303,7 +303,7 @@ exitwait(void)
int i, pid;
for(i = 0; i < 100; i++){
pid = fork();
pid = fork(0);
if(pid < 0){
printf(1, "fork failed\n");
return;
......@@ -328,7 +328,7 @@ mem(void)
printf(1, "mem test\n");
ppid = getpid();
if((pid = fork()) == 0){
if((pid = fork(0)) == 0){
m1 = 0;
while((m2 = malloc(10001)) != 0){
*(char**)m2 = m1;
......@@ -369,7 +369,7 @@ sharedfd(void)
printf(1, "fstests: cannot open sharedfd for writing");
return;
}
pid = fork();
pid = fork(0);
memset(buf, pid==0?'c':'p', sizeof(buf));
for(i = 0; i < 1000; i++){
if(write(fd, buf, sizeof(buf)) != sizeof(buf)){
......@@ -417,7 +417,7 @@ twofiles(void)
unlink("f1");
unlink("f2");
pid = fork();
pid = fork(0);
if(pid < 0){
printf(1, "fork failed\n");
return;
......@@ -477,7 +477,7 @@ createdelete(void)
char name[32];
printf(1, "createdelete test\n");
pid = fork();
pid = fork(0);
if(pid < 0){
printf(1, "fork failed\n");
exit();
......@@ -672,7 +672,7 @@ concreate(void)
for(i = 0; i < 40; i++){
file[1] = '0' + i;
unlink(file);
pid = fork();
pid = fork(0);
if(pid && (i % 3) == 1){
link("C0", file);
} else if(pid == 0 && (i % 5) == 1){
......@@ -720,7 +720,7 @@ concreate(void)
for(i = 0; i < 40; i++){
file[1] = '0' + i;
pid = fork();
pid = fork(0);
if(pid < 0){
printf(1, "fork failed\n");
exit();
......@@ -1207,7 +1207,7 @@ forktest(void)
printf(1, "fork test\n");
for(n=0; n<1000; n++){
pid = fork();
pid = fork(0);
if(pid < 0)
break;
if(pid == 0)
......@@ -1256,7 +1256,7 @@ sbrktest(void)
*b = 1;
a = b + 1;
}
pid = fork();
pid = fork(0);
if(pid < 0){
printf(stdout, "sbrk test fork failed\n");
exit();
......@@ -1324,7 +1324,7 @@ sbrktest(void)
// can we read the kernel's memory?
for(a = (char*)(640*1024); a < (char*)2000000; a += 50000){
ppid = getpid();
pid = fork();
pid = fork(0);
if(pid < 0){
printf(stdout, "fork failed\n");
exit();
......@@ -1345,7 +1345,7 @@ sbrktest(void)
exit();
}
for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
if((pids[i] = fork()) == 0){
if((pids[i] = fork(0)) == 0){
// allocate the full 640K
sbrk((640 * 1024) - (uint)sbrk(0));
write(fds[1], "x", 1);
......@@ -1398,7 +1398,7 @@ validatetest(void)
hi = 1100*1024;
for(p = 0; p <= (uint)hi; p += 4096){
if((pid = fork()) == 0){
if((pid = fork(0)) == 0){
// try to crash the kernel by passing in a badly placed integer
validateint((int*)p);
exit();
......@@ -1443,7 +1443,7 @@ bigargtest(void)
int pid, ppid;
ppid = getpid();
pid = fork();
pid = fork(0);
if(pid == 0){
char *args[32+1];
int i;
......
......@@ -270,13 +270,14 @@ vmap_alloc(void)
m->e[j].lock.name = "vma";
}
m->lock.name = "vmap";
m->ref = 1;
return m;
}
}
panic("out of vmaps");
}
void
static void
vmap_free(struct vmap *m)
{
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++)
......@@ -285,6 +286,13 @@ vmap_free(struct vmap *m)
m->alloc = 0;
}
void
vmap_decref(struct vmap *m)
{
if(__sync_sub_and_fetch(&m->ref, 1) == 0)
vmap_free(m);
}
int
vmap_insert(struct vmap *m, struct vmnode *n, uint va_start)
{
......@@ -346,7 +354,7 @@ vmap_copy(struct vmap *m)
c->e[i].n = vmn_copy(m->e[i].n);
if(c->e[i].n == 0) {
release(&m->lock);
vmap_free(c);
vmap_decref(c);
return 0;
}
__sync_fetch_and_add(&c->e[i].n->ref, 1);
......
#pragma once
// Routines to let C code use special x86 instructions.
static inline uchar
......
......@@ -8,7 +8,7 @@
int
main(void)
{
if(fork() > 0)
if(fork(0) > 0)
sleep(5); // Let child exit before parent.
exit();
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论