/*
* Copyright 2021 Jeisson Hidalgo-Cespedes - Universidad de Costa Rica
*/
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "simulation.h"
#include "static_simulation.h"
#include "dynamic_simulation.h"
/** @todo: documenting */
int simulation_analyze_arguments(simulation_t* simulation
, int argc, char* argv[]);
int simulation_read_data(simulation_t* simulation, FILE* input);
int simulation_start(simulation_t* simulation);
int simulation_run_serial(simulation_t* simulation);
void simulation_init(simulation_t* simulation) {
assert(simulation);
simulation->thread_count = sysconf(_SC_NPROCESSORS_ONLN);
array_init(&simulation->work);
simulation->total_duration = 0;
}
void simulation_destroy(simulation_t* simulation) {
assert(simulation);
array_destroy(&simulation->work);
}
int simulation_run(simulation_t* simulation, int argc, char* argv[]) {
assert(simulation);
int error = simulation_analyze_arguments(simulation, argc, argv);
if (error == EXIT_SUCCESS) {
error = simulation_read_data(simulation, stdin);
if (error == EXIT_SUCCESS) {
error = simulation_start(simulation);
}
}
return error;
}
int simulation_analyze_arguments(simulation_t* simulation
, int argc, char* argv[]) {
if (argc >= 2) {
simulation->thread_count = strtoull(argv[1], NULL, 10);
}
return EXIT_SUCCESS;
}
int simulation_read_data(simulation_t* simulation, FILE* input) {
assert(simulation);
int error = 0;
data_t duration = 0;
while (fscanf(input, "%u", &duration) == 1) {
error = array_append(&simulation->work, duration);
if (error) {
fprintf(stderr, "error: no enough memory\n");
break;
}
}
return error;
}
#if 0
useconds_t duration = 0;
while (std::cin >> duration) {
this->work.push_back(duration);
}
#endif
int simulation_start(simulation_t* simulation) {
assert(simulation);
int error = simulation_run_serial(simulation);
if (error == 0) {
static_simulation_t block_simulation;
static_simulation_init(&block_simulation, MAPPING_BLOCK, simulation);
static_simulation_run(&block_simulation);
static_simulation_destroy(&block_simulation);
static_simulation_t cyclic_simulation;
static_simulation_init(&cyclic_simulation, MAPPING_CYCLIC, simulation);
static_simulation_run(&cyclic_simulation);
static_simulation_destroy(&cyclic_simulation);
}
dynamic_simulation_t dynamic_simulation;
dynamic_simulation_init(&dynamic_simulation, simulation);
dynamic_simulation_run(&dynamic_simulation);
dynamic_simulation_destroy(&dynamic_simulation);
return error;
}
int simulation_run_serial(simulation_t* simulation) {
assert(simulation);
simulation->total_duration = 0;
for (size_t index = 0; index < simulation->work.count; ++index) {
simulation->total_duration += simulation->work.elements[index];
}
if (simulation->total_duration > 0) {
printf("%7u", simulation->total_duration);
for (size_t thread_num = 0; thread_num < simulation->thread_count;
++thread_num) {
printf(" %4zu", thread_num);
}
printf(" Duration Speedup Efficiency Elapsed(s)\n");
return EXIT_SUCCESS;
} else {
fprintf(stderr, "error: total duration must be positive\n");
return EXIT_FAILURE;
}
}