#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define DEF_NUM_ALLOCATED 1000;
#define SIM_DURATION 1000
#define SLOT_SIZE 1.0
#define G_MAX 6.0
#define G_STEP 0.1
#define RAND_UNIFORM (double) random() / (double) RAND_MAX
int
s_evt_n_elements = 0;
int
s_evt_n_allocated = 0;
struct
slot_event *s_evt_list = NULL;
int
p_evt_n_elements = 0;
int
p_evt_n_allocated = 0;
struct
packet_event *p_evt_list = NULL;
double
p_error = 0.0;
int
p_error_flag = 0;
struct
slot_event
{
double
time
;
int
num_packets;
};
struct
packet_event
{
double
time
;
};
int
slot_event_add(
struct
slot_event);
int
packet_event_add(
struct
packet_event);
void
run_simulation(
double
);
double
calc_exp_random_var(
double
);
double
get_max_packet_evt_time();
void
init_slot_event_list();
void
check_for_collisions();
int
calc_successful_tx();
void
clear_all();
int
validate_args(
int
,
char
**);
void
print_usage();
int
main(
int
argc,
char
**argv)
{
int
n;
double
g, s;
if
(validate_args(argc, argv) == 0)
{
print_usage();
return
1;
}
if
(argc == 2)
{
p_error_flag = 1;
p_error =
atof
(argv[1]);
}
for
(g = 0.1; g <= G_MAX; g += G_STEP)
{
clear_all();
run_simulation(g);
init_slot_event_list();
check_for_collisions();
n = calc_successful_tx();
s = (
double
) n / (
double
) s_evt_n_elements;
printf
(
"%lf,%lf\n"
, g, s);
}
free
(s_evt_list);
free
(p_evt_list);
return
(EXIT_SUCCESS);
}
int
slot_event_add(
struct
slot_event evt)
{
if
(s_evt_n_elements == s_evt_n_allocated)
{
if
(s_evt_n_allocated == 0)
{
s_evt_n_allocated = DEF_NUM_ALLOCATED;
}
else
{
s_evt_n_allocated *= 2;
}
void
*tmp =
realloc
(s_evt_list, (s_evt_n_allocated *
sizeof
(
struct
slot_event)));
if
(!tmp)
{
fprintf
(stderr,
"ERROR: Couldn't realloc memory\n"
);
return
(-1);
}
s_evt_list = (
struct
slot_event*) tmp;
}
s_evt_list[s_evt_n_elements] = evt;
s_evt_n_elements++;
return
s_evt_n_elements;
}
int
packet_event_add(
struct
packet_event evt)
{
if
(p_evt_n_elements == p_evt_n_allocated)
{
if
(p_evt_n_allocated == 0)
{
p_evt_n_allocated = DEF_NUM_ALLOCATED;
}
else
{
p_evt_n_allocated *= 2;
}
void
*tmp =
realloc
(p_evt_list, (p_evt_n_allocated *
sizeof
(
struct
packet_event)));
if
(!tmp)
{
fprintf
(stderr,
"ERROR: Couldn't realloc memory\n"
);
return
(-1);
}
p_evt_list = (
struct
packet_event*) tmp;
}
p_evt_list[p_evt_n_elements] = evt;
p_evt_n_elements++;
return
p_evt_n_elements;
}
void
run_simulation(
double
lambda)
{
int
i;
struct
packet_event p_evt;
double
evt_time = 0.0;
for
(i = 0; i < SIM_DURATION; i++)
{
if
(p_evt_n_elements > 0)
{
evt_time = p_evt_list[p_evt_n_elements-1].
time
;
}
p_evt.
time
= evt_time + calc_exp_random_var(lambda);
packet_event_add(p_evt);
}
}
double
calc_exp_random_var(
double
lambda)
{
return
(-
log
(RAND_UNIFORM) / lambda);
}
double
get_max_packet_evt_time()
{
int
i;
double
max_evt_time = p_evt_list[0].
time
;
for
(i = 1; i < p_evt_n_elements; i++)
{
if
(p_evt_list[i].
time
> max_evt_time)
{
max_evt_time = p_evt_list[i].
time
;
}
}
return
max_evt_time;
}
void
init_slot_event_list()
{
double
slot_time;
struct
slot_event s_evt;
double
max_evt_time = get_max_packet_evt_time();
for
(slot_time = SLOT_SIZE; slot_time <= max_evt_time + SLOT_SIZE;
slot_time += SLOT_SIZE)
{
s_evt.
time
= slot_time;
s_evt.num_packets = 0;
slot_event_add(s_evt);
}
}
void
check_for_collisions()
{
int
i, j;
for
(i = 0; i < s_evt_n_elements; i++)
{
for
(j = 0; j < p_evt_n_elements; j++)
{
if
(p_evt_list[j].
time
<= s_evt_list[i].
time
&&
p_evt_list[j].
time
> (s_evt_list[i].
time
- SLOT_SIZE))
{
s_evt_list[i].num_packets += 1;
}
}
}
}
int
calc_successful_tx()
{
int
n = 0;
int
i;
for
(i = 0; i < s_evt_n_elements; i++)
{
if
(s_evt_list[i].num_packets == 1)
{
if
(p_error_flag == 1)
{
if
(RAND_UNIFORM > p_error)
{
++n;
}
}
else
{
++n;
}
}
}
return
n;
}
void
clear_all()
{
s_evt_list = NULL;
p_evt_list = NULL;
s_evt_n_elements = 0;
p_evt_n_elements = 0;
s_evt_n_allocated = 0;
p_evt_n_allocated = 0;
}
int
validate_args(
int
argc,
char
**argv)
{
if
(argc > 2)
{
return
0;
}
return
1;
}
void
print_usage()
{
fprintf
(stderr,
"Usage: slottedaloha [Perror]\n"
);
}