Repository navigation
Expand file tree
/
Copy pathmm1.c
More file actions
executable file
·182 lines (162 loc) · 6.52 KB
/
Copy pathmm1.c
File metadata and controls
executable file
·182 lines (162 loc) · 6.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/* -------------------------------------------------------------------------
* This program is a next-event simulation of a multi-server, single-queue
* service node. There are two event types:
* arrival at the service node;
* departure from a server.
* The service node is assumed to be initially idle, no arrivals are
* are permitted after the terminal time 'stop' and the node is then purged
* by processing any remaining jobs.
*
* Name : mm1.c (M/M/1 queue)
* Author : Steve Park & Dave Geyer w/modifications by Rob Jones
* Language : ANSI C
* Created : 10-29-96
* Latest Revision : 10-30-01
* -------------------------------------------------------------------------
*/
#include <stdio.h>
#include <math.h>
#include "rngs.h"
#define STOP 10000000.0 /* terminal (close the door) time */
#define SERVERS 1 /* number of servers */
typedef struct { /* the next-event list */
double t; /* next event time */
int x; /* event status, 0 or 1 */
} events;
/* ============================ */
static double Exponential(double m)
/* ============================ */
{
return (-m * log(1.0 - Random()));
}
/* ================================== */
[[maybe_unused]] static double Uniform(double a, double b)
/* ================================== */
{
return (a + (b - a) * Random());
}
/* ============================ */
static double GetInterarrival(void)
/* ============================ */
{
SelectStream(0);
return (Exponential(1.0)); /* interarrival times have mean 1.0 */
}
/* ======================= */
static double GetService(void)
/* ======================= */
{
SelectStream(1);
return (Exponential(1.0/1.25)); /* interarrival times have mean 1/1.25 */
}
/* =============================== */
static int NextEvent(events event[])
/* =============================== */
{
int e;
int i = 0;
while (event[i].x == 0)
i++;
e = i; /* at this point e is the index of the */
while (i < SERVERS) { /* first 'active' element in the event list */
i++; /* - now check the others */
if ((event[i].x == 1) && (event[i].t < event[e].t))
e = i;
}
return (e); /* returns the index of the next event */
}
/* ============================= */
static int FindOne(events event[])
/* ============================= */
{
int s;
int i = 1;
while (event[i].x == 1)
i++;
s = i; /* at this point s is the index of */
while (i < SERVERS) { /* the first available (idle) server */
i++; /* - now check the others */
if ((event[i].x == 0) && (event[i].t < event[s].t))
s = i;
}
return (s); /* return the index of the available server idle longest */
}
/* ============== */
int main(void)
/* ============== */
{
struct {
double current; /* current time */
double next; /* next (most imminent) event time */
} t;
events event_list[SERVERS+1];
int e;
int s; /* server index */
long number = 0; /* number in the node */
long index = 0; /* used to count processed jobs */
double area = 0.0; /* time integrated number in the node */
double service;
struct { /* accumulated sums of */
double service; /* - service times */
long served; /* - # served */
} sum[SERVERS + 1];
PlantSeeds(123456789);
t.current = 0.0;
event_list[0].t = t.current + GetInterarrival();
event_list[0].x = 1;
for (s = 1; s <= SERVERS; s++) {
event_list[s].t = 0.0;
event_list[s].x = 0; /* all servers are initially idle */
sum[s].service = 0.0;
sum[s].served = 0;
}
while ((event_list[0].x != 0) || (number != 0)) {
e = NextEvent(event_list); /* next event index */
t.next = event_list[e].t; /* next event time */
area += (t.next - t.current) * number; /* update integral */
t.current = t.next; /* advance the clock*/
if (e == 0) { /* process an arrival*/
number++;
event_list[0].t = t.current + GetInterarrival();
if (event_list[0].t > STOP)
event_list[0].x = 0;
if (number <= SERVERS) {
s = FindOne(event_list);
service = GetService();
sum[s].service += service;
sum[s].served++;
event_list[s].t = t.current + service;
event_list[s].x = 1;
}
}
else { /* process a departure */
index++; /* from server s */
number--;
s = e;
if (number >= SERVERS) {
service = GetService();
sum[s].service += service;
sum[s].served++;
event_list[s].t = t.current + service;
}
else
event_list[s].x = 0;
}
}
printf("\nfor %ld jobs the node statistics are:\n\n", index);
printf(" avg interarrivals .. = %6.2f\n", event_list[0].t / index);
printf(" avg wait ........... = %6.2f\n", area / index);
printf(" avg # in node ...... = %6.2f\n", area / t.current);
for (s = 1; s <= SERVERS; s++) /* adjust area to calculate */
area -= sum[s].service; /* averages for the queue */
printf(" avg delay .......... = %6.2f\n", area / index);
printf(" avg # in queue ..... = %6.2f\n", area / t.current);
printf("\nthe server statistics are:\n\n");
printf(" server utilization avg service share\n");
for (s = 1; s <= SERVERS; s++)
printf("%8d %14.3f %15.2f %15.3f\n", s, sum[s].service / t.current,
sum[s].service / sum[s].served,
(double) sum[s].served / index);
printf("\n");
return (0);
}