📄 uthread.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 + -