Download c source code

/*
 * 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;
  }
}