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

📄 simlib.c

📁 离散事件系统仿真程序CPU_scheduler说明: 1.仿真功能与要求: 1.1 单CPU系统
💻 C
📖 第 1 页 / 共 2 页
字号:

    if (row == tail[LIST_EVENT]) {

        /* Double check to see that this is a match. */

        if ((value > low) && (value < high)) {
            list_remove(LAST, LIST_EVENT);
            return 1;
        }

        else /* no match */
            return 0;
    }

    /* Check to see if this is the head of the list.  If it is at the head, then
       it MUST be a match. */

    if (row == head[LIST_EVENT]) {
        list_remove(FIRST, LIST_EVENT);
        return 1;
    }

    /* Else remove this event somewhere in the middle of the event list. */

    /* Update pointers. */

    ahead        = (*row).sr;
    behind       = (*row).pr;
    (*behind).sr = ahead;
    (*ahead).pr  = behind;

    /* Decrement the size of the event list. */

    list_size[LIST_EVENT]--;

    /* Copy and free memory. */

    free((char *)transfer);       /* Free the old transfer. */
    transfer = (*row).value;      /* Transfer the data. */
    free((char *)row);            /* Free the space vacated by row. */

    /* Update the area under the number-in-event-list curve. */

    timest((float)list_size[LIST_EVENT], TIM_VAR + LIST_EVENT);
    return 1;
}


float sampst(float value, int variable)
{

/* Initialize, update, or report statistics on discrete-time processes:
   sum/average, max (default -1E30), min (default 1E30), number of observations
   for sampst variable "variable", where "variable":
       = 0 initializes accumulators
       > 0 updates sum, count, min, and max accumulators with new observation
       < 0 reports stats on variable "variable" and returns them in transfer:
           [1] = average of observations
           [2] = number of observations
           [3] = maximum of observations
           [4] = minimum of observations */

    static int   ivar, num_observations[SVAR_SIZE];
    static float max[SVAR_SIZE], min[SVAR_SIZE], sum[SVAR_SIZE];

    /* If the variable value is improper, stop the simulation. */

    if(!(variable >= -MAX_SVAR) && (variable <= MAX_SVAR)) {
        printf("\n%d is an improper value for a sampst variable at time %f\n",
            variable, sim_time);
        exit(1);
    }

    /* Execute the desired option. */

    if(variable > 0) { /* Update. */
        sum[variable] += value;
        if(value > max[variable]) max[variable] = value;
        if(value < min[variable]) min[variable] = value;
        num_observations[variable]++;
        return 0.0;
    }

    if(variable < 0) { /* Report summary statistics in transfer. */
        ivar        = -variable;
        transfer[2] = (float) num_observations[ivar];
        transfer[3] = max[ivar];
        transfer[4] = min[ivar];
        if(num_observations[ivar] == 0)
            transfer[1] = 0.0;
        else
            transfer[1] = sum[ivar] / transfer[2];
        return transfer[1];
    }

    /* Initialize the accumulators. */

    for(ivar=1; ivar <= MAX_SVAR; ++ivar) {
        sum[ivar]              = 0.0;
        max[ivar]              = -INFINITY;
        min[ivar]              =  INFINITY;
        num_observations[ivar] = 0;
    }
}


float timest(float value, int variable)
{

/* Initialize, update, or report statistics on continuous-time processes:
   integral/average, max (default -1E30), min (default 1E30)
   for timest variable "variable", where "variable":
       = 0 initializes counters
       > 0 updates area, min, and max accumulators with new level of variable
       < 0 reports stats on variable "variable" and returns them in transfer:
           [1] = time-average of variable updated to the time of this call
           [2] = maximum value variable has attained
           [3] = minimum value variable has attained
   Note that variables TIM_VAR + 1 through TVAR_SIZE are used for automatic
   record keeping on the length of lists 1 through MAX_LIST. */

    int          ivar;
    static float area[TVAR_SIZE], max[TVAR_SIZE], min[TVAR_SIZE],
                 preval[TVAR_SIZE], tlvc[TVAR_SIZE], treset;

    /* If the variable value is improper, stop the simulation. */

    if(!(variable >= -MAX_TVAR) && (variable <= MAX_TVAR)) {
        printf("\n%d is an improper value for a timest variable at time %f\n",
            variable, sim_time);
        exit(1);
    }

    /* Execute the desired option. */

    if(variable > 0) { /* Update. */
        area[variable] += (sim_time - tlvc[variable]) * preval[variable];
        if(value > max[variable]) max[variable] = value;
        if(value < min[variable]) min[variable] = value;

        preval[variable] = value;
        tlvc[variable]   = sim_time;
        return 0.0;
    }

    if(variable < 0) { /* Report summary statistics in transfer. */
        ivar         = -variable;
        area[ivar]   += (sim_time - tlvc[ivar]) * preval[ivar];
        tlvc[ivar]   = sim_time;
        transfer[1]  = area[ivar] / (sim_time - treset);
        transfer[2]  = max[ivar];
        transfer[3]  = min[ivar];
        return transfer[1];
    }

    /* Initialize the accumulators. */

    for(ivar = 1; ivar <= MAX_TVAR; ++ivar) {
        area[ivar]   = 0.0;
        max[ivar]    = -INFINITY;
        min[ivar]    =  INFINITY;
        preval[ivar] = 0.0;
        tlvc[ivar]   = sim_time;
    }
    treset = sim_time;
}


float filest(int list)
{

/* Report statistics on the length of list "list" in transfer:
       [1] = time-average of list length updated to the time of this call
       [2] = maximum length list has attained
       [3] = minimum length list has attained
   This uses timest variable TIM_VAR + list. */

    return timest(0.0, -(TIM_VAR + list));
}


void out_sampst(FILE *unit, int lowvar, int highvar)
{

/* Write sampst statistics for variables lowvar through highvar on file
   "unit". */

    int ivar, iatrr;

    if(lowvar>highvar || lowvar > MAX_SVAR || highvar > MAX_SVAR) return;

    fprintf(unit, "\n sampst                         Number");
    fprintf(unit, "\nvariable                          of");
    fprintf(unit, "\n number       Average           values          Maximum");
    fprintf(unit, "          Minimum");
    fprintf(unit, "\n___________________________________");
    fprintf(unit, "_____________________________________");
    for(ivar = lowvar; ivar <= highvar; ++ivar) {
        fprintf(unit, "\n\n%5d", ivar);
        sampst(0.00, -ivar);
        for(iatrr = 1; iatrr <= 4; ++iatrr) pprint_out(unit, iatrr);
    }
    fprintf(unit, "\n___________________________________");
    fprintf(unit, "_____________________________________\n\n\n");
}


void out_timest(FILE *unit, int lowvar, int highvar)
{

/* Write timest statistics for variables lowvar through highvar on file
   "unit". */

    int ivar, iatrr;

    if(lowvar > highvar || lowvar > TIM_VAR || highvar > TIM_VAR ) return;


    fprintf(unit, "\n  timest");
    fprintf(unit, "\n variable       Time");
    fprintf(unit, "\n  number       average          Maximum          Minimum");
    fprintf(unit, "\n________________________________________________________");
    for(ivar = lowvar; ivar <= highvar; ++ivar) {
        fprintf(unit, "\n\n%5d", ivar);
        timest(0.00, -ivar);
        for(iatrr = 1; iatrr <= 3; ++iatrr) pprint_out(unit, iatrr);
    }
    fprintf(unit, "\n________________________________________________________");
    fprintf(unit, "\n\n\n");
}


void out_filest(FILE *unit, int lowlist, int highlist)
{

/* Write timest list-length statistics for lists lowlist through highlist on
   file "unit". */

    int list, iatrr;

    if(lowlist > highlist || lowlist > MAX_LIST || highlist > MAX_LIST) return;

    fprintf(unit, "\n  File         Time");
    fprintf(unit, "\n number       average          Maximum          Minimum");
    fprintf(unit, "\n_______________________________________________________");
    for(list = lowlist; list <= highlist; ++list) {
        fprintf(unit, "\n\n%5d", list);
        filest(list);
        for(iatrr = 1; iatrr <= 3; ++iatrr) pprint_out(unit, iatrr);
    }
    fprintf(unit, "\n_______________________________________________________");
    fprintf(unit, "\n\n\n");
}


void pprint_out(FILE *unit, int i) /* Write ith entry in transfer to file
                                      "unit". */
{
    if(transfer[i] == -1e30 || transfer[i] == 1e30)
        fprintf(unit," %#15.6G ", 0.00);
    else
        fprintf(unit," %#15.6G ", transfer[i]);
}


float expon(float mean, int stream) /* Exponential variate generation
                                       function. */
{
    return -mean * log(lcgrand(stream));

}


int random_integer(float prob_distrib[], int stream) /* Discrete-variate
                                                        generation function. */
{
    int   i;
    float u;

    u = lcgrand(stream);

    for (i = 1; u >= prob_distrib[i]; ++i)
        ;
    return i;
}


float uniform(float a, float b, int stream) /* Uniform variate generation
                                               function. */
{
    return a + lcgrand(stream) * (b - a);
}


float erlang(int m, float mean, int stream)  /* Erlang variate generation
                                                function. */
{
    int   i;
    float mean_exponential, sum;

    mean_exponential = mean / m;
    sum = 0.0;
    for (i = 1; i <= m; ++i)
        sum += expon(mean_exponential, stream);
    return sum;
}


/* Prime modulus multiplicative linear congruential generator

   Z[i] = (630360016 * Z[i-1]) (mod(pow(2,31) - 1)), based on Marse and
   Roberts' portable FORTRAN random-number generator UNIRAN.  Multiple
   (100) streams are supported, with seeds spaced 100,000 apart.
   Throughout, input argument "stream" must be an int giving the
   desired stream number.  The header file lcgrand.h must be included in
   the calling program (#include "lcgrand.h") before using these
   functions.

   Usage: (Three functions)

   1. To obtain the next U(0,1) random number from stream "stream,"
      execute
          u = lcgrand(stream);
      where lcgrand is a float function.  The float variable u will
      contain the next random number.

   2. To set the seed for stream "stream" to a desired value zset,
      execute
          lcgrandst(zset, stream);
      where lcgrandst is a void function and zset must be a long set to
      the desired seed, a number between 1 and 2147483646 (inclusive). 
      Default seeds for all 100 streams are given in the code.

   3. To get the current (most recently used) integer in the sequence
      being generated for stream "stream" into the long variable zget,
      execute
          zget = lcgrandgt(stream);
      where lcgrandgt is a long function. */

/* Define the constants. */

#define MODLUS 2147483647
#define MULT1       24112
#define MULT2       26143

/* Set the default seeds for all 100 streams. */

static long zrng[] =
{         1,
 1973272912, 281629770,  20006270,1280689831,2096730329,1933576050,
  913566091, 246780520,1363774876, 604901985,1511192140,1259851944,
  824064364, 150493284, 242708531,  75253171,1964472944,1202299975,
  233217322,1911216000, 726370533, 403498145, 993232223,1103205531,
  762430696,1922803170,1385516923,  76271663, 413682397, 726466604,
  336157058,1432650381,1120463904, 595778810, 877722890,1046574445,
   68911991,2088367019, 748545416, 622401386,2122378830, 640690903,
 1774806513,2132545692,2079249579,  78130110, 852776735,1187867272,
 1351423507,1645973084,1997049139, 922510944,2045512870, 898585771,
  243649545,1004818771, 773686062, 403188473, 372279877,1901633463,
  498067494,2087759558, 493157915, 597104727,1530940798,1814496276,
  536444882,1663153658, 855503735,  67784357,1432404475, 619691088,
  119025595, 880802310, 176192644,1116780070, 277854671,1366580350,
 1142483975,2026948561,1053920743, 786262391,1792203830,1494667770,
 1923011392,1433700034,1244184613,1147297105, 539712780,1545929719,
  190641742,1645390429, 264907697, 620389253,1502074852, 927711160,
  364849192,2049576050, 638580085, 547070247 };

/* Generate the next random number. */

float lcgrand(int stream)
{
    long zi, lowprd, hi31;

    zi     = zrng[stream];
    lowprd = (zi & 65535) * MULT1;
    hi31   = (zi >> 16) * MULT1 + (lowprd >> 16);
    zi     = ((lowprd & 65535) - MODLUS) +
             ((hi31 & 32767) << 16) + (hi31 >> 15);
    if (zi < 0) zi += MODLUS;
    lowprd = (zi & 65535) * MULT2;
    hi31   = (zi >> 16) * MULT2 + (lowprd >> 16);
    zi     = ((lowprd & 65535) - MODLUS) +
             ((hi31 & 32767) << 16) + (hi31 >> 15);
    if (zi < 0) zi += MODLUS;
    zrng[stream] = zi;
    return (zi >> 7 | 1) / 16777216.0;
}


void lcgrandst (long zset, int stream) /* Set the current zrng for stream
                                          "stream" to zset. */
{
    zrng[stream] = zset;
}


long lcgrandgt (int stream) /* Return the current zrng for stream "stream". */
{
    return zrng[stream];
}

⌨️ 快捷键说明

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