codexion/coders/main.c

188 lines
4.7 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: semebrah <semebrah@student.42berlin.de> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/03/22 18:07:14 by semebrah #+# #+# */
/* Updated: 2026/03/22 18:07:31 by semebrah ### ########.fr */
/* */
/* ************************************************************************** */
#include "codexion.h"
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
long now(void)
{
struct timeval current;
gettimeofday(&current, NULL);
return (current.tv_sec * 1000L + current.tv_usec / 1000);
}
void print(char *str, t_state *state, int coder_idx)
{
pthread_mutex_lock(&state->print_mutex);
printf(str, now() - state->start, coder_idx + 1);
pthread_mutex_unlock(&state->print_mutex);
}
void compile_op(t_coder *coder, t_state *state)
{
t_dongle *first;
t_dongle *second;
if (coder->right_dongle->idx < coder->left_dongle->idx)
{
first = coder->left_dongle;
second = coder->right_dongle;
}
else
{
first = coder->right_dongle;
second = coder->left_dongle;
}
pthread_mutex_lock(&first->lock);
first->last_used = now();
print("%ld %d has taken a dongle\n", state, coder->idx);
pthread_mutex_lock(&second->lock);
second->last_used = now();
print("%ld %d has taken a dongle\n", state, coder->idx);
coder->last_compile = now();
print("%ld %d is compiling\n", state, coder->idx);
usleep(state->args.time_to_compile * 1000L);
pthread_mutex_unlock(&first->lock);
pthread_mutex_unlock(&second->lock);
coder->compiles_done += 1;
}
void debug_op(t_coder *coder, t_state *state)
{
print("%ld %d is debugging\n", state, coder->idx);
usleep(state->args.time_to_debug * 1000L);
}
void refactor_op(t_coder *coder, t_state *state)
{
print("%ld %d is refactoring\n", state, coder->idx);
usleep(state->args.time_to_refactor * 1000L);
}
void *run(void *param)
{
t_coder *coder;
t_state *state;
int i;
coder = param;
state = coder->state;
i = 0;
while (i < state->args.number_of_compiles_required)
{
compile_op(coder, state);
debug_op(coder, state);
refactor_op(coder, state);
i++;
}
return (NULL);
}
void *monitor(void *param)
{
(void)param;
return (NULL);
}
int cleanup(t_args *args, t_coder *coders, t_dongle *dongles)
{
if (args)
free(args);
if (coders)
free(coders);
if (dongles)
free(dongles);
return (0);
}
t_state init_state(t_args *args)
{
t_state state;
state.start = now();
state.args = *args;
state.is_over = false;
pthread_mutex_init(&state.print_mutex, NULL);
pthread_mutex_init(&state.over_mutex, NULL);
return (state);
}
t_dongle *init_dongles(t_args *args, t_state *state)
{
int i;
t_dongle *dongles;
dongles = malloc(sizeof(t_dongle) * args->number_of_coders);
if (!dongles)
return (NULL);
i = -1;
while (++i < args->number_of_coders)
{
dongles[i].idx = i;
pthread_mutex_init(&dongles[i].lock, NULL);
dongles[i].last_used = state->start - args->dongle_cooldown;
}
return (dongles);
}
t_coder *init_coders(t_args *args, t_state *state)
{
t_coder *coders;
int i;
coders = malloc(sizeof(t_coder) * args->number_of_coders);
if (!coders)
return (NULL);
i = -1;
while (++i < args->number_of_coders)
{
coders[i].idx = i;
coders[i].compiles_done = 0;
coders[i].last_compile = state->start;
coders[i].left_dongle = &state->dongles[i];
coders[i].right_dongle = &state->dongles[(i + 1)
% args->number_of_coders];
coders[i].state = state;
}
return (coders);
}
int main(int argc, char **argv)
{
int i;
t_args *args;
t_state state;
args = parse_arguments(argc - 1, &argv[1]);
if (!args)
return (cleanup(args, NULL, NULL));
state = init_state(args);
state.dongles = init_dongles(args, &state);
state.coders = init_coders(args, &state);
if (!state.coders || !state.dongles)
return (cleanup(args, state.coders, state.dongles));
i = -1;
while (++i < args->number_of_coders)
pthread_create(&state.coders[i].thread, NULL, run, &state.coders[i]);
pthread_create(&state.monitor, NULL, monitor, &state);
i = -1;
while (++i < args->number_of_coders)
pthread_join(state.coders[i].thread, NULL);
pthread_join(state.monitor, NULL);
cleanup(args, state.coders, state.dongles);
}