www.pudn.com > LFYOS.zip > migrate.c


#include"kernel.h" 
 
#define WRONG_PROCESS		-1 
#define NO_RETURN_STACK		-2 
#define WRONG_THREAD		-3 
#define WRONG_CAPABILITY	-4 
#define WRONG_THREAD_STATE	-5 
	 
int thread_migrate_with_physical_block( 
	int thread_id, 
	int process_id,int process_v_flag, 
	struct thread_physical_block *pb, 
	struct capability *capability) 
{ 
	struct thread *t; 
	struct return_stack *rt; 
	int return_value; 
 
	return_value=thread_migrate(thread_id, 
		process_id,TRUE,FALSE,process_v_flag); 
	if(return_value<0) 
		return return_value; 
 
	t=&(os->thread[thread_id]); 
	rt=&(t->return_stack[t->return_stack_top-1]); 
 
	if(!KERNEL_COMPARE_CAPABILITY( 
		(os->system_capability),(*capability))) 
	{ 
		thread_return(thread_id,TRUE); 
		return WRONG_CAPABILITY; 
	} 
 
	COPY_THREAD_PHYSICAL_BLOCK((*pb),(rt->physical_block)); 
	 
	return return_value; 
} 
 
int thread_migrate(int thread_id,int destination_process_id, 
	int stack_flag,int exception_flag,int process_v_flag) 
{ 
	int process_id,old_process_id,sem_value,process_p_flag; 
	struct thread *t; 
	struct return_stack *rt,*old_rt; 
	struct process *process,*old_process; 
	 
	if((thread_id<0)||(thread_id>=THREAD_NUMBER)) 
		return WRONG_THREAD; 
	t=&(os->thread[thread_id]); 
	if((t->state!=RUN)&&(t->state!=READY)) 
		return WRONG_THREAD_STATE; 
	old_rt=&(t->return_stack[t->return_stack_top-1]); 
	old_process_id=old_rt->current_process; 
	old_process=&(os->process[old_process_id]); 
	rt=old_rt; 
	if(destination_process_id==0) 
		process_id=old_rt->current_process; 
	else 
		process_id=destination_process_id; 
 
	if((process_id<=0)||(process_id>=PROCESS_NUMBER)) 
		return  WRONG_PROCESS; 
	process=&(os->process[process_id]); 
	if(!stack_flag){ 
		old_process->enter_thread_number--; 
	}else{ 
		if(t->return_stack_top>=RETURN_BLOCK_NUMBER) 
			return NO_RETURN_STACK; 
		t->return_stack_top++; 
		rt=&(t->return_stack[t->return_stack_top-1]); 
		COPY_THREAD_PHYSICAL_BLOCK((old_rt->physical_block), 
			(rt->physical_block)); 
		rt->exception.flag=exception_flag; 
		if(!exception_flag) 
			COPY_THREAD_ENVIRONMENT((old_rt->environment), 
				(rt->environment)); 
	} 
	process->enter_thread_number++; 
	if(destination_process_id==0){ 
		COPY_RUN_POINT((old_rt->environment.point), 
			(rt->environment.point)); 
	}else 
		COPY_RUN_POINT((process->start_point), 
			(rt->environment.point)); 
	RESET_THREAD_PARAMETER(rt->environment); 
 
	rt->current_process=process_id; 
	rt->process_id=process->id; 
 
	rt->environment.system_call=t->return_stack_top; 
	if(exception_flag) 
		rt->environment.system_call_arg1=0-(t->semaphore); 
	else 
		rt->environment.system_call_arg1=t->semaphore; 
	 
	COPY_CAPABILITY((process->capability), 
		(os->semaphore[t->semaphore].capability)); 
	if(rt->current_process==old_rt->current_process){ 
		process_p_flag=old_rt->process_p_flag; 
		old_rt->process_p_flag=TRUE; 
		rt->process_p_flag=process_p_flag; 
	}else{ 
		if(process_v_flag) 
		if(!(old_rt->process_p_flag)) 
		if(old_process->semaphore>0){ 
			sem_value=1; 
			if(system_call_v( 
				old_process->semaphore,&sem_value, 
				&(old_process->capability))>=0) 
					old_rt->process_p_flag=TRUE; 
		} 
		rt->process_p_flag=TRUE; 
	} 
	return	(rt->environment.system_call); 
}