?? smpl.cpp
字號:
/*
%%%%%%%%%%%%%%%%%%%% SMPL.c %%%%%%%%%%%%%%%%%%%%%%%
*/
#include "smpl.h"
#include "rand.h"
#include <process.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
//#include <windows.h>
#define nl 256 /* element pool length */
#define ns 256 /* namespace length */
#define pl 58 /* printer page length (lines used */
#define sl 23 /* screen page length by 'smpl') */
#define FF 12 /* form feed */
static FILE
*display=stdout, /* screen display file */
*opf=stdout; /* current output destination */
static int
event, /* current simulation event */
token, /* last token dispatched */
blk, /* next available block index */
avl, /* available element list header */
evl, /* event list header */
fchn, /* facility descriptor chain header */
avn, /* next available namespace position */
tr, /* event trace flag */
mtr, /* monitor activation flag */
lft=sl; /* lines left on current page/screen */
static real
clock, /* current simulation time */
start, /* simulation interval start time */
tl; /* last trace message issue time */
static int
L1[nl],
L2[nl], /* facility descriptor, */
L3[nl]; /* queue, & */
static real /* event list */
L4[nl], /* element pool */
L5[nl];
static char
smpl_name[ns]; /* model and facility name space */
/*--------------------*/
int dump( void );
void dump_hdr(int );
void fdump(int );
void qdump(int );
void q_hdr( void );
void edump( void );
/*--------------------*/
/*--------------- INITIALIZE SIMULATION SUBSYSTEM ------------------*/
void smpl( int m, char *s )
{
int i; static int rns=1;
blk=1; avl=-1; avn=0; /* element pool & namespace headers */
evl=fchn=0; /* event list & descriptor chain headers */
clock=start=tl=0.0; /* sim., interval start, last trace times */
event=tr=0; /* current event no. & trace flags */
for (i=0; i<nl; i++) {L1[i]=L2[i]=L3[i]=0; L4[i]=L5[i]=0.0;}
i=save_name(s,50); /* model name -> namespace */
rns=stream(rns); rns=++rns>15? 1:rns; /* set random no. stream */
mtr=(m>0)? 1:0; /* set monitor flag */
/* if (mtr) then {opf=display; init_mtr(1);} */
}
/*----------------------- RESET MEASUREMENTS -----------------------*/
void reset()
{
resetf(); start=clock;
}
/*--------------------------- SAVE NAME ----------------------------*/
int save_name( char *s, int m )
{
int i,n;
n=strlen(s); if (n>m) then n=m;
if (avn+n>ns) then error(2,NULL); /* namespace exhausted */
i=avn; avn+=n+1; strncpy(&smpl_name[i],s,n);
if (n==m) then smpl_name[avn++]='\0';
return(i);
}
/*------------------------- GET MODEL NAME -------------------------*/
char *mname(void)
{
return(smpl_name);
}
/*------------------------ GET FACILITY NAME -----------------------*/
char *fname( int f ) {
return(&smpl_name[L3[f+1]]);
}
/*--------------------------- GET BLOCK ----------------------------*/
static get_blk( int n ) {
int i;
if (blk==0) then error(3,NULL); /* block request after schedule */
i=blk; blk+=n;
if (blk>=nl) then error(1,NULL); /* element pool exhausted */
return(i);
}
/*-------------------------- GET ELEMENT ---------------------------*/
static get_elm ( void )
{
int i;
if (avl<=0) then
{
if (avl==0) then error(1,NULL); /* empty element list */
/* if (mtr && !tr) then init_mtr(2); */
/* build the free element list from the block of elements */
/* remaining after all facilities have been defined */
for (i=blk; i<(nl-1); i++) L1[i]=i+1;
avl=blk; blk=0;
}
i=avl; avl=L1[i];
return(i);
}
/*------------------------- RETURN ELEMENT -------------------------*/
void put_elm(int i )
{
L1[i]=avl; avl=i;
}
/*------------------------- SCHEDULE EVENT -------------------------*/
void schedule( int ev, real te, int tkn)
{
int i;
if (te<0.0) then error(4,NULL); /* negative event time */
i=get_elm(); L2[i]=tkn; L3[i]=ev; L4[i]=0.0; L5[i]=clock+te;
enlist(&evl,i);
if (tr) then msg(1,tkn,"",ev,0);
}
/*--------------------------- CAUSE EVENT --------------------------*/
void cause(int *ev, int *tkn)
{
int i;
if (evl==0) then error(5,NULL); /* empty event list */
i=evl; *tkn=token=L2[i]; *ev=event=L3[i]; clock=L5[i];
evl=L1[i]; put_elm(i); /* delink element & return to pool */
if (tr) then msg(2,*tkn,"",event,0);
/* if (mtr && (tr!=3)) then mtr(tr,0); */
}
/*-------------------------- RETURN TIME ---------------------------*/
real time()
{
return(clock);
}
/*-------------------------- CANCEL EVENT --------------------------*/
cancel( int ev)
{
int pred,succ=evl,tkn;
while((succ!=0) && (L3[succ]!=ev)) {pred=succ; succ=L1[pred];}
if (succ==0) then return(-1);
tkn=L2[succ]; if (tr) then msg(3,tkn,"",L3[succ],0);
if (succ==evl)
then evl=L1[succ]; /* unlink event */
else L1[pred]=L1[succ]; /* list entry & */
put_elm(succ); /* deallocate it */
return(tkn);
}
/*------------------------- SUSPEND EVENT --------------------------*/
static suspend( int tkn )
{
int pred,succ=evl;
while((succ!=0) && (L2[succ]!=tkn)) {pred=succ; succ=L1[pred];}
if (succ==0) then error(6,NULL); /* no event scheduled for tkn */
if (succ==evl)
then evl=L1[succ]; /* unlink event */
else L1[pred]=L1[succ]; /* list entry */
if (tr) then msg(6,-1,"",L3[succ],0);
return(succ);
}
/*-------------- ENTER ELEMENT IN QUEUE OR EVENT LIST --------------*/
void enlist( int *head, int elm)
{ /* 'head' points to head of queue/event list */
int pred,succ; real arg,v;
arg=L5[elm]; succ=*head;
while(1)
{ /* scan for position to insert entry: event list is order- */
/* ed in ascending 'arg' values, queues in descending order */
if (succ==0)
then break; /* end of list */
else
{
v=L5[succ];
if (*head==evl)
then
{ /* event list */
if (v>arg) then break;
}
else
{ /* queue: if entry is for a preempted token- */
/* (L4, the remaining event time, >0), insert */
/* entry at beginning of its priority class; */
/* otherwise, insert it at the end */
if ((v<arg) || ((v==arg) && (L4[elm]>0.0)))
then break;
}
}
pred=succ; succ=L1[pred];
}
L1[elm]=succ; if (succ!=*head) then L1[pred]=elm; else *head=elm;
}
/*------------------------- DEFINE FACILITY ------------------------*/
facility ( char *s, int n )
{
int f,i;
f=get_blk(n+2); L1[f]=n; L3[f+1]=save_name(s,(n>1 ? 14:17));
if (fchn==0)
then fchn=f;
else {i=fchn; while(L2[i+1]) i=L2[i+1]; L2[i+1]=f;}
L2[f+1]=0;
if (tr) then msg(13,-1,fname(f),f,0);
return(f);
}
/*--------------------- RETURN FACILITY SEQUENCE ----------------------*/
int getfacility ( int f ) {
if ( f == 0 ) return ( fchn );
return ( L2 [ f + 1 ] );
}
/*--------------------- RETURN CURRENTE TOKEN ----------------------*/
int gettoken ( void ) {
return ( token );
}
/*--------------------- RETURN CURRENTE EVENT ----------------------*/
int getevent ( void ) {
return ( event );
}
/*--------------------- RETURN CURRENTE EVT ----------------------*/
int getevl ( void ) {
return ( evl );
}
/*--------------------- RETURN FACILITY DESCRIPTOR ----------------------*/
int getfdes ( int f ) {
return ( L1 [ f ] );
}
/*--------------------- RETURN POOL DESCRIPTOR ----------------------*/
int getpdes ( int f ) {
return ( L4 [ f ] );
}
/*--------------------- RETURN START TIME ---------------------------*/
real getstart ( void ) {
return ( start );
}
/*--------------- RESET FACILITY & QUEUE MEASUREMENTS --------------*/
void resetf(void)
{
int i=fchn,j;
while(i)
{
L4[i]=L4[i+1]=L5[i+1]=0.0;
for (j=i+2; j<=(i+L1[i]+1); j++) {L3[j]=0; L4[j]=0.0;}
i=L2[i+1]; /* advance to next facility */
}
}
/*------------------------ REQUEST FACILITY ------------------------*/
request ( int f, int tkn, int pri )
{
int i,r;
if (L2[f]<L1[f])
then
{ /* facility nonbusy - reserve 1st-found nonbusy server */
for (i=f+2; L1[i]!=0; i++);
L1[i]=tkn; L2[i]=pri; L5[i]=clock; L2[f]++; r=0;
}
else
{ /* facility busy - enqueue token marked w/event, priority */
enqueue(f,tkn,pri,event,0.0); r=1;
}
if (tr) then msg(7,tkn,fname(f),r,L3[f]);
return(r);
}
/*------------------------- ENQUEUE TOKEN --------------------------*/
void enqueue( int f, int j, int pri, int ev, real te)
{
int i;
L5[f+1]+=L3[f]*(clock-L5[f]); L3[f]++; L5[f]=clock;
i=get_elm(); L2[i]=j; L3[i]=ev; L4[i]=te; L5[i]=(real)pri;
enlist(&L1[f+1],i);
}
/*------------------------ PREEMPT FACILITY ------------------------*/
int preempt( int f, int tkn, int pri )
{
int ev,i,j,k,r; real te;
if (L2[f]<L1[f])
then
{ /* facility nonbusy - locate 1st-found nonbusy server */
for (k=f+2; L1[k]!=0; k++); r=0;
if (tr) then msg(8,tkn,fname(f),0,0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -