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

📄 3.txt

📁 操作系统 线程的调度根据时间片轮转和消息缓冲区的通信
💻 TXT
字号:

#include <stdlib.h>
#include <dos.h>
#include <stdio.h>

#define GET_INDOS 0x34
#define GET_CRIT_ERR 0x5d06

#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* indos_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 empty={10,NULL};
semaphore full={0,NULL};

struct buffer{
  int sender;
  int size;
  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 Destroy(int i);

void f1()
{
  long i,j,k;
for(i=0;i<20;i++)
   {
      p(&empty);
      
      send("f2","f1 send message to f2",NTEXT);
      v(&full);
      for(j=0;j<1000;j++)
	 for(k=0;k<20000;k++);
   }     

  

 for(i=0;i<20;i++)
   {
    putchar('a');
      for(j=0;j<1000;j++)
	 for(k=0;k<20000;k++);
   }     
}

void f2()
{
  long i,j,k;
  char a[NTEXT];
for(i=0;i<10;i++)
  {
       p(&full);
  receive("f1",a);
  v(&empty);
  printf("%s",a);

          for(j=0;j<1000;j++)
	for(k=0;k<20000;k++);
  }

  p(&full);
  receive("f1",a);
  v(&empty);
  printf("%s",a);

 
 for(i=0;i<10;i++)
  {
     putchar('b');
     for(j=0;j<1000;j++)
	for(k=0;k<20000;k++);
  }

  printf("\n");
}

void InitInDos()
{
  union REGS regs;
  struct SREGS segregs;

  regs.h.ah=GET_INDOS;
  intdosx(&regs,&regs,&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(&regs,&regs,&segregs);
      crit_err_ptr=MK_FP(segregs.ds,regs.x.si);
    }
}

int DosBusy(void)
{
  if(indos_ptr&&crit_err_ptr)
    return (*indos_ptr||*crit_err_ptr);
  else
    return(-1);
}
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)
{
   int i;
   (*old_int8) ();
   timecount++;
   if(timecount==TL)
   {
     if(DosBusy)
     {
	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()
{
  int i;
  if(tcb[current].state!=FINISHED&&current!=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* p1;
  tcb[current].state=BLOCKED;

  if((*p)==NULL)
	  *p=&tcb[current];
  else
  {
	  p1=*p;
	  while(p1->next!=NULL)
		  p1=p1->next;
	  p1->next=&tcb[current];
  }
  tcb[current].next=NULL;
  swtch();
}

void wakeup_first(struct TCB**p)
{
  struct TCB *p1;
  if((*p)==NULL)
	  return ;
  p1=(*p);
  (*p)=(*p)->next;
  p1->state=READY;
  p1->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)
{
  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;
  }
}

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: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);
  v(&tcb[id].mutex);
  v(&tcb[id].sm);

  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];
  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);
  
}

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();
 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 + -