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

📄 simlib.c

📁 离散事件系统仿真程序CPU_scheduler说明: 1.仿真功能与要求: 1.1 单CPU系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* This is simlib.c (adapted from SUPERSIMLIB, written by Gregory Glockner). */

/* Include files. */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "simlibdefs.h"

/* Declare simlib global variables. */

int    *list_rank, *list_size, next_event_type, maxatr = 0, maxlist = 0;
float  *transfer, sim_time, prob_distrib[26];
struct master {
    float  *value;
    struct master *pr;
    struct master *sr;
} **head, **tail;

/* Declare simlib functions. */

void  init_simlib(void);
void  list_file(int option, int list);
void  list_remove(int option, int list);
void  timing(void);
void  event_schedule(float time_of_event, int type_of_event);
int   event_cancel(int event_type);
float sampst(float value, int variable);
float timest(float value, int variable);
float filest(int list);
void  out_sampst(FILE *unit, int lowvar, int highvar);
void  out_timest(FILE *unit, int lowvar, int highvar);
void  out_filest(FILE *unit, int lowlist, int highlist);
void  pprint_out(FILE *unit, int i);
float expon(float mean, int stream);
int   random_integer(float prob_distrib[], int stream);
float uniform(float a, float b, int stream);
float erlang(int m, float mean, int stream);
float lcgrand(int stream);
void  lcgrandst(long zset, int stream);
long  lcgrandgt(int stream);


void init_simlib()
{

/* Initialize simlib.c.  List LIST_EVENT is reserved for event list, ordered by
   event time.  init_simlib must be called from main by user. */

    int list, listsize;

    if (maxlist < 1) maxlist = MAX_LIST;
    listsize = maxlist + 1;

    /* Initialize system attributes. */

    sim_time = 0.0;
    if (maxatr < 4) maxatr = MAX_ATTR;

    /* Allocate space for the lists. */

    list_rank = (int *)            calloc(listsize,   sizeof(int));
    list_size = (int *)            calloc(listsize,   sizeof(int));
    head      = (struct master **) calloc(listsize,   sizeof(struct master *));
    tail      = (struct master **) calloc(listsize,   sizeof(struct master *));
    transfer  = (float *)          calloc(maxatr + 1, sizeof(float));

    /* Initialize list attributes. */

    for(list = 1; list <= maxlist; ++list) {
        head [list]     = NULL;
        tail [list]     = NULL;
        list_size[list] = 0;
        list_rank[list] = 0;
    }

    /* Set event list to be ordered by event time. */

    list_rank[LIST_EVENT] = EVENT_TIME;

    /* Initialize statistical routines. */

    sampst(0.0, 0);
    timest(0.0, 0);
}


void list_file(int option, int list)
{

/* Place transfr into list "list".
   Update timest statistics for the list.
   option = FIRST place at start of list
            LAST  place at end of list
            INCREASING  place in increasing order on attribute list_rank(list)
            DECREASING  place in decreasing order on attribute list_rank(list)
            (ties resolved by FIFO) */

    struct master *row, *ahead, *behind, *ihead, *itail;
    int    item, postest;

////////////////////////////////////////////////////////////////////////////////
/* This section is added by Bowlderforest at 2nd.March,2004.  The aim is 
   to keep the new transfer[] as same as the old one when it is created 
   by the calloc() function.                                                  */

	float* t_transfer;
	int i;
////////////////////////////////////////////////////////////////////////////////

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

    if(!((list >= 0) && (list <= MAX_LIST))) {
        printf("\nInvalid list %d for list_file at time %f\n", list, sim_time);
        exit(1);
    }

    /* Increment the list size. */

    list_size[list]++;

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

    if(!((option >= 1) && (option <= DECREASING))) {
        printf(
            "\n%d is an invalid option for list_file on list %d at time %f\n",
            option, list, sim_time);
        exit(1);
    }

    /* If this is the first record in this list, just make space for it. */

    if(list_size[list] == 1) {

        row        = (struct master *) malloc(sizeof(struct master));
        head[list] = row ;
        tail[list] = row ;
        (*row).pr  = NULL;
        (*row).sr  = NULL;
    }

    else { /* There are other records in the list. */

        /* Check the value of option. */

        if ((option == INCREASING) || (option == DECREASING)) {
            item = list_rank[list];
            if(!((item >= 1) && (item <= maxatr))) {
                printf(
                    "%d is an improper value for rank of list %d at time %f\n",
                    item, list, sim_time) ;
                exit(1);
            }

            row    = head[list];
            behind = NULL; /* Dummy value for the first iteration. */

            /* Search for the correct location. */

            if (option == INCREASING) {
                postest = (transfer[item] >= (*row).value[item]);
                while (postest) {
                    behind  = row;
                    row     = (*row).sr;
                    postest = (behind != tail[list]);
                    if (postest)
                        postest = (transfer[item] >= (*row).value[item]);
                }
            }

            else {

                postest = (transfer[item] <= (*row).value[item]);
                while (postest) {
                    behind  = row;
                    row     = (*row).sr;
                    postest = (behind != tail[list]);
                    if (postest)
                        postest = (transfer[item] <= (*row).value[item]);
                }
            }

            /* Check to see if position is first or last.  If so, take care of
               it below. */

            if (row == head[list])

                option = FIRST;

            else

                if (behind == tail[list])

                    option = LAST;

                else { /* Insert between preceding and succeeding records. */

                    ahead        = (*behind).sr;
                    row          = (struct master *)
                                        malloc(sizeof(struct master));
                    (*row).pr    = behind;
                    (*behind).sr = row;
                    (*ahead).pr  = row;
                    (*row).sr    = ahead;
                }
        } /* End if inserting in increasing or decreasing order. */

        if (option == FIRST) {
            row         = (struct master *) malloc(sizeof(struct master));
            ihead       = head[list];
            (*ihead).pr = row;
            (*row).sr   = ihead;
            (*row).pr   = NULL;
            head[list]  = row;
        }
        if (option == LAST) {
            row         = (struct master *) malloc(sizeof(struct master));
            itail       = tail[list];
            (*row).pr   = itail;
            (*itail).sr = row;
            (*row).sr   = NULL;
            tail[list]  = row;
        }
    }

    /* Copy the data. */

    (*row).value = transfer;

    /* Make room for new transfer. */

    transfer = (float *) calloc(maxatr + 1, sizeof(float));

////////////////////////////////////////////////////////////////////////////////
/* This section is added by Bowlderforest at 2nd.March,2004.  The aim is 
   to keep the new transfer[] as same as the old one when it is created
   by the calloc() function.                                                  */

	t_transfer = (*row).value;
	for(i = 1; i <= maxatr; i++) transfer[i] = t_transfer[i];

////////////////////////////////////////////////////////////////////////////////

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

    timest((float)list_size[list], TIM_VAR + list);
}


void list_remove(int option, int list)
{

/* Remove a record from list "list" and copy attributes into transfer.
   Update timest statistics for the list.
   option = FIRST remove first record in the list
            LAST  remove last record in the list */

    struct master *row, *ihead, *itail;

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

    if(!((list >= 0) && (list <= MAX_LIST))) {
        printf("\nInvalid list %d for list_remove at time %f\n",
               list, sim_time);
        exit(1);
    }

    /* If the list is empty, stop the simulation. */

    if(list_size[list] <= 0) {
        printf("\nUnderflow of list %d at time %f\n", list, sim_time);
        exit(1);
    }

    /* Decrement the list size. */

    list_size[list]--;

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

    if(!(option == FIRST || option == LAST)) {
        printf(
            "\n%d is an invalid option for list_remove on list %d at time %f\n",
            option, list, sim_time);
        exit(1);
    }

    if(list_size[list] == 0) {

        /* There is only 1 record, so remove it. */

        row        = head[list];
        head[list] = NULL;
        tail[list] = NULL;
    }

    else {

        /* There is more than 1 record, so remove according to the desired
           option. */

        switch(option) {

            /* Remove the first record in the list. */

            case FIRST:
                row         = head[list];
                ihead       = (*row).sr;
                (*ihead).pr = NULL;
                head[list]  = ihead;
                break;

            /* Remove the last record in the list. */

            case LAST:
                row         = tail[list];
                itail       = (*row).pr;
                (*itail).sr = NULL;
                tail[list]  = itail;
                break;
        }
    }

    /* Copy the data and free memory. */

    free((char *)transfer);
    transfer = (*row).value;
    free((char *)row);

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

    timest((float)list_size[list], TIM_VAR + list);
}


void timing()
{

/* Remove next event from event list, placing its attributes in transfer.
   Set sim_time (simulation time) to event time, transfer[1].
   Set next_event_type to this event type, transfer[2]. */

    /* Remove the first event from the event list and put it in transfer[]. */

    list_remove(FIRST, LIST_EVENT);

    /* Check for a time reversal. */

    if(transfer[EVENT_TIME] < sim_time) {
        printf(
            "\nAttempt to schedule event type %f for time %f at time %f\n",
            transfer[EVENT_TYPE], transfer[EVENT_TIME], sim_time);
        exit(1);
    }

    /* Advance the simulation clock and set the next event type. */

    sim_time        = transfer[EVENT_TIME];
    next_event_type = transfer[EVENT_TYPE];
}


void event_schedule(float time_of_event, int type_of_event)
{

/* Schedule an event at time event_time of type event_type.  If attributes
   beyond the first two (reserved for the event time and the event type) are
   being used in the event list, it is the user's responsibility to place their
   values into the transfer array before invoking event_schedule. */

    transfer[EVENT_TIME] = time_of_event;
    transfer[EVENT_TYPE] = type_of_event;
    list_file(INCREASING, LIST_EVENT);
}


int event_cancel(int event_type)
{

/* Remove the first event of type event_type from the event list, leaving its
   attributes in transfer.  If something is cancelled, event_cancel returns 1;
   if no match is found, event_cancel returns 0. */

    struct       master *row, *ahead, *behind;
    static float high, low, value;

    /* If the event list is empty, do nothing and return 0. */

    if(list_size[LIST_EVENT] == 0) return 0;

    /* Search the event list. */

    row   = head[LIST_EVENT];
    low   = event_type - EPSILON;
    high  = event_type + EPSILON;
    value = (*row).value[EVENT_TYPE] ;

    while (((value <= low) || (value >= high)) && (row != tail[LIST_EVENT])) {
        row   = (*row).sr;
        value = (*row).value[EVENT_TYPE];
    }

    /* Check to see if this is the end of the event list. */

⌨️ 快捷键说明

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