Page 1 of 1

the problem when I implement the fork

Posted: Mon Dec 26, 2011 1:13 am
by taxus
Hello everyone , now I'm implement the memory management
when I work on the fork() ,it stuck me so many time
here is my Init()

Code: Select all

void		Init()
{
	
	printx("INIT()       running...........\n");

	int	pid	=	fork();
	if(pid	!=	0)
	{
		printx("Parent    is    running\n");
		while(1){}
	}
	else
	{
		printx("Child    is    running..\n");
		while(1){}
	}

}
the fork()

Code: Select all

int	fork()
{
	message		forkmsg;
	forkmsg.type		=	FORK;
	poster(BOTH, 		TASK_MM, 	&forkmsg);

	return	forkmsg.PID;
}

Code: Select all

int	final_fork()
{
	int		child_body;
	int		parent_body;
	int		parent_limit;
	int		parent_len;
	int		pid;
	int		child_pid;
	process_table	*	pproc;
	/*************************\
	*	stage	1
	*	copy		father's	proctable
	\*************************/
	pproc	=	proc;
	int	i;
	for(i=0;	i < procnum + tasknum;	i++,pproc++)
	{
		if(pproc->flags	==	FREE_PROC)
			break;	
	}
	child_pid	=	i;
	pproc->pid	=	child_pid;
	pid			=	mmsg.src;											//	@@
	if(i	==	procnum	+	tasknum	)									//	@@ 
		while(1){}
	
	
	u16	child_ldtstr	=	pproc->ldtstr;								//	
	*pproc	=	proc[pid];
	pproc->ldtstr	=	child_ldtstr;
	
	mmprintf(pproc->procname, 	"%s %d",	proc[pid].procname,		child_pid);	//	@@ 
	pproc->parent	=	pid;													//	@@

	/*************************\
	*	stage	2
	*	alloc		mem
	\*************************/
	
	
	/*************************\
	*	stage	2 & 3
	*	copy		father's	body
	\*************************/
	Descriptor	*	pdesc;
	pdesc		=	&proc[pid].ldt[INDEX_EXE];
	
	parent_body	=	combine_ldt(pdesc->base03,	24,	pdesc->base02,			16,		pdesc->base01);
	parent_limit	=	combine_ldt(0,				0,	(pdesc->limit02_prop & 0xf),	16,		pdesc->limit01);
	parent_len	=	(parent_limit +1)*(pdesc->limit02_prop & GRANULARITY_MASK	?	4096	:	1);

	pdesc		=	&proc[pid].ldt[1];
	int body	=	combine_ldt(pdesc->base03,	24,	pdesc->base02,			16,		pdesc->base01);
	int limit	=	combine_ldt(	(pdesc->limit02_prop & 0xf),	16,	0,				0,		pdesc->limit01);
	int	len		=	(limit +1)*(pdesc->limit02_prop & GRANULARITY_MASK	?	4096	:	1);

	child_body	=	alloc_mm(child_pid, 	parent_len);					//	@@ stage	2
	printx("%x <----- %x (%x)\n",child_body,parent_body, parent_limit);
	memcpy((void *)child_body, 	(void *)parent_body, parent_len);

	init_descriptor(&pproc->ldt[0], 	child_body, 	(MM_CELL-1) >> LIMIT_4K, 		LIMIT_CELL	|	DP_32CODE	| DP_EXE | DP_SODO_USER << 5);
	init_descriptor(&pproc->ldt[1], 	child_body, 	(MM_CELL-1) >> LIMIT_4K, 		LIMIT_CELL	|	DP_32CODE	| DP_RW  | DP_SODO_USER << 5);
	/*************************\
	*	stage	4
	*	unlock	the	child
	\*************************/
	mmsg.PID	=	child_pid;
	message		msg;
	msg.PID		=	0;				//	@@
	msg.retvalue	=	0;				//	@@
	
	poster(SEND, 	child_pid, 	&msg);
	return 0;	
}
my problem is that ,when the os running ,it suppose to print two different sentences
one is parent ,the other is child
but I got two same sentences,both of them are "parent is running "
the odd thing is my process table and the selector is correct ,also the ldt is right
when I change the Init() first printx like this

Code: Select all

printx("Parent    is    running,pid %d\n",get_pid());
the first sentence become the "INIT() running..........."
and the second is correct " Parent is running,pid 4 "
so , that means I really get into the child process ,but something goes wrong
anyone have any ideas where I might wrong ?
Thanks a lot !

Re: the problem when I implement the fork

Posted: Tue Dec 27, 2011 9:40 am
by taxus
e... nobody have any opinion ?

Re: the problem when I implement the fork

Posted: Tue Dec 27, 2011 2:24 pm
by AJ
Hi,

I can't say I've had a detailed look at your code, but could it be some sort of lock issue? The new version of the printx statement has a system call and an integer conversion, and so will take longer to run in addition to performing a user --> system switch. All this means that in your second version of the code, things happen in a very different order. I suspect the fork is happening correctly, but the console output is not.

Cheers,
Adam