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


#include"kernel.h" 
 
#define SET_THREAD_PARAMETER					\ 
{								\ 
	int m_id,s_id;						\ 
								\ 
	current.return_stack_top=current.t->return_stack_top;	\ 
	current.rt=&(current.t->return_stack[			\ 
		current.return_stack_top-1]);			\ 
	current.env=&(current.rt->environment);			\ 
	m_id=current.rt->physical_block.memory_id;		\ 
	s_id=current.rt->physical_block.stack_block_id;		\ 
	if((m_id>=0)&&(s_id>=0))				\ 
		current.par=(union system_call_parameter *)	\ 
			get_block_base(m_id,s_id);		\ 
	else							\ 
		current.par=(union system_call_parameter *)	\ 
		(kernel_get_thread_parameter(			\ 
			current.thread_id));			\ 
								\ 
} 
 
void system_call() 
{ 
	int sem_id,return_value,p_id; 
 
	for(;;){ 
		current.cpu_id=get_virtual_cpu(); 
		current.cpu_info=&(os->virtual_cpu.used_cpu[ 
			current.cpu_id]); 
		if((current.thread_id=(current.cpu_info->thread_id))<0){ 
			current.env=(struct thread_environment *)0; 
			do_idle(); 
			switch_virtual_cpu(); 
			continue; 
		} 
		current.t=&(os->thread[current.thread_id]); 
		SET_THREAD_PARAMETER; 
		if(((int)(current.env->point.function))==0) 
			return_value=1; 
		else{ 
			if(lock_os_kernel()){ 
				switch_virtual_cpu(); 
				continue; 
			} 
			return_value=current.env->point.function(); 
			unlock_os_kernel(); 
			RESET_THREAD_PARAMETER(*(current.env)); 
			if(return_value==0){ 
				switch_virtual_cpu(); 
				continue; 
			} 
		} 
 
		if(current.t->state!=RUN) 
			continue; 
		if((current.return_stack_top) 
			!=(current.t->return_stack_top)) 
				SET_THREAD_PARAMETER; 
	 
		if(!(current.rt->process_p_flag)) 
			break; 
		p_id=current.rt->current_process; 
		if((sem_id=os->process[p_id].semaphore)<=0) 
			break; 
		if(lock_os_kernel()){ 
			switch_virtual_cpu(); 
			continue; 
		} 
		return_value=p(current.thread_id,sem_id,TRUE,FALSE, 
			&(os->semaphore[sem_id].capability)); 
		unlock_os_kernel(); 
		if(return_value<0) 
			break; 
		current.rt->process_p_flag=FALSE; 
		if(current.t->state==RUN) 
			break; 
	} 
 
	if(!(COMPARE_THREAD_PHYSICAL_BLOCK((current.rt->physical_block), 
		(current.cpu_info->last.physical_block)))) 
	{ 
		notify_physical_block_switch(current.thread_id, 
			&(current.rt->physical_block)); 
		COPY_THREAD_PHYSICAL_BLOCK((current.rt->physical_block), 
			(current.cpu_info->last.physical_block)); 
	} 
 
	if(((current.cpu_info->last.thread_id)!=current.thread_id)|| 
		((current.cpu_info->last.process_id) 
		!=(current.rt->current_process))) 
	{ 
		notify_switch(current.thread_id); 
		current.cpu_info->last.thread_id=current.thread_id; 
		current.cpu_info->last.process_id 
			=current.rt->current_process; 
	} 
 
	return ; 
}