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

📄 smpl.c

📁 排队论中的一个仿真程序
💻 C
📖 第 1 页 / 共 2 页
字号:
                { /* requesting token's priority is not higher than   */
                  /* that of any user: enqueue requestor & return r=1 */
                  enqueue(f,tkn,pri,event,0.0); r=1;
                  if (tr) then msg(7,tkn,fname(f),1,l3[f]);
                }
              else
                { /* preempt user of server k.  suspend event, save   */
                  /* event number & remaining event time, & enqueue   */
                  /* preempted token.  If remaining event time is 0   */
                  /* (preemption occurred at the instant release was  */
                  /* to occur, set 'te' > 0 for proper enqueueing     */
                  /* (see 'enlist').  Update facility & server stati- */
                  /* stics for the preempted token, and set r = 0 to  */
                  /* reserve the facility for the preempting token.   */
                  if (tr) then msg(8,tkn,fname(f),2,0);
                  j=l1[k]; i=suspend(j); ev=l3[i]; te=l5[i]-clock;
                  if (te==0.0) then te=1.0e-99; put_elm(i);
                  enqueue(f,j,l2[k],ev,te);
                  if (tr) then
                    {msg(10,-1,"",j,l3[f]); msg(12,-1,fname(f),tkn,0);}
                  l3[k]++; l4[k]+=clock-l5[k];
                  l2[f]--; l4[f+1]++; r=0;
                }
          }
      if (r==0) then
        { /* reserve server k of facility */
          l1[k]=tkn; l2[k]=pri; l5[k]=clock; l2[f]++;
        }
      return(r);
    }

/*------------------------  RELEASE FACILITY  ------------------------*/
release(f,tkn)
  int f,tkn;
    {
      int i,j=0,k,m; real te;
      /* locate server (j) reserved by releasing token */
      k=f+1+l1[f];     /* index of last server element */
      for (i=f+2; i<=k; i++) if (l1[i]==tkn) then {j=i; break;}
      if (j==0) then error(7,NULL); /* no server reserved */
      l1[j]=0; l3[j]++; l4[j]+=clock-l5[j]; l2[f]--;
      if (tr) then msg(9,tkn,fname(f),0,0);
      if (l3[f]>0) then
        { /* queue not empty:  dequeue request ('k' =  */
          /* index of element) & update queue measures */
          k=l1[f+1]; l1[f+1]=l1[k]; te=l4[k];
          l5[f+1]+=l3[f]*(clock-l5[f]); l3[f]--; l4[f]++; l5[f]=clock;
          if (tr) then msg(11,-1,"",l2[k],l3[f]);
          if (te==0.0) then
            then
              { /* blocked request:  place request at head of event   */
                /* list (so its facility request can be re-initiated  */
                /* before any other requests scheduled for this time) */
                l5[k]=clock; l1[k]=evl; evl=k; m=4;
              }
            else
              { /* return after preemption:  reserve facility for de- */
                /* queued request & reschedule remaining event time   */
                l1[j]=l2[k]; l2[j]=(int)l5[k]; l5[j]=clock; l2[f]++;
                if (tr) then msg(12,-1,fname(f),l2[k],0);
                l5[k]=clock+te; enlist(&evl,k); m=5;
              }
          if (tr) then msg(m,-1,"",l3[k],0);
        }
    }

/*-----------------------  GET FACILITY STATUS  ----------------------*/
status(f)
  int f;
    {
      return(l1[f]==l2[f]? 1:0);
    }

/*--------------------  GET CURRENT QUEUE LENGTH  --------------------*/
inq(f)
  int f;
    {
      return(l3[f]);
    }

/*--------------------  GET FACILITY UTILIZATION  --------------------*/
real U(f)
  int f;
    {
      int i; real b=0.0,t=clock-start;
      if (t>0.0) then
        {
          for (i=f+2; i<=f+l1[f]+1; i++) b+=l4[i];
          b/=t;
        }
      return(b);
    }

/*----------------------  GET MEAN BUSY PERIOD  ----------------------*/
real B(f)
  int f;
    {
      int i,n=0; real b=0.0;
      for (i=f+2; i<=f+l1[f]+1; i++) {b+=l4[i]; n+=l3[i];}
      return((n>0)? b/n:b);
    }

/*--------------------  GET AVERAGE QUEUE LENGTH  --------------------*/
real Lq(f)
  int f;
    {
      real t=clock-start;
      return((t>0.0)? (l5[f+1]/t):0.0);
    }

/*-----------------------  TURN TRACE ON/OFF  ------------------------*/
trace(n)
  int n;
    {
      switch(n)
        {
          case 0: tr=0; break;
          case 1:
          case 2:
          case 3: tr=n; tl= -1.0; newpage(); break;
          case 4: end_line(); break;
         default: break;
        }
    }

/*--------------------  GENERATE TRACE MESSAGE  ----------------------*/
static msg(n,i,s,q1,q2)
  int n,i,q1,q2; char *s;
    {
      static char *m[14] = {"",  "SCHEDULE", "CAUSE", "CANCEL",
        "   RESCHEDULE","   RESUME", "   SUSPEND", "REQUEST", "PREEMPT",
        "RELEASE", "   QUEUE", "   DEQUEUE", "   RESERVE", "FACILITY" };
      if (clock>tl)     /* print time stamp (if time has advanced) */
        then {tl=clock; fprintf(opf,"  time %-12.3f  ",clock);}
        else fprintf(opf,"%21s",m[0]);
      if (i>=0)         /* print token number if specified */
        then fprintf(opf,"--  token %-4d  -- ",i);
        else fprintf(opf,"--              -- ");
      fprintf(opf,"%s %s",m[n],s);  /* print basic message */
      switch(n)
        { /* append qualifier */
          case 1:
          case 2:
          case 3:
          case 4:
          case 5:
          case 6:  fprintf(opf," EVENT %d",q1); break;
          case 7:
          case 8:  switch(q1)
                     {
                       case 0: fprintf(opf,":  RESERVED"); break;
                       case 1: fprintf(opf,":  QUEUED  (inq = %d)",q2);
                               break;
                       case 2: fprintf(opf,":  INTERRUPT"); break;
                       default: break;
                     }
                   break;
          case 9:  break;
          case 10:
          case 11: fprintf(opf," token %d  (inq = %d)",q1,q2); break;
          case 12: fprintf(opf," for token %d",q1); break;
          case 13: fprintf(opf,":  f = %d",q1); break;
          default: break;
        }
      fprintf(opf,"\n"); end_line();
    }

/*-------------------------  TRACE LINE END  -------------------------*/
static end_line()
  {
    if ((--lft)==0) then
      { /* end of page/screen.  for trace 1, advance page if print- */
        /* er output;  screen output is free-running.  for trace 2, */
        /* pause on full screen;  for trace 3, pause after line.    */
        switch(tr)
          {
            case 1: if (opf==display)
                      then lft=sl;
                      else endpage();
                    break;
            case 2: if (mr)
                      then {putchar('\n'); lft=sl; pause();}
                      else endpage();
                    break;
            case 3: lft=sl; break;
          }
      }
    if (tr==3) then pause();
  }

/*-----------------------------  PAUSE  ------------------------------*/
pause()
  { /* pause execution via 'mtr' call (if active) */
 /* if (mr) then mtr(tr,1); else */ getchar();
  }

/*------------------  DISPLAY ERROR MESSAGE & EXIT  ------------------*/
error(n,s)
  int n; char *s;
    {
      FILE *dest;
      static char
          *m[8]= { "Simulation Error at Time ",
                   "Empty Element Pool",
                   "Empty Name Space",
                   "Facility Defined After Queue/Schedule",
                   "Negative Event Time",
                   "Empty Event List",
                   "Preempted Token Not in Event List",
                   "Release of Idle/Unowned Facility" };
      dest=opf;
      while(1)
        { /* send messages to both printer and screen */
          fprintf(dest,"\n**** %s%.3f\n",m[0],clock);
          if (n) then fprintf(dest,"     %s\n",m[n]);
          if (s!=NULL) then fprintf(dest,"     %s\n",s);
          if (dest==display) then break; else dest=display;
        }
      if (opf!=display) then report();
   /* if (mr) then mtr(0,1); */
      exit(0);
    }

/*------------------------  GENERATE REPORT  -------------------------*/
report()
  {
    newpage();
    reportf();
    endpage();
  }

/*--------------------  GENERATE FACILITY REPORT  --------------------*/
reportf()
  {
    int f;
    if ((f=fchn)==0)
      then fprintf(opf,"\nno facilities defined:  report abandoned\n");
      else
        { /* f = 0 at end of facility chain */
          while(f) {f=rept_page(f); if (f>0) then endpage();}
        }
  }

/*----------------------  GENERATE REPORT PAGE  ----------------------*/
static rept_page(fnxt)
  int fnxt;
    {
      int f,i,n; char fn[19];
      static char *s[7]= {
        "smpl SIMULATION REPORT", " MODEL: ", "TIME: ", "INTERVAL: ",
        "MEAN BUSY     MEAN QUEUE        OPERATION COUNTS",
        " FACILITY          UTIL.    ",
        " PERIOD        LENGTH     RELEASE   PREEMPT   QUEUE" };
      fprintf(opf,"\n%51s\n\n\n",s[0]);
      fprintf(opf,"%-s%-54s%-s%11.3f\n",s[1],mname(),s[2],clock);
      fprintf(opf,"%68s%11.3f\n\n",s[3],clock-start);
      fprintf(opf,"%75s\n",s[4]);
      fprintf(opf,"%s%s\n",s[5],s[6]);
      f=fnxt; lft-=8;
      while(f && lft--)
        {
          n=0; for (i=f+2; i<=f+l1[f]+1; i++) n+=l3[i];
          if (l1[f]==1)
            then sprintf(fn,"%s",fname(f));
            else sprintf(fn,"%s[%d]",fname(f),l1[f]);
          fprintf(opf," %-17s%6.4f %10.3f %13.3f %11d %9d %7d\n",
            fn,U(f),B(f),Lq(f),n,(int)l4[f+1],(int)l4[f]);
          f=l2[f+1];
        }
      return(f);
    }

/*---------------------------  COUNT LINES  --------------------------*/
lns(i)
  int i;
    {
      lft-=i;  if (lft<=0) then endpage();
      return(lft);
    }

/*----------------------------  END PAGE  ----------------------------*/
endpage()
  {
    int c;
    if (opf==display)
      then
        { /* screen output: push to top of screen & pause */
          while(lft>0) {putc('\n',opf); lft--;}
          printf("\n[ENTER] to continue:");  getchar();
       /* if (mr) then clr_scr(); else */ printf("\n\n");
        }
      else if (lft<pl) then putc(FF,opf);
    newpage();
  }

/*----------------------------  NEW PAGE  ----------------------------*/
newpage()
  { /* set line count to top of page/screen after page change/screen  */
    /* clear by 'smpl', another SMPL module, or simulation program    */
    lft=(opf==display)? sl:pl;
  }

/*------------------------  REDIRECT OUTPUT  -------------------------*/
FILE *sendto(dest)
  FILE *dest;
    {
      if (dest!=NULL) then opf=dest;
      return(opf);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -