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

📄 threadlibrary.c

📁 I use C to implement thread operating,include initiallize,fork,yield,exit,kill. You should have driv
💻 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 + -