⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uthread.c

📁 可模拟实现Linux用户级线程库的静态调用,规避了多线程库的竞态条件和复杂的同步问题.除源代码外还有详细的设计说明文档.
💻 C
字号:
/*学号:200620110268
  姓名:李海波*/

#include "uthread.h"


int uthreads_init()
{
	if( uthread_inits == 1 )
	{
		last_errno = 1;
		return -1;
	}

	running_tid = 0;
	running_thread = NULL;
	total_thread_num = 0;
	uthread_starts = 0;
	last_errno = 0;

	long loopi;
	for( loopi = 0; loopi < MAX_THREAD_NUM; loopi ++ )
	{
		thread[loopi].t_id = loopi;
		thread[loopi].s_status.bursts = 0;
		thread[loopi].s_status.run_time = 0;
		thread[loopi].s_status.total_time = 0;
		thread[loopi].quantum = V_QUANTUM;
	}

	q_ready = (struct queue *) malloc( sizeof( struct queue ) );
	if( q_ready == NULL )
	{
		last_errno = 5;
		return -1;
	}

	q_blocked = (struct queue *) malloc( sizeof( struct queue ) );
	if( q_blocked == NULL )
	{
		last_errno = 5;
		return -1;
	}
	q_zomby = (struct queue *) malloc( sizeof( struct queue ) );
	if( q_zomby == NULL )
	{
		last_errno = 5;
		return -1;
	}

	q_ready->num = q_blocked->num = q_zomby->num = 0;
	q_ready->head = q_blocked->head = q_zomby->head = NULL;	


	if( signal(SIGALRM, cpu_dispatch) == SIG_ERR )
	{
		last_errno = 4;
		return -1;
	}
	uthread_inits = 1;

	return 0;
}


int uthreads_spawn( int stacksize, void (* proc)(int), int param )
{
	static int 		tid=0;
	long 		new_base;

	if( uthread_inits == 0 )
	{
		last_errno = 8;
		return -1;
	}

	if( stacksize <= 0 )
	{
		last_errno = 6;
		return -1;
	}

	if( proc == NULL )
	{
		last_errno = 7;
		return -1;
	}
	thread[tid].start_func = proc;

	thread[tid].parameter = param;

	thread[tid].stack_size = stacksize;

	thread[tid].stack = (char *) malloc( sizeof( char ) * stacksize );
	if( thread[tid].stack == NULL)
	{
		last_errno = 5;
		return -1;
	}

	temp = (struct node*) malloc( sizeof( struct node ) );
	if( temp == NULL )
	{
		last_errno = 5;
		return -1;
	}
	temp->tid = tid;
	temp->next = NULL;
	queue_insert( q_ready, temp );

	total_thread_num ++;

	if( sigsetjmp( jbuf[tid], 1 ) )
	{	
	
		thread[m].start_func( thread[m].parameter );
	  cpu_dispatch();
	}
	else
	{
		new_base = ( long ) (thread[tid].stack);
		new_base += thread[tid].stack_size - sizeof( long );
	}

	(jbuf[tid]->__jmpbuf)[JB_BP] = new_base;
	(jbuf[tid]->__jmpbuf)[JB_SP] = new_base;
	jbuf[tid]->__mask_was_saved = 1;
	tid++;
	test[x]=0;
	x++;
	return tid;
}

int uthreads_start()
{
	
	running_thread=q_ready->head;
	
	q_ready->head=q_ready->head->next;
running_thread->next=NULL;
	if( uthread_starts == 1 )
	{
		last_errno = 2;
		return -1;
	}
	else
		uthread_starts = 1;

	if( total_thread_num == 0 )
	{
		last_errno = 3;
		return -1;
	}

	if( sigsetjmp(g_jbuf, 1) )
		return 0;
	else
	{
		ualarm( 3 * SECOND, 3 * SECOND );				                
		siglongjmp( jbuf[0], 1);
	}
}

int uthreads_yield()
{
	if(total_thread_num==1)
	return 0;
}



void uthreads_exit()
{
	thread[running_tid].r_status = ZOMBY;
	total_thread_num --;
	return;
}



long uthreads_wait( struct thread_status *ss )

{
	struct node	*temp;

	if( uthread_inits == 0 )
	{
		last_errno = 8;
		return -1;
	}

	if( total_thread_num == 0 )
	{
		last_errno = 9;
		return -1;
	}

	if( q_zomby->num == 0 )
	{
		last_errno = 10;
		return -1;
	}
	
	temp = q_zomby->head;
	q_zomby->head = q_zomby->head->next;
	
	if( ss != NULL )
	{
		(*ss).bursts = thread[temp->tid].s_status.bursts;
		(*ss).run_time = thread[temp->tid].s_status.run_time;
		(*ss).total_time = thread[temp->tid].s_status.total_time;
	}

	return temp->tid;
}



void uthreads_perror( char *user_info )
{
	printf( "%s   %s", errinfo[last_errno], user_info );

	last_errno = 0;
}



void queue_insert( struct queue *q, struct node *n )
{  
	struct node	*tempa, *tempb;
	tempa=tempb=NULL;
	
	if( q->num == 0 )
		{
	q->head = n;

	}
	else
	{
	if(thread[q->head->tid].quantum < thread[n->tid].quantum )
		{
	
			n->next = q->head;
			q->head = n;
		}
		else
		{
			tempa = q->head;
			tempb = tempa->next;

			while( tempb != NULL )
			{
				if( thread[tempb->tid].quantum <thread[n->tid].quantum )
				{

					tempa->next = n;
					n->next = tempb;
					break;
				}
				else
				{
			
					tempa = tempb;
					tempb = tempb->next;
			
				}
			}
			tempa->next = n;
		}

	}

	q->num ++;

}


void cpu_dispatch()
{
	  int loopi;
	  int j;
	  int mm=0;
	  struct node *tempp;
	  

		if(total_thread_num!=0)
			{
	
		if(total_thread_num==1) mm=1;

			   if(sigsetjmp( jbuf[running_tid], 1 ))
			   {	return; }
	
		
		thread[running_tid].s_status.bursts ++;
		thread[running_tid].s_status.run_time ++;
	

		if(mm==0)
  {
		if (thread[running_tid].r_status == ZOMBY ) 
		{

			tempp = q_zomby->head;test[m]=1;
	
			if( tempp == NULL )
				{q_zomby->head = running_thread;q_zomby->head->tid=running_tid;}
			else
			{
				while(tempp->next != NULL )
				tempp = tempp->next;
				tempp->next = running_thread;tempp->next->tid=running_tid;
			}
	
		}
		else
		{	
	thread[running_tid].quantum -= TIME_SLICE;
	if( thread[running_tid].quantum <= 0 )
			{
				thread[running_tid].r_status = BLOCKED;
				queue_insert( q_blocked, running_thread );
			}
			else
			{
				thread[running_tid].r_status = READY;			
				if(mm==0)
				queue_insert( q_ready, running_thread );			
			}
		}
	
		if( q_ready->num == 0 )
		{
			tempp = q_blocked->head;
			while( tempp != NULL )
			{
				thread[tempp->tid].quantum = thread[tempp->tid].quantum/2 + V_QUANTUM;
				thread[tempp->tid].r_status = READY;
				tempp = tempp->next;
			}

			q_ready->head = q_blocked->head;
			q_blocked->head = NULL;

		}
	}
	running_tid = q_ready->head->tid;
	running_thread = q_ready->head;
	q_ready->head = q_ready->head->next;
	running_thread->next = NULL;
  q_ready->num --;
	thread[running_tid].r_status = RUNNING;	
	   }		
	if( total_thread_num == 0)
	siglongjmp( g_jbuf, 1 );

	for(j=(m+1)%x;j<x+1;j++)
	  {
		m=(m+1)%x;
		if(test[j%x]==0) break;			
		}	
siglongjmp( jbuf[j], 1 );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -