|
#include
#include
#include
#include
#define FINISHED 0
#define RUNNING 1
#define READY 2
#define BLOCKED 3
#define NTCB 10
#define NBUF 10
#define NTEXT 50
#define GET_INDOS 0x34
#define GET_CRIT_ERR 0x5d06
#define TL 2
struct tcb_stack{
unsigned bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags,off,seg;
};
struct buffer{
int sender;/*消息发送者的标识数*/
int size;/*消息长度*/
char text[NTEXT];/*消息正文*/
struct buffer * next;/*指向下一个消息缓冲区的指针*/
}*freebuf;
typedef struct{
int value;
struct TCB * wq;
}semaphore;
semaphore mutexfb; /*消息缓冲区的互斥信号量*/
semaphore sfb; /*空闲缓冲队列的计数信号量*/
struct TCB{
unsigned char * stack;
unsigned ss;
unsigned sp;
char state;
char name[10];
int ID;
struct TCB *next;
struct buffer * mq;/*消息队列队首指针*/
semaphore mutex;/*消息队列的互斥信号量*/
semaphore sm;/*消息队列的计数信号量*/
}tcb[NTCB];
typedef struct TCB *READYQUEUE;
typedef int (far *codeptr)(void);
char far *indos_ptr=0;
char far *crit_err_ptr=0;
int current;
int timecount=0;
int count1,count2;
READYQUEUE readyhead;
int DosBusy(void); /*判断DOS是否忙或出现严重错误*/
void InitInDos(void); /*获得DOS状态标志位*/
void f1(void);
void f2(void);
void tcb_state(); /*打印所有线程状态*/
void InitTcb(); /*初始化TCB*/
int all_finished(void); /*判断所有线程是否结束*/
void interrupt swtch(void);
void interrupt swtch2(void);
void interrupt new_int8(void); /*新的时钟中断*/
void interrupt (*old_int8)(void);
void Create(char * name,codeptr code,int stacklen); /*线程创建函数*/
void Over(); /*线程终止函数*/
void Destroy(int i); /*释放线程堆栈指针*/
int Choose_FIFO(); /*先进先出调度算法*/
int Choose_Priority(); /*基于优先级的调度算法*/
void P(semaphore *sem); /*P操作*/
void V(semaphore *sem); /*V操作*/
void wakeup_first(struct TCB **qp); /*线程唤醒原语*/
void block(struct TCB **qp); /*线程阻塞原语*/
void add();
void changecount1();
struct buffer * getbuf(void);
void insert (struct buffer ** mq,struct buffer * buff); /*将buff所指的缓冲区插到*mq所指的缓冲队列末尾*/
void send(char * receiver,char * a,int size);
void Freebuf(struct buffer * buff);
void Initbuff(void);
void receive(char * sender);
void SysInit(void);
main()
{
int i,j,k;
SysInit();
strcpy(tcb[0].name,"main");
tcb[0].state=RUNNING;
Create("f1",(codeptr)f1,1024);
Create("f2",(codeptr)f2,1024);
Create("f3",(codeptr)add,1024);
tcb_state();
swtch();
/* setvect(8,new_int8);
for(i=0;i<20;i++)
{
putchar('c');
for(j=0;j<10000;j++)
for(k=0;k<10000;k++)
;
}
printf("\n");
Create("f2",(codeptr)f2,1024);
swtch();*/
receive("f1");
while(!all_finished())
swtch();
tcb[0].name[0]='\0';
tcb[0].state=FINISHED;
setvect(8,old_int8);
tcb_state();
printf("\n Multi_task system terminated.\n");
getchar();
}
/***************************************************************
** 函数名:f1
** 功能:
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void f1(void)
{
int i,j,k,size;
char s[20] = "Hello,world!";
size = strlen(s);
for(i=0;i<20;i++)
{
putchar('a');
for(j=0;j<1;j++)
for(k=0;k<1;k++)
;
}
printf("\n");
}
/***************************************************************
** 函数名:f2
** 功能:
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void f2(void)
{
long i,j,k;
swtch();
for(i=0;i<10;i++)
{
putchar('b');
for(j=0;j<1;j++)
for(k=0;k<1;k++)
;
}
printf("\n");
}
/***************************************************************
** 函数名:tcb_state
** 功能:输出所有线程当前的运行状态
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void tcb_state()
{
int i;
for(i=0;i{
printf("Thread[%d]state is:",i);
if(tcb[i].state==FINISHED)
printf("FINNISHED!\n");
else if(tcb[i].state==RUNNING)
printf("RUNNING!\n");
else if(tcb[i].state==BLOCKED)
printf("BLOCKED!\n");
else
printf("READY!\n");
}
}
/***************************************************************
** 函数名:all_finished
** 功能:判断所有线程运行是否结束
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
int all_finished()
{
int i;
int flag;
for(i=1;i{
if(tcb[i].state!=FINISHED)
return 0;
}
return 1;
}
/***************************************************************
** 函数名:add
** 功能:两数相加
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void add()
{
int i,sum,j,k;
count1=0;
count2=0;
/*P(&mutex);*/
for(i=0;i<10;i++)
{
count1++;
sum=count1+count2;
printf("%d\n",sum);
printf("Adding!\n");
for(j=0;j<1;j++)
for(k=0;k<1;k++)
;
}
/* V(&mutex);*/
}
/***************************************************************
** 函数名:changecount1
** 功能:改变count1的值
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void changecount1()
{
int i,j,k;
for(i=0;i<10;i++)
{
count1-=10;
printf("%d\n",count1);
printf("Changing!!\n");
for(j=0;j<10000;j++)
for(k=0;k<10000;k++)
;
}
}
/***************************************************************
** 函数名:SysInit
** 功能:系统初始化
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void SysInit(void)
{
readyhead->next = NULL;
InitInDos();
InitTcb();
Initbuff();
old_int8 = getvect(8);
current = 0;
mutexfb.value = 1;
mutexfb.wq = NULL;
sfb.value = 10;
sfb.wq = NULL;
}
/***************************************************************
** 函数名:InitInDos
** 功能:获得DOS标志位
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void InitInDos(void)
{
union REGS regs;
struct SREGS segregs;
regs.h.ah=GET_INDOS;
intdosx(®s,®s,&segregs);
indos_ptr=MK_FP(segregs.es,regs.x.bx);
if(_osmajor<3)
crit_err_ptr=indos_ptr+1;
else if(_osmajor==3&&_osminor==0)
crit_err_ptr=indos_ptr-1;
else
{
regs.x.ax=GET_CRIT_ERR;
intdosx(®s,®s,&segregs);
crit_err_ptr=MK_FP(segregs.ds,regs.x.si);
}
}
/***************************************************************
** 函数名:DosBusy
** 功能:判断DOS是否忙
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
int DosBusy(void)
{
if(indos_ptr&&crit_err_ptr)
return (*indos_ptr||*crit_err_ptr);
else
return -1;
}
/***************************************************************
** 函数名:swtch
** 功能:线程切换
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void interrupt swtch(void)
{
int i;
i=Choose_FIFO();
disable();
tcb[current].ss=_SS;
tcb[current].sp=_SP;
if(tcb[current].state==RUNNING)
tcb[current].state=READY;
_SS=tcb[i].ss;
_SP=tcb[i].sp;
current=i;
tcb[i].state=RUNNING;
/*printf("%s is running\n",tcb[i].name);*/
enable();
/*tcb_state();*/
}
/***************************************************************
** 函数名:InitTcb
** 功能:初始化TCB
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void InitTcb()
{
int i;
for(i=0;i{
tcb[i].name[0] = '\0';
tcb[i].state = FINISHED;
tcb[i].ID = i;
tcb[i].next = NULL;
tcb[i].mq = NULL;
tcb[i].mutex.value = 1;
tcb[i].mutex.wq = NULL;
tcb[i].sm.value = 0;
tcb[i].sm.wq = NULL;
}
}
/***************************************************************
** 函数名:new_int8
** 功能:新的时钟中断,中断产生间隔TL
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void interrupt new_int8()
{
int i;
old_int8();
timecount++;
if(timecount==TL)
{
if(!DosBusy())
{
i=Choose_FIFO();
disable();
tcb[current].ss=_SS;
tcb[current].sp=_SP;
if(tcb[current].state==RUNNING)
tcb[current].state=READY;
_SS=tcb[i].ss;
_SP=tcb[i].sp;
current=i;
tcb[i].state=RUNNING;
/*printf("%s is running\n",tcb[i].name);*/
timecount=0;
enable();
}
}
}
/***************************************************************
** 函数名:Create
** 功能:创建线程函数
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void Create(char * name,codeptr code,int stacklen)
{
int i,flag=0;
unsigned char * temp1;
struct tcb_stack * temp2;
for(i=1;i if(tcb[i].state==FINISHED)
{
strcpy(tcb[i].name,name);
tcb[i].stack=(unsigned char *)malloc(stacklen);
temp1=tcb[i].stack+stacklen;
temp2=(struct tcb_stack *)temp1-1;
temp2->ds=_DS;
temp2->es=_ES;
temp2->ip=FP_OFF(code);
temp2->cs=FP_SEG(code);
temp2->flags=0x200;
temp2->off=FP_OFF(Over);
temp2->seg=FP_SEG(Over);
tcb[i].sp=FP_OFF(temp2);
tcb[i].ss=FP_SEG(tcb[i].stack);
tcb[i].state=READY;
tcb[i].next=readyhead->next;
readyhead->next=&tcb[i];
flag=1;
break;
}
if(flag==0)
printf("No free TCB!");
}
/***************************************************************
** 函数名:Over
** 功能:撤销线程函数
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void Over()
{
Destroy(current);
swtch();
}
/***************************************************************
** 函数名:Destroy
** 功能:释放线程私有堆栈
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void Destroy(int i)
{
if(tcb[i].state==RUNNING)
{
disable();
tcb[i].state=FINISHED;
free(tcb[i].stack);
enable();
}
return;
}
/***************************************************************
** 函数名:Choose_FIFO
** 功能:先进先出调度算法
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
int Choose_FIFO()
{
READYQUEUE temp,temp1;
temp=readyhead->next;
temp1=readyhead;
while(temp&&temp->next!=NULL)
{
temp=temp->next;
temp1=temp1->next;
}
temp1->next=NULL;
if(tcb[current].state==RUNNING)
{
tcb[current].next=readyhead->next;
readyhead->next=&tcb[current];
}
if(temp!=NULL)
{
return temp->ID;
}
}
/***************************************************************
** 函数名:Choose_Priority
** 功能:基于优先级的调度算法
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
int Choose_Priority()
{
}
/***************************************************************
** 函数名:P
** 功能:P操作
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void P(semaphore *sem)
{
struct TCB **qp;
disable();
sem->value=sem->value-1;
if(sem->value<0)
{
qp=&(sem->wq);
block(qp);
}
enable();
}
/***************************************************************
** 函数名:V
** 功能:V操作
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void V(semaphore *sem)
{
struct TCB **qp;
disable();
qp=&(sem->wq);
sem->value=sem->value+1;
if(sem->value<=0)
wakeup_first(qp);
enable();
}
/***************************************************************
** 函数名:block
** 功能:阻塞线程
** 被调用函数:
** 调用函数:
** 算法:每次都把需要阻塞的线程添加到队尾
** 作者:Visable
****************************************************************/
void block(struct TCB **qp)
{
struct TCB * p;
tcb[current].state=BLOCKED;
if((*qp)==NULL)
{
(*qp)=&(tcb[current]);
swtch();
}
else
{
p=(*qp);
while(p->next)
p=p->next;
p->next=&(tcb[current]);
swtch();
}
}
/***************************************************************
** 函数名:weakup_first
** 功能:唤醒第一个被阻塞的线程
** 被调用函数:
** 调用函数:
** 算法:取出阻塞队列中的第一个线程,调度执行
** 作者:Visable
****************************************************************/
void wakeup_first(struct TCB **qp)
{
struct TCB * p;
struct TCB * q;
q=(*qp);
if(q!=NULL)
{
(*qp)=(*qp)->next;
q->state=READY;
q->next=NULL;
p=readyhead->next;
while(p&&p->next){
p=p->next;
}
p->next=q;
}
}
/***************************************************************
** 函数名:getbuf
** 功能:从空闲消息缓冲队列头上取下一缓冲区返回指向该缓冲区的指针
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
struct buffer * getbuf(void)
{
struct buffer *buff;
buff=freebuf;
freebuf=freebuf->next;
return (buff);
}
/***************************************************************
** 函数名:insert
** 功能:将buff所指的缓冲区插到*mq所指的缓冲队列末尾
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void insert (struct buffer ** mq,struct buffer * buff)
{
struct buffer *temp;
if(buff==NULL)
return;
buff->next=NULL;
if(*mq==NULL)
*mq=buff;
else
{
temp=*mq;
while(temp->next!=NULL)
temp=temp->next;
temp->next=buff;
}
}
/***************************************************************
** 函数名:send
** 功能:将地址a开始的size个字节发送给外部标识符为reciever的线程
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void send(char * receiver,char * a,int size)
{
struct buffer * buff;
int i,id=-1;
disable();
for(i = 0;i < NTCB;i++)
{
if(strcmp(receiver,tcb[i].name)==0){
id=i;
break;
}
}
if(id==-1){
printf("Error:Reciever not exist!\n");
enable();
return;
}
P(&sfb);
P(&mutexfb);
buff=getbuf();
V(&mutexfb);
buff->sender=current;
buff->size=size;
buff->next=NULL;
for(i = 0;i < buff->size;i++,a++)
buff->text[i] = *a;
P(&tcb[id].mutex);
insert(&(tcb[id].mq),buff);
V(&tcb[id].mutex);
V(&tcb[id].sm);
enable();
}
/***************************************************************
** 函数名:receive
** 功能:
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void receive(char * sender)
{
struct buffer *buff;
int i;
for(i = 0;i < NTCB;i++)
if(strcmp(sender,tcb[i].name)==0&& tcb[i].state != FINISHED)
break;
if(i == NTCB)
{
printf("Error:Sender not exist!\n");
enable();
return;
}
P(&tcb[current].sm);
P(&tcb[current].mutex);
buff = tcb[current].mq;
tcb[current].mq = tcb[current].mq->next;
for(i = 0;i < buff->size;i++)
printf("%c", buff->text[i]);
V(&tcb[current].mutex);
buff->sender = -1;
buff->size = 0;
buff->text[0] = '\0';
buff->next = NULL;
P(&mutexfb);
Freebuf(buff);
V(&mutexfb);
V(&sfb);
enable();
}
/***************************************************************
** 函数名:Freebuf
** 功能:将buff所指的缓冲区插到*freebuf所指的缓冲队列末尾
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void Freebuf(struct buffer * buff)
{
struct buffer * temp;
if(freebuf == NULL)
freebuf = buff;
else
{
temp = freebuf;
while(temp->next!=NULL)
temp = temp->next;
temp->next = buff;
buff->next = NULL;
}
}
/***************************************************************
** 函数名:Initbuff
** 功能:初始化缓冲区
** 被调用函数:
** 调用函数:
** 算法:
** 作者:Visable
****************************************************************/
void Initbuff(void)
{
int i;
struct buffer * temp;
freebuf = (struct buffer *)malloc(sizeof(struct buffer));
temp = freebuf;
for(i = 0;i <= NBUF;i++)
{
temp = temp->next;
temp = (struct buffer *)malloc(sizeof(struct buffer));
temp->next = NULL;
}
}
|