📄 threadlibrary.c
字号:
//***************************************************************
// Thread library and implemention
//
// Developer: Yiye Chen
//
// I use array for ready queue,struct for Thread Control Block
// Date: Oct 30,2007
//***************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <tswitch.h>
#include "threadlibrary.h"
typedef void (*cleanvec_t) (void); // library defined
//******* globle variables *************
struct TCB
{
th_id_t threadid ; // the thread ID
regbuf_t reg_save_area; // register save area
int *stack; // the stack
}tcb[100];// create 100 Thread Control Block
int id=1000;// to assign thread id
int queue[100];// build ready queue, initilize 0
//************* functions begin **********
void th_init()
{
int init;
for(init=0;init<100;init++)
{
queue[init]=0;// initiallize the ready queue elements to 0
}
tcb[0].threadid=id;// assign the main a thread id,which is 100
queue[0]=tcb[0].threadid; // put the main thread id to ready queue[0]
// for making only queue[0] is the current thread
setcleanup(th_exit);
}
th_id_t th_fork(int s)
{
int i; // compute the thread id in th_fork()
int myid,size,run;
id=id+1; // fork will produce a new thread,so thread id will be add one
i=id-1000;// the new tcb[] number;
tcb[i].threadid=id;// assign the child thread id
queue[i]=id;// the child thread id save on ready queue array
//**** malloc the stack space******************************
if(s>0) {tcb[i].stack=malloc(s*8192);size=s*8192;}
if(s==0) {tcb[i].stack=malloc(8192);size=8192;}
if(s<0) {tcb[i].stack=malloc((-s)*4);size=(-s)*4;}
//**** fork operation *****************
run=queue[0]-1000;// get the current thread tcb number
//printf(" ***fork the tcb is %d\n",run);
if(!regsave(tcb[run].reg_save_area)) // save the main thread register
{
restack(tcb[i].stack,size,2,5);// switch main thread to child thread
if(!regsave(tcb[i].reg_save_area))// save the child thread register
regrest(tcb[run].reg_save_area,1);// restore the main thread
else
{
return NULL_THREAD;// return the child thread,value is 0
}
}
else {return tcb[i].threadid;}
//printf(" fork the child id is %d",tcb[i].threadid);
}
void th_yield()
{
int loop,yieldid,currentid;
int index=-1;
int flag=0;
int temp;
temp=queue[0];// save the current thread id to temp
for(loop=0;loop<100;loop++)
{
queue[loop]=queue[loop+1];// resize the ready queue
}
while(flag==0)
{
index++;// make sure index begin with 0
if(queue[index]==0)// find where is the first 0
{
queue[index]=temp;// save the thread id that will be yield to the end of ready queue
flag=1;// end while loop
}
}
yieldid=queue[index]-1000;// for finding the yield thread tcb[]
currentid=queue[0]-1000; //
//printf("yield id is %d,currently id is %d\n",yieldid,currentid);
if(yieldid==currentid)
{
regrest(tcb[yieldid].reg_save_area,1);// avoid only one thread live, always yield itself
}
else
{
if(!regsave(tcb[yieldid].reg_save_area)) // save the yield thread register
regrest(tcb[currentid].reg_save_area,1); //let the child thread can run
}
}
void th_exit()
{
int mytcb,check;
int readythread;
mytcb=queue[0]-1000;// get current running thread's tcb number
queue[0]=0;// delete it from ready queue
for(check=0;check<100;check++)
{
queue[check]=queue[check+1]; // suspend thread will be the first
}
free(tcb[mytcb].stack);// release the memory
tcb[mytcb].threadid=0;
if(queue[0]==0) //check the ready queue,if no thread in it,exit
{
printf("there is no ready thread\n");
exit(0);
}
else
{
readythread=queue[0]-1000;
regrest(tcb[readythread].reg_save_area,1);// restore the first
}
}
int th_kill(th_id_t t)
{
int callid,nextid;
int search;
int searchid;
int unfind=0;
callid=t-1000;//get the tcb array position
//printf("\n kill function begin\n");
if(queue[0]==t)// kill itself
{
free(tcb[callid].stack); // release
tcb[callid].threadid=0; // memory
nextid=queue[1]-1000; // and thread id
queue[0]=0;
for(search=0;search<100;search++)
queue[search]=queue[search+1];// reset the ready queue
regrest(tcb[nextid].reg_save_area,1);// reset the next thread beccome current thread
}
else
{
for(search=1;search<99;search++)
{
if(queue[search]==t)
{
unfind=1;
int exitid=t-1000;// get the exit thread tcb number
free(tcb[exitid].stack);// release memory
tcb[exitid].threadid=0;
queue[search]=0;// delete from ready queue
for(searchid=search;searchid<100-search;searchid++)
{
queue[searchid]=queue[searchid+1];// pop the ready queue
}
return 1;
break;// a thread killed, return 1
}// if queue[search] end
}// for loop end
}// else end
if(unfind=0)
return 0;
}// function end
th_id_t th_myid()
{
int myid;
myid=queue[0]; // get the id from ready queue array,queue[0] is the current running thread
return myid;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -