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

📄 cpu_schedule.c

📁 离散事件系统仿真程序CPU_scheduler说明: 1.仿真功能与要求: 1.1 单CPU系统
💻 C
字号:
 //          Single CPU with ten terminals schedule queueing system using simlib. 
//          Function: 
//          Editor  :  曹玉林 
//          Date    :  2004-2 


/* External definitions */

#include "simlib.h"                  /* Required for use of simlib.c. */

#define EVENT_ARRIVAL             1  /* Event type for arrival at terminals. */
#define EVENT_DEPARTURE           2  /* Event type for departure from CPU. */

#define ARRIVAL_TIME              1   /* Attribute number for arrival time of each assignment.*/
#define TERMINAL_NUMBER           3   /* Attribute number that denotes which terminal the assignment came in.*/
#define SERVICE_TIME              4   /* Attribute number for service time of each assignment.*/
#define LEFT_TIME                 5   /* Attribute number for the left time that each assignment need the CPU service.*/

#define LIST_QUEUE_INNER          1   /* List number for queue out of the CPU. */
#define LIST_QUEUE_OUTER          2   /* List number for queue out of the terminals. */
#define LIST_CPU                  3   /* List number for CPU. Here is single system, 
                                         so  that the number is zero means CPU is free,
									     otherwise is busy. */
#define SAMPST_SERVICE            1   /* sampst variable for service time.*/
#define SAMPST_ARRIVAL            2   /* sampst variable for interarrival time.*/


#define STREAM_SERVICE            11  /* Random-number stream for service times. */
#define STREAM_INTERARRIVAL1      1   /* Random-number stream for interarrivals of terminal 1. */
#define STREAM_INTERARRIVAL2      2   /* Random-number stream for interarrivals of terminal 2. */
#define STREAM_INTERARRIVAL3      3   /* Random-number stream for interarrivals of terminal 3. */
#define STREAM_INTERARRIVAL4      4   /* Random-number stream for interarrivals of terminal 4. */
#define STREAM_INTERARRIVAL5      5   /* Random-number stream for interarrivals of terminal 5. */
#define STREAM_INTERARRIVAL6      6   /* Random-number stream for interarrivals of terminal 6. */
#define STREAM_INTERARRIVAL7      7   /* Random-number stream for interarrivals of terminal 7. */
#define STREAM_INTERARRIVAL8      8   /* Random-number stream for interarrivals of terminal 8. */
#define STREAM_INTERARRIVAL9      9   /* Random-number stream for interarrivals of terminal 9. */
#define STREAM_INTERARRIVAL10     10  /* Random-number stream for interarrivals of terminal 10. */


/* Declare non-simlib global variables. */

int   num_assign_over, num_assign_required, cpu_access_num;
float mean_interarrival, mean_service, cpu_time_segment, shifting_time;

int terminal_state[11];     /* o: free; >1: busy.*/

FILE  *infile, *outfile;

/* Declare non-simlib functions. */

void init_model(void);
void arrive(void);
void depart(void);
void report(void);
void serve(void);

//**************************************************************************
//**************************主程序******************************************
//**************************************************************************

main()  /* Main function. */
{
    //**************************************************************************
	/* Open input and output files. */

    infile  = fopen("cpu_schedule_in.txt",  "r");
    outfile = fopen("cpu_schedule_out.txt", "w");

    /* Read input parameters. */

    fscanf(infile, "%f %f %f %f %d", &mean_interarrival, &mean_service,
           &cpu_time_segment, &shifting_time, &num_assign_required);

    /* Write report heading and input parameters. */

    fprintf(outfile, "Single-server CPU with ten terminals queueing system using simlib\n\n\n");
    fprintf(outfile, "Mean interarrival time of tasks: \t %11.3f minutes\n\n", mean_interarrival);
	fprintf(outfile, "Mean service time for tasks:     \t %11.3f minutes\n\n", mean_service);
	fprintf(outfile, "The segment time of CPU:\t\t %11.5f minutes\n\n", cpu_time_segment);
	fprintf(outfile, "The shifting time of CPU access:\t %11.5f minutes\n\n", shifting_time);
    fprintf(outfile, "Number of tasks required: \t\t %10d\n\n\n", num_assign_required);

    //****************************************************************************
    /* Initialize simlib */

	maxatr = 5;
    init_simlib();

    /* Initialize the model. */

    init_model();

    //******************************************************************************
	/* Run the simulation while more delays are still needed. */

    while (num_assign_over < num_assign_required) 
	{

        /* Determine the next event. */

        timing();

        /* Invoke the appropriate event function. */

        switch (next_event_type) 
		{
            case EVENT_ARRIVAL:
////////////////////////////////////////////////////////////////////////////////////////
//				printf("EVENT_ARRIVAL:  \t%10.5f\t%5d\t%10.8f\n",transfer[EVENT_TIME],
//					  (int)transfer[TERMINAL_NUMBER],transfer[SERVICE_TIME]);
////////////////////////////////////////////////////////////////////////////////////////
                arrive();
                break;
            case EVENT_DEPARTURE:
////////////////////////////////////////////////////////////////////////////////////////
//				printf("EVENT_DEPARTURE:\t%10.5f\t%5d\t%10.8f\n",transfer[EVENT_TIME],
//					  (int)transfer[TERMINAL_NUMBER],transfer[LEFT_TIME]);
////////////////////////////////////////////////////////////////////////////////////////
                depart();
                break;
        }
    }

    //******************************************************************************
    /* Invoke the report generator and end the simulation. */

    report();

    fclose(infile);
    fclose(outfile);

    return 0;
}

//*******************************************************************************
//***************************子函数定义******************************************
//*******************************************************************************

void init_model(void)  /* Initialization function. */
{
    int i;
	float t_schedule_time;
	num_assign_over = 0;
	cpu_access_num = 0;
	/* initialize each terminal.*/
    for(i = 1; i < 11; i++)
	{
		terminal_state[i] = 0;
		transfer[TERMINAL_NUMBER] = (float)i;
		transfer[SERVICE_TIME] = expon(mean_service, STREAM_SERVICE);
		transfer[LEFT_TIME] = transfer[SERVICE_TIME];
	    t_schedule_time = sim_time + expon(mean_interarrival, i);
/////////////////////////////////////////////////////////////////////////////////////
//	printf("Schedule_ARRIVAL:\t%10.5f\t%5d\t%10.8f\n",t_schedule_time,
//					 i,transfer[SERVICE_TIME]);
/////////////////////////////////////////////////////////////////////////////////////
		sampst(t_schedule_time - sim_time,SAMPST_ARRIVAL);
        event_schedule(t_schedule_time, EVENT_ARRIVAL);
	}
	/* initialize the orders of the LIST_QUEUE_INNER and LIST_QUEUE_OUTER . */

    list_rank[LIST_QUEUE_INNER] =  LEFT_TIME;
	list_rank[LIST_QUEUE_OUTER] =  ARRIVAL_TIME;

}

//*****************************************************************************
void arrive(void)  /* Arrival event function. */
{
	float t_schedule_time;
	/* Keep tranfer[].*/
	
	int t_event_type = (int)transfer[EVENT_TYPE];
    int t_terminal_number = (int)transfer[TERMINAL_NUMBER];
	float t_service_time = transfer[SERVICE_TIME];
	float t_left_time = transfer[LEFT_TIME];

    /* Schedule next arrival at this terminal. */

	transfer[SERVICE_TIME] = expon(mean_service,STREAM_SERVICE);
	transfer[LEFT_TIME] = transfer[SERVICE_TIME];
	                  /* the terminal number is the same as the old one.*/
	t_schedule_time = sim_time + expon(mean_interarrival, t_terminal_number);
/////////////////////////////////////////////////////////////////////////////////////
//	printf("Schedule_ARRIVAL:\t%10.5f\t%5d\t%10.8f\n",t_schedule_time,
//					  t_terminal_number,transfer[SERVICE_TIME]);
/////////////////////////////////////////////////////////////////////////////////////
	sampst(t_schedule_time - sim_time,SAMPST_ARRIVAL);
    event_schedule(t_schedule_time, EVENT_ARRIVAL);

	/* Check to see whether corresponding terminal is busy*/

	if(terminal_state[t_terminal_number])
	{
		/* Terminal is busy, so store the assignment at the end
           of list LIST_QUEUE_OUTER. */
		
		terminal_state[t_terminal_number]++;
		list_file(LAST, LIST_QUEUE_OUTER);
		return;
	}
	else
	{
        /* Terminal is idle, so enter the LIST_QUEUE_INNER 
		   in an INCREASING order.*/

		list_file(INCREASING, LIST_QUEUE_INNER);

		/*Set the flag of the terminal to busy.*/

        terminal_state[t_terminal_number] = 1;
	}
	    
	/* Check to see whether CPU is busy (i.e., list LIST_CPU contains a
       record). if CPU is idie, so start the service directly. */
    if (!list_size[LIST_CPU])        serve();
}

//****************************************************************************
void depart(void)  /* Departure event function. */
{
    int i = 0;
	int t_terminal_number = (int)transfer[TERMINAL_NUMBER];

	/* Check to see whether the task is over. */
	if(transfer[LEFT_TIME])
	{
		/* Task is not over, so enter back to the LIST_QUEUE_INNER. */
		
		list_file(INCREASING, LIST_QUEUE_INNER);

		/* CPU goes on with its service for the less LEFT_TIME task and then return. */
		serve();
		return;
	}
	else
	{
		/* Task is over. */
		num_assign_over++;
		terminal_state[t_terminal_number]--;
	    /*	printf("%10.5f",transfer[SERVICE_TIME]);  */
        sampst(transfer[SERVICE_TIME], SAMPST_SERVICE);
	}
	
    /* One task has been over, therefore check to see whether there is another task 
	   out of the very terminal requiring to enter the INNER queue . */
	if(terminal_state[t_terminal_number])
	{
		/* Yes,there is another task waiting for entrance into the INNER queue.*/
		/* Fetch the task belonging to this terminal, then place it into the INNER queue
		   in INCREASING order of the LEFT_TIME. */

		list_rank[LIST_QUEUE_OUTER] = TERMINAL_NUMBER;
		list_remove(FIRST, LIST_QUEUE_OUTER);
		list_rank[LIST_QUEUE_OUTER] = ARRIVAL_TIME;

		list_file(INCREASING, LIST_QUEUE_INNER);
		serve();
		return;
	}
	
	/* There is no task waiting for entrance into the INNER queue.*/
	/* Check whether there is any task in the INNER queue. */

	if(list_size[LIST_QUEUE_INNER])
	{
		/* Yes, there is task in the INNER queue, so directly start the CPU service. */
        serve();
		return;
	}

	/* There is no task in the INNER queue, so  set the CPU state to free. */

	list_remove(FIRST, LIST_CPU);

	/* The following section is not necessary. It's just for checking the correctness of my program.*/
	/* If any of the terminal_state[i] for i=1...10 are not 0, there are some mistakes. */

	for(i = 1; i < 11; i++)
	{
        if(terminal_state[i]) {printf("Error Found!"); exit(1);}
	}
}

//*******************************************************************************

void serve(void)
{
	float t_left_time;

    /* Fetch a task from the INNER queue, then place it into CPU for execution.*/
	list_remove(FIRST, LIST_QUEUE_INNER);
	
	/* Check to see whether the CPU is free.*/
	if(!list_size[LIST_CPU]) 
	{
		/* If the CPU is free, then list a record into the LIST_CPU to set the CPU busy*/
		transfer[EVENT_TIME] = transfer[EVENT_TIME] + shifting_time;
		list_file(FIRST, LIST_CPU);
	}

	cpu_access_num++;

	/* Schedule the depart event.*/

    t_left_time = transfer[LEFT_TIME];

	if(t_left_time > cpu_time_segment)
	{
		transfer[LEFT_TIME] = t_left_time - cpu_time_segment;
/////////////////////////////////////////////////////////////////////////////////////
//	printf("Schedule_DEPARURE:\t%10.5f\t%5d\t%10.8f\n",sim_time + cpu_time_segment + shifting_time,
//					  (int)transfer[TERMINAL_NUMBER],transfer[LEFT_TIME]);
/////////////////////////////////////////////////////////////////////////////////////
		event_schedule(sim_time + cpu_time_segment + shifting_time, EVENT_DEPARTURE);
	}
	else
	{
        transfer[LEFT_TIME] = 0.0;
/////////////////////////////////////////////////////////////////////////////////////
//	printf("Schedule_DEPARURE:\t%10.5f\t%5d\t%10.8f\n",sim_time + t_left_time + shifting_time,
//					 (int)transfer[TERMINAL_NUMBER],transfer[LEFT_TIME]);
/////////////////////////////////////////////////////////////////////////////////////
        event_schedule(sim_time + t_left_time + shifting_time, EVENT_DEPARTURE);
	}
}

//******************************************************************************
void report(void)  /* Report generator function. */
{
    /* Get and write out estimates of desired measures of performance. */

    fprintf(outfile, "\nTask service time(1), in minutes:\n");
    out_sampst(outfile, SAMPST_SERVICE, SAMPST_SERVICE);
    fprintf(outfile, "\nQueue length out of CPU(1) and Queue length out of terminals (2):\n");
    out_filest(outfile, LIST_QUEUE_INNER, LIST_QUEUE_OUTER);
    fprintf(outfile, "\nTime simulation ended:%12.3f minutes\n", sim_time);
}
//*****************************************************************************

⌨️ 快捷键说明

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