Reputation: 407
I've done all the steps to create a system call, and then created a user program and run it:
proc.c
int countChildren (int pid) {
struct proc *p;
int count = 0;
acquire(&ptable.lock);
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
if(p->parent->pid == pid) count++;
release(&ptable.lock);
return count;
}
sysproc.c
int
sys_getchildren(void)
{
int pid;
argint(0, &pid);
return countChildren(pid);
}
userProgram.c
...
#include "types.h"
#include "user.h"
int main (void) {
int n1 = fork();
int n2 = fork();
int n3 = fork();
int n4 = fork();
if (n1 > 0 && n2 > 0 && n3 > 0 && n4 > 0) {
printf(1,"parent\n");
printf(1," getchildren = %d \n", getchildren());
}
exit();
}
But the result is not what I expected, below is the result:
Upvotes: 1
Views: 1478
Reputation: 9629
I think that your kernel code is corrected, your problem comes from the user code: you create processes but you do not take care of them so they become zombies and could not be counted.
When a process exit and is not waited by its parent, it become a zombie:
a zombie is a process is adopted by the init process (see exit
definition in file proc.c
) and cannot be counted in child.
To correct your testing code, make the processes to sleep for some time and to wait their child:
#include "types.h"
#include "user.h"
int main (void) {
int n1 = fork();
int n2 = fork();
int n3 = fork();
int n4 = fork();
if (n1 > 0 && n2 > 0 && n3 > 0 && n4 > 0) {
printf(1,"parent\n");
printf(1," getchildren = %d \n", getchildren());
}
/* wait for all child to terminate */
while(wait() != -1) { }
/* give time to parent to reach wait clause */
sleep(1);
exit();
}
Edit: you have a little typo in syscall, instead of getint
you should get pid
from myproc
:
int
sys_getchildren(void)
{
int pid;
pid = myproc()->pid;
return countChildren(pid);
}
or shorter:
int
sys_getchildren(void)
{
return countChildren(myproc()->pid);
}
Upvotes: 1