#include<stdlib.h>
#include<dos.h>
#include<stdio.h>
#define GET_INDOS 0x34 /* 34H 系统功能调用 */
#define GET_CRIT_ERR 0x5d06 /* 5D06H号系统功能调用 */
#define BLANK -1
#define FINISHED 0 /* 终止 */
#define RUNNING 1 /* 执行 */
#define READY 2 /* 就绪 */
#define BLOCKED 3 /* 阻塞 */
#define NTCB 10 /* 系统线程的最大数 */
#define TL 2 /* 时间片大小 */
char far* intdos_ptr=0;
char far* crit_err_ptr=0;
int timecount=0;
int current=-1;
int test;
struct TCB{ /* 线程控制块 */
unsigned char* stack; /* 堆栈的起始地址 */
unsigned ss;
unsigned sp; /* 堆栈段址和堆栈指针 */
char state; /* 进程状态 */
char name[10]; /* 线程的外部标识符 */
}tcb[NTCB];
struct int_regs{ /* 现场保护和恢复结构体 */
unsigned Bp,DI,SI,DS,ES,DX,CX,BX,AX,IP,CS,Flags,off,seg;
};
typedef int(far* codeptr)(void);
void interrupt(*old_int8)(void);
int DosBusy(void);
void InitIndos(void);
void InitTcb();
void interrupt new_int8(void);
void interrupt swtch();
void Create(char* name,codeptr code,int stacklen); /* 创建线程 */
void Destroy(int i);
void f1() /* 1#线程 */
{
int i,j,k;
for(i=0;i<40;i++)
{
printf("a");
for(j=0;j<1000;j++)
for(k=0;k<5000;k++);
}
}
void f2() /* 2#线程 */
{
int i,j,k;
for(i=0;i<40;i++)
{
printf("b");
for(j=0;j<1000;j++)
for(k=0;k<5000;k++);
}
printf("/n");
}
void InitInDos() /* 取得INDOS标志和严重错误标志地址 */
{
union REGS regs;
struct SREGS segregs;
regs.h.ah=GET_INDOS; /* 使用34H号系统功能调用 */
intdosx(®s,®s,&segregs);
intdos_ptr=MK_FP(segregs.es,regs.x.bx);
if(_osmajor<3)
crit_err_ptr=intdos_ptr+1; /* 严重错误在INDOS后一字节处 */
else if(_osmajor==3&&_osminor==0)
crit_err_ptr=intdos_ptr-1; /* 严重错误在INDOS前一字节处 */
else
{
regs.x.ax=GET_CRIT_ERR;
intdosx(®s,®s,&segregs);
crit_err_ptr=MK_FP(segregs.ds,regs.x.si);
}
}
int DosBusy(void) /* 判断DOS是否忙 */
{
if(intdos_ptr&&crit_err_ptr)
return(*intdos_ptr||*crit_err_ptr); /* DOS忙,返回严重错误标志 */
else
return(-1); /* DOS不忙 */
}
void InitTcb() /* 初始化线程 */
{
int i;
for(i=0;i<NTCB;i++)
{
tcb[i].state=BLANK; /* 初始状态标志 */
}
}
void over()
{
Destroy(current);
swtch();
}
void Create(char *name,codeptr code,int stacklen)
{
int i;
struct int_regs *p;
for(i=1;i<NTCB;i++)
{
if(tcb[i].state==BLANK||tcb[i].state==FINISHED)
break;
}
if(i==NTCB)
return;
strcpy(tcb[i].name,name);
tcb[i].stack=(unsigned char *)malloc(stacklen);
tcb[i].stack+=stacklen;
p=(struct int_regs *)tcb[i].stack;
p--;
p->Flags=0x200;
p->CS=FP_SEG(code);
p->IP=FP_OFF(code);
p->off=FP_OFF(over);
p->seg=FP_SEG(over);
p->DS=_DS;
p->ES=_ES;
tcb[i].sp=FP_OFF(p);
tcb[i].ss=FP_SEG(p);
tcb[i].state=READY;
return;
}
void Destroy(int i)
{
disable();
if(tcb[i].state==RUNNING)
{
disable();
tcb[i].state=FINISHED;
strcpy(tcb[i].name,NULL);
free(tcb[i].stack);
enable();
}
return;
}
void tcb_state() /* 线程状态信息 */
{
int i;
for(i=0;i<NTCB;i++)
if(tcb[i].state!=BLANK)
{
switch(tcb[i].state)
{
case FINISHED:
printf("tcb[%d] is FINISHED/n",i);
break;
case RUNNING:
printf("tcb[%d] is RUNNING/n",i);
break;
case READY:
printf("tcb[%d] is READY/n",i);
break;
case BLOCKED:
printf("tcb[%d] is BLOCKED/n",i);
break;
}
}
}
int Find()
{
int i;
for(i=current +1 ;i<NTCB;i++)
if(tcb[i].state==READY)
{
return i;
}
for(i = 0; i < current; i++)
if(tcb[i].state==READY)
{
return i;
}
if(i==NTCB)
return -1;
}
void interrupt new_int8(void) /* CPU 调度*/
{
int i;
(*old_int8)();
timecount++;
if(timecount >= TL)
{
if(DosBusy())
{
return;
}
else
{
int ready;
disable();
/*保存旧线程的指针*/
tcb[current].ss = _SS;
tcb[current].sp = _SP;
if(tcb[current].state == RUNNING)
tcb[current].state = READY;
ready = Find();
/*切换线程*/
_SS = tcb[ready].ss;
_SP = tcb[ready].sp;
tcb[ready].state = RUNNING;
current=ready;
timecount=0;
enable();
}
}
}
void interrupt swtch() /* 其他原因CPU调度 */
{
int i;
i=Find();
if(i<0)
return;
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; /* 保存现场 */
tcb[i].state=RUNNING;
current=i;
enable();
}
int all_finished()
{
int i;
for(i=1;i<NTCB;i++)
if(tcb[i].state==RUNNING||tcb[i].state==BLOCKED||tcb[i].state==READY)
return 0;
return 1;
}
void main()
{
InitInDos();
InitTcb();
old_int8=getvect(8);
strcpy(tcb[0].name,"main");
tcb[0].state=RUNNING;
current=0;
Create("f1",(codeptr)f1,1024);
Create("f2",(codeptr)f2,1024);
tcb_state();
setvect(8,new_int8);
swtch();
while(!all_finished());
tcb[0].name[0]='/0';
tcb[0].state=FINISHED;
setvect(8,old_int8);
tcb_state();
printf("/nMuli_task system teminated /n");
system("PAUSE");
}