?? ossystem.c
字號:
#include<stdlib.h>
#include<dos.h>
#include<stdio.h>
#define GET_INDOS 0x34 /* 34H 系統功能調用 */
#define BLANK -1
#define FINISHED 0 /* 終止 */
#define RUNNING 1 /* 執行 */
#define READY 2 /* 就緒 */
#define BLOCKED 3 /* 阻塞 */
#define NTCB 10 /* 系統線程的最大數 */
#define TL 1 /* 時間片大小 */
#define NBUF 10 /* 消息緩沖區數目 */
#define NTEXT 50 /* 文本輸出大小 */
char far* intdos_ptr=0;
char far* crit_err_ptr=0;
int timecount=0;
int current=-1;
typedef struct{ /* 信號量 */
int value;
struct TCB* wq;
}semaphore;
semaphore mutexfb={1,NULL};
semaphore sfb={10,NULL};
semaphore test={0,NULL};
semaphore test2={0,NULL};
struct buffer{ /* 消息緩沖區 */
int sender; /* 消息發送者的標識數 */
int size; /* 消息長度<=NTEXT 個字節 */
char text[NTEXT]; /* 消息正文 */
struct buffer* next; /* 指向下一個消息緩沖區的指針 */
}*freebuf;
struct TCB{ /* 線程控制塊 */
unsigned char* stack; /* 堆棧的起始地址 */
unsigned ss;
unsigned sp; /* 堆棧段址和堆棧指針 */
char state; /* 進程狀態 */
char name[10]; /* 線程的外部標識符 */
int value;
struct TCB* next; /* 指向控制快指針 */
struct buffer* mq; /* 消息緩沖隊列首指針 */
semaphore mutex; /* 互斥信號量 */
semaphore sm; /* 消息緩沖隊列計數信號量*/
}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 send(char *receiver,char *a,int size);
void receive(char *sender,char *a);
void p(semaphore *sem);
void v(semaphore *sem);
int Create(char* name,codeptr code,int stacklen,int value); /* 創建線程 */
/*void interrupt(&old_int8)(void)
{
old_int8=getvect(8);
}*/
void Destroy(int i);
void f1() /* 1#線程 */
{
long i,j,k;
/*test the message*/
send("f2","f1 send message to f2",NTEXT);
v(&test2);
p(&test);
/*test the call*/
/* for(i=0;i<20;i++)
{
putchar(`a`)
for(j=0;j<1000;j++)
for(k=0;k<20000;k++);
}*/
/*test the mutex*/
/*for(i=0;i<=30;i++)
{
putchar(`a`);
if(i%5==0);
p(&mutexfb);
v(&test);
}*/
}
void f2() /* 2#線程 */
{
long i,j,k;
/*test the message*/
/*char*a=(char*)malloc((20*sizeof(char);*/
char a[NTEXT];
p(&test2);
receive("f1",a);
v(&test);
printf("%s",a);
/*test the call*/
/*for(i=0;i<10;i++)
{
putchar(`b`);
for(j=0;j<1000;j++)
for(k=0;k<20000;k++);
}*/
/*test the mutex*/
/*for(i=o;i<=30;i++)
{
putchar(`b`);
if(i%5==0)
v(&mutexfb);
v(&test);
}*/
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; /* 初始狀態標志 */
tcb[i].mq=NULL;
tcb[i].mutex.value=1;
tcb[i].mutex.wq=NULL;
tcb[i].sm.value=0;
tcb[i].sm.wq=NULL;
}
}
void over()
{
Destroy(current);
swtch();
}
int Create(char*name,codeptr code,int stacklen,int value)
{
int i;
char*p;
struct int_regs*pt;
for(i=1;i<NTCB;i++)
{
if(tcb[i].state==BLANK||tcb[i].state==FINISHED)
break;
}
if(i==NTCB)
return-1;
tcb[i].value=value;
strcpy(tcb[i].name,name);
tcb[i].stack=p=(unsigned char*)malloc(stacklen);
p=p+stacklen;
pt=(struct int_regs*)p;
pt--;
pt->Flags=0x200;
pt->CS=FP_SEG(code);
pt->IP=FP_OFF(code);
pt->off=FP_OFF(over);
pt->seg=FP_SEG(over);
pt->DS=_DS;
pt->ES=_ES;
tcb[i].sp=FP_OFF(pt);
tcb[i].ss=FP_SEG(pt);
tcb[i].state=READY;
return i;
}
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,j;
for(i=0;i<NTCB;i++)
if(tcb[i].state==READY&&i!=current)
break;
for(j=i+1;j<NTCB;j++)
{
if(tcb[j].state==READY&&j!=current)
if(tcb[j].value>tcb[i].value)
i=j;
}
if(i==NTCB)
return -1;
return i;
}
void interrupt new_int8(void) /* CPU 調度*/
{
int i;
(*old_int8)(); /* 指向原來時鐘中斷處理過程入口的中斷處理函數指針 */
timecount++;
if(timecount==TL) /* 時間片是否到? */
{
if(!DosBusy()) /* DOS是否忙? */
{
disable();
tcb[current].ss=_SS; /* 保存現場 */
tcb[current].sp=_SP;
if(tcb[current].state==RUNNING)
tcb[current].state=READY;
i=Find();
if(i<0)
return;
_SS=tcb[i].ss;
_SP=tcb[i].sp;
tcb[i].state=RUNNING;
current=i;
timecount=0; /* 重新計時 */
enable();
}
else
return;
}
else
return;
}
void interrupt swtch() /* 其他原因CPU調度 */
{
int i;
if(tcb[current].state!=FINISHED&¤t!=0&&tcb[current].state!=BLOCKED) /* 當前線程還沒結束 */
return;
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 block(struct TCB**p) /* 阻塞原語 */
{
struct TCB*pl;
tcb[current].state=BLOCKED;
if((*p)==NULL)
*p=&tcb[current]; /* 阻塞隊列空,直接放入 */
else
{
pl=*p;
while(pl->next!=NULL)
pl=pl->next; /* 找到阻塞隊列最后一個節點 */
pl->next=&tcb[current]; /* 放入阻塞隊列 */
}
tcb[current].next=NULL;
swtch(); /* 重新進行CPU調度 */
}
void wakeup_first(struct TCB**p) /* 喚醒隊首線程 */
{
struct TCB*pl;
if((*p)==NULL)
return;
pl=(*p);
(*p)=(*p)->next; /* 得到阻塞隊列隊首線程 */
pl->state=READY; /* 修為就緒狀態 */
pl->next=NULL;
}
void p(semaphore*sem)
{
struct TCB**qp;
disable();
sem->value=sem->value-1;
if(sem->value<0)
{
qp=&(sem->wq);
block(qp);
}
enable();
}
void v(semaphore*sem)
{
struct TCB**qp;
disable();
qp=&(sem->wq);
sem->value=sem->value+1;
if(sem->value>=0)
wakeup_first(qp);
enable();
}
struct buffer*Initbuf(void)
{
struct buffer *p,*pt,*pt2;
int i;
pt2=pt=(struct buffer*)malloc(sizeof(struct buffer));
pt->sender=-1;
pt->size=0;
strcmp(pt->text,"");
pt->next=NULL;
for(i=0;i<NBUF-1;i++)
{
p=(struct buffer*)malloc(sizeof(struct buffer));
p->sender=-1;
p->size=0;
p->text[NTEXT]='\0';
p->next=NULL;
pt2->next=p;
pt2=p;
}
return pt;
}
struct buffer*getbuf(void) /* 從空閑消息緩沖隊列隊頭上取下一緩沖區 */
{
struct buffer*buff;
buff=freebuf; /* 取得緩沖隊列的緩沖區*/
freebuf=freebuf->next;
return(buff); /* 返回指向該緩沖區的指針 */
}
void putbuf(struct buffer*pt)
{
struct buffer*p=freebuf;
while(p->next!=NULL)
p=p->next;
p->next=pt;
pt->next=NULL;
}
void insert(struct buffer**mq,struct buffer*buff)
{ /* 將buff所指的緩沖區插到*mq所指的緩沖隊列末尾*/
struct buffer*temp;
if(buff==NULL)return; /* buff為空 */
buff->next=NULL;
if(*mq==NULL) /* *mq為空 則直接插入*/
*mq=buff;
else
{
temp=*mq;
while(temp->next!=NULL) /* 找到隊尾 */
temp=temp->next;
temp->next=buff; /* 插入隊列末尾 */
}
}
void send(char*receiver,char*a,int size)
{ /* 將地址a開始的size個字節發送給外部標識符為receiver的線程 */
struct buffer*buff;
int i,id=-1;
disable();
for(i=0;i<NTCB;i++) /* 找receiver相對應的線程號*/
{
if(strcmp(receiver,tcb[i].name)==0)
{
id=i;
break;
}
}
if(id==-1) /* 沒找到 */
{
printf("Error:Receiver 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);/* buff所指的緩沖區插到相應線程的消息緩沖隊列末尾 */
v(&tcb[id].mutex);
v(&tcb[id].sm); /* 對應于p(&sfb),線程的消息緩沖隊列數量的互斥操作 */
enable();
}
void receive(char *sender,char *a)
{
struct buffer *buff;
int i;
disable();
for(i=0;i<NTCB;i++)
if(strcmp(sender,tcb[i].name)==0)
break;
if(i==NTCB)
{
printf("error:sender not exist!\n");
enable();
return;
}
if(tcb[current].mq==NULL)
return;
p(&tcb[current].mutex); /* 當前線程的消息緩沖隊列資源的互斥操作*/
buff=tcb[current].mq;
tcb[current].mq=tcb[current].mq->next;
for(i=0;i<buff->size;i++,a++) /* 輸出所接受的內容 */
(*a)=buff->text[i];
/*a=buff->next*/
v(&tcb[current].mutex); /* 當前線程的消息緩沖隊列資源的互斥操作 */
p(&mutexfb);
buff->sender=-1;
buff->size=0;
strcmp(buff->text,"");
buff->next=NULL;
putbuf(buff);
v(&mutexfb);
p(&sfb);
p(&tcb[current].sm);
v(&test); /* 對應于p(&Tcb[current].sm) */
}
void main()
{
InitInDos();
InitTcb();
freebuf=Initbuf();
old_int8=getvect(8);
strcpy(tcb[0].name,"main");
tcb[0].state=RUNNING;
tcb[0].value=0;
current=0;
Create("f1",(codeptr)f1,1024,5);
Create("f2",(codeptr)f2,1024,6);
tcb_state();
/*setvect(8,new_int8);*/
swtch();
/*for(i=0;i<5000000;i++);*/
while(!all_finished());
tcb[0].name[0]='\0';
tcb[0].state=FINISHED;
setvect(8,old_int8);
tcb_state();
printf("\n Muli_task system teminated \n");
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -