📄 cpu_schedule.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 + -