www.pudn.com > LFYOS.zip > return.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 
	 
static void exit_thread(int thread_id) 
{ 
	struct thread *t; 
	 
	t=&(os->thread[thread_id]); 
 
	if(t->semaphore>0) 
		release_semaphore(t->semaphore,FALSE, 
			&(os->semaphore[t->semaphore].capability)); 
 
	if(t->state==SLEEP) 
		v_thread(thread_id); 
 
	os->semaphore[0].value=(-THREAD_NUMBER); 
	p(thread_id,0,TRUE,FALSE,&(os->system_capability)); 
	if(t->pro_front==thread_id) 
		os->process[t->process].thread_ring=-1; 
	else{ 
		os->process[t->process].thread_ring=t->pro_front; 
		os->thread[t->pro_front].pro_back=t->pro_back; 
		os->thread[t->pro_back].pro_front=t->pro_front; 
	} 
 
	os->process[t->process].thread_number--; 
	os->process[0].thread_number++; 
	t->process=0; 
 
	if(os->process[0].thread_ring<0){ 
			t->pro_front=thread_id; 
			t->pro_back=thread_id; 
			os->process[0].thread_ring=thread_id; 
		} 
	else{ 
		int front_thread,back_thread; 
		front_thread=os->process[0].thread_ring; 
		back_thread=os->thread[front_thread].pro_back; 
		os->thread[front_thread].pro_back=thread_id; 
		os->thread[back_thread].pro_front=thread_id; 
		os->thread[thread_id].pro_front=front_thread; 
		os->thread[thread_id].pro_back=back_thread; 
	} 
	t->return_stack_top=1; 
	t->set_v_operation_result_flag=FALSE; 
	return ; 
} 
 
int thread_return(int thread_id,int exception_return_flag) 
{ 
	int i,first_flag,sem_value; 
	struct return_stack *first_rt; 
	struct thread *t; 
	struct process *process; 
	struct return_stack *old_rt,*rt; 
 
	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; 
 
	first_rt=&(t->return_stack[t->return_stack_top-1]); 
	first_flag=first_rt->process_p_flag; 
	first_rt->process_p_flag=TRUE; 
	for(i=0,old_rt=first_rt,rt=first_rt;;i++){ 
		os->process[old_rt->current_process] 
			.enter_thread_number--; 
		if(!(old_rt->process_p_flag)){ 
			sem_value=1; 
			process=&(os->process[old_rt->current_process]); 
			if(process->semaphore>0) 
				system_call_v(process->semaphore, 
				&sem_value,&(process->capability)); 
		} 
		old_rt->process_p_flag=TRUE; 
		if(t->return_stack_top<=1){ 
			if(!first_flag){ 
				sem_value=1; 
				process=&(os->process[ 
					first_rt->current_process]); 
				if(process->semaphore>0) 
					system_call_v( 
						process->semaphore, 
						&sem_value, 
						&(process->capability)); 
			} 
			exit_thread(thread_id); 
			return 0; 
		} 
		t->return_stack_top--; 
		rt=&(t->return_stack[t->return_stack_top-1]); 
		process=&(os->process[rt->current_process]); 
		if((rt->process_id)!=(process->id)) 
			exception_return_flag=FALSE; 
		else{ 
			if(!(old_rt->exception.flag)){ 
				if(i==0) 
					COPY_THREAD_ENVIRONMENT( 
						(old_rt->environment), 
						(rt->environment)); 
				rt->environment.system_call=i; 
				rt->environment.system_call_arg1 
					=exception_return_flag; 
				break; 
			} 
			if(exception_return_flag) 
				break; 
		} 
		old_rt=rt; 
	} 
	if(!first_flag){ 
		if((first_rt->current_process==rt->current_process) 
			&&(rt->process_p_flag)) 
				rt->process_p_flag=FALSE; 
		else{ 
			sem_value=1; 
			process=&(os->process[ 
				first_rt->current_process]); 
			if(process->semaphore>0) 
				system_call_v(process->semaphore, 
				&sem_value,&(process->capability)); 
		} 
 
	} 
	COPY_CAPABILITY((os->process[rt->current_process].capability), 
		(os->semaphore[t->semaphore].capability)); 
	return 0; 
}