Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change #205

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"files.associations": {
"defs.h": "c",
"user.h": "c",
"traps.h": "c",
"proc.h": "c"
}
}
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ OBJS = \
uart.o\
vectors.o\
vm.o\


# Cross-compiling (e.g., on Mac OS X)
# TOOLPREFIX = i386-jos-elf
Expand Down Expand Up @@ -143,7 +144,7 @@ tags: $(OBJS) entryother.S _init
vectors.S: vectors.pl
./vectors.pl > vectors.S

ULIB = ulib.o usys.o printf.o umalloc.o
ULIB = ulib.o usys.o printf.o umalloc.o

_%: %.o $(ULIB)
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
Expand All @@ -153,7 +154,7 @@ _%: %.o $(ULIB)
_forktest: forktest.o $(ULIB)
# forktest has less library code linked in - needs to be small
# in order to be able to max out the proc table.
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o umalloc.o
$(OBJDUMP) -S _forktest > forktest.asm

mkfs: mkfs.c fs.h
Expand Down Expand Up @@ -181,6 +182,8 @@ UPROGS=\
_usertests\
_wc\
_zombie\
_Test_Thread\
_Test_Thread2\

fs.img: mkfs README $(UPROGS)
./mkfs fs.img README $(UPROGS)
Expand Down Expand Up @@ -250,7 +253,7 @@ qemu-nox-gdb: fs.img xv6.img .gdbinit
EXTRA=\
mkfs.c ulib.c user.h cat.c echo.c forktest.c grep.c kill.c\
ln.c ls.c mkdir.c rm.c stressfs.c usertests.c wc.c zombie.c\
printf.c umalloc.c\
printf.c umalloc.c Test_Thread.c Test_Thread2.c\
README dot-bochsrc *.pl toc.* runoff runoff1 runoff.list\
.gdbinit.tmpl gdbutil\

Expand Down
26 changes: 26 additions & 0 deletions Test_Thread.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include"types.h"
#include"user.h"
#include"stat.h"
Lock My_Lock;
void function(void* arg1,void* arg2){
int* X=(int*)arg2;
Lock_Acquire(&My_Lock);
printf(2,"Thread %d Finished with value =%d\n",(*X),2*(*X)+1);
Lock_Release(&My_Lock);
exit();
}
int main(){
int l=3;
int* size=&l;
int list[3];
printf(0,"***This Program will calculate 2x+1 for 3 threads where x is the tid passed to thread as its 2nd arg***\n");
Lock_Init(&My_Lock);
for(int i=0;i<3;i++){
list[i]=i+1;
thread_create(&function,(void*)size,(void*)&list[i]);
}
for(int i=1;i<=3;i++){
join(i);
}
exit();
}
32 changes: 32 additions & 0 deletions Test_Thread2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include"types.h"
#include"user.h"
#include"stat.h"
Lock P2_Perm,P1_Perm;
void p1(void* arg1,void* arg2){
printf(0,"A\n");
Lock_Release(&P2_Perm);
Lock_Acquire(&P1_Perm);
printf(0,"C\n");
printf(0,"B\n");
exit();
}

void p2(void* arg1,void* arg2){
Lock_Acquire(&P2_Perm);
printf(0,"F\n");
Lock_Release(&P1_Perm);
printf(0,"E\n");
printf(0,"G\n");
exit();
}
int main(){
Lock_Init(&P2_Perm);
Lock_Init(&P1_Perm);
Lock_Acquire(&P2_Perm);
Lock_Acquire(&P1_Perm);
thread_create(&p1,(void*)0,(void*)0);
thread_create(&p2,(void*)0,(void*)0);
join(1);
join(2);
exit();
}
4 changes: 4 additions & 0 deletions defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ void userinit(void);
int wait(void);
void wakeup(void*);
void yield(void);
int clone(void (*)(void*,void*),void*,void*,void*);
int join(int);
//We will add clone & join syscall prototypes here


// swtch.S
void swtch(struct context**, struct context*);
Expand Down
135 changes: 132 additions & 3 deletions proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ allocproc(void)
p->context = (struct context*)sp;
memset(p->context, 0, sizeof *p->context);
p->context->eip = (uint)forkret;

p->Is_Thread=0;
p->Thread_Num=0;
p->tstack=0;
p->tid=0;
return p;
}

Expand Down Expand Up @@ -209,7 +212,7 @@ fork(void)
np->cwd = idup(curproc->cwd);

safestrcpy(np->name, curproc->name, sizeof(curproc->name));

//np->tid=-1;
pid = np->pid;

acquire(&ptable.lock);
Expand Down Expand Up @@ -246,7 +249,9 @@ exit(void)
iput(curproc->cwd);
end_op();
curproc->cwd = 0;

if(curproc->tid == 0 && curproc->Thread_Num!=0) {
panic("Parent cannot exit before its children");
}
acquire(&ptable.lock);

// Parent might be sleeping in wait().
Expand Down Expand Up @@ -495,6 +500,130 @@ kill(int pid)
release(&ptable.lock);
return -1;
}
int clone(void (*worker)(void*,void*),void* arg1,void* arg2,void* stack)
{
//int i, pid;
struct proc *New_Thread;
struct proc *curproc = myproc();
uint sp,HandCrafted_Stack[3];
// Allocate process.
if((New_Thread = allocproc()) == 0){
return -1;
}
if(curproc->tid!=0){
kfree(New_Thread->kstack);
New_Thread->kstack = 0;
New_Thread->state = UNUSED;
cprintf("Clone called by a thread\n");
return -1;
}
//The new thread parent would be curproc
New_Thread->pid=curproc->pid;
New_Thread->sz=curproc->sz;

//The tid of the thread will be determined by Number of current threads
//of a process
curproc->Thread_Num++;
New_Thread->tid=curproc->Thread_Num;
New_Thread->Is_Thread=1;

//The parent of thread will be the process calling clone
New_Thread->parent=curproc;

//Sharing the same virtual address space
New_Thread->pgdir=curproc->pgdir;
if(!stack){
kfree(New_Thread->kstack);
New_Thread->kstack = 0;
New_Thread->state = UNUSED;
curproc->Thread_Num--;
New_Thread->tid=0;
New_Thread->Is_Thread=0;
cprintf("Child process wasn't allocated a stack\n");
}
//Assuming that child_stack has been allocated by malloc
New_Thread->tstack=(char*)stack;
//Thread has the same trapframe as its parent
*New_Thread->tf=*curproc->tf;

HandCrafted_Stack[0]=(uint)0xfffeefff;
HandCrafted_Stack[1]=(uint)arg1;
HandCrafted_Stack[2]=(uint)arg2;

sp=(uint)New_Thread->tstack;
sp-=3*4;
if(copyout(New_Thread->pgdir, sp,HandCrafted_Stack, 3 * sizeof(uint)) == -1){
kfree(New_Thread->kstack);
New_Thread->kstack = 0;
New_Thread->state = UNUSED;
curproc->Thread_Num--;
New_Thread->tid=0;
New_Thread->Is_Thread=0;
return -1;
}
New_Thread->tf->esp=sp;
New_Thread->tf->eip=(uint)worker;
//Duplicate all the file descriptors for the new thread
for(uint i = 0; i < NOFILE; i++){
if(curproc->ofile[i])
New_Thread->ofile[i] = filedup(curproc->ofile[i]);
}
New_Thread->cwd = idup(curproc->cwd);
safestrcpy(New_Thread->name, curproc->name, sizeof(curproc->name));
acquire(&ptable.lock);
New_Thread->state=RUNNABLE;
release(&ptable.lock);
//cprintf("process running Clone has %d threads\n",curproc->Thread_Num);
return New_Thread->tid;
}
int join(int Thread_id)
{
struct proc *p,*curproc=myproc();
int Join_Thread_Exit=0,jtid;
if(Thread_id==0)
return -1;
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
if(p->tid == Thread_id && p->parent == curproc) {
Join_Thread_Exit=1;
break;
}
}
if(!Join_Thread_Exit || curproc->killed){
//cprintf("Herere");
return -1;
}
acquire(&ptable.lock);
for(;;){
// thread is killed by some other thread in group
//cprintf("I am waiting\n");
if(curproc->killed){
release(&ptable.lock);
return -1;
}
if(p->state == ZOMBIE){
// Found the thread
curproc->Thread_Num--;
jtid = p->tid;
kfree(p->kstack);
p->kstack = 0;
p->pgdir = 0;
p->pid = 0;
p->tid = 0;
p->tstack = 0;
p->parent = 0;
p->name[0] = 0;
p->killed = 0;
p->state = UNUSED;
release(&ptable.lock);
//cprintf("Parent has %d threads\n",curproc->Thread_Num);
return jtid;
}

sleep(curproc, &ptable.lock);
}
//curproc->Thread_Num--;
return 0;
}

//PAGEBREAK: 36
// Print a process listing to console. For debugging.
Expand Down
4 changes: 4 additions & 0 deletions proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ struct proc {
char *kstack; // Bottom of kernel stack for this process
enum procstate state; // Process state
int pid; // Process ID
int tid; // Thread Id
char* tstack; // Thread stack
int Is_Thread; // if 0 --->Parent o.w child
int Thread_Num; // Keeping track of the number of threads of a process
struct proc *parent; // Parent process
struct trapframe *tf; // Trap frame for current syscall
struct context *context; // swtch() here to run process
Expand Down
1 change: 0 additions & 1 deletion string.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "types.h"
#include "x86.h"

void*
memset(void *dst, int c, uint n)
{
Expand Down
5 changes: 4 additions & 1 deletion syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ extern int sys_unlink(void);
extern int sys_wait(void);
extern int sys_write(void);
extern int sys_uptime(void);

extern int sys_clone(void);
extern int sys_join(void);
static int (*syscalls[])(void) = {
[SYS_fork] sys_fork,
[SYS_exit] sys_exit,
Expand All @@ -126,6 +127,8 @@ static int (*syscalls[])(void) = {
[SYS_link] sys_link,
[SYS_mkdir] sys_mkdir,
[SYS_close] sys_close,
[SYS_clone] sys_clone,
[SYS_join] sys_join,
};

void
Expand Down
2 changes: 2 additions & 0 deletions syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_clone 22
#define SYS_join 23
43 changes: 43 additions & 0 deletions sysproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,49 @@
#include "mmu.h"
#include "proc.h"

int sys_clone(void)
{

void (*func)(void *,void *);
char *child_stack, *arg1,*arg2;

if(argptr(0, (char **)&func, 0) == -1) {
return -1;
}

if(argptr(1, &arg1, 0) == -1) {
return -1;
}

if(argptr(2, &arg2, 0) == -1) {
return -1;
}
if(argint(3, (int *)&child_stack) == -1) {
return -1;
}


if(myproc()->sz < (uint)arg1 + (uint)arg2) {
return -1;
}


if(myproc()->sz <= (uint)child_stack &&
myproc()->sz < (uint)child_stack - PGSIZE) {
return -1;
}


return clone(func,(void*)arg1,(void*)arg2,(void *)child_stack);

}
int sys_join(void)
{
int Thread_id;
if(argint(0,&Thread_id)<0)
return -1;
return join(Thread_id);
}
int
sys_fork(void)
{
Expand Down
Loading