refactored main; monitoring & scheduling not done yet

This commit is contained in:
Semere M. Mebrahtom 2026-03-26 10:54:24 +01:00
parent 7748a53eb2
commit f08c635390
Signed by: semere
GPG key ID: 7FC937214DF30488
4 changed files with 93 additions and 77 deletions

View file

@ -6,8 +6,8 @@ INCLUDES = coders/codexion.h
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)
CC = cc CC = cc
CFLAGS = -Wall -Wextra -Werror -pthread # CFLAGS = -Wall -Wextra -Werror -pthread -g
# CFLAGS = -Wall -Wextra -Werror -pthread -g -fsanitize=thread CFLAGS = -Wall -Wextra -Werror -pthread -g -fsanitize=thread
all: $(NAME) all: $(NAME)
@ -27,7 +27,7 @@ $(NAME): $(OBJS)
# scheduler # scheduler
test: $(NAME) test: $(NAME)
./$(NAME) 2 800 200 100 10 5 0 edf ./$(NAME) 2 800 200 100 10 3 0 edf
test-val: $(NAME) test-val: $(NAME)
valgrind --leak-check=full --show-leak-kinds=all ./$(NAME) 2 800 200 100 10 5 0 edf valgrind --leak-check=full --show-leak-kinds=all ./$(NAME) 2 800 200 100 10 5 0 edf

View file

@ -13,6 +13,7 @@
#ifndef CODEXION_H #ifndef CODEXION_H
# define CODEXION_H # define CODEXION_H
# include <pthread.h> # include <pthread.h>
# include <stdbool.h>
# include <sys/time.h> # include <sys/time.h>
typedef struct s_state t_state; typedef struct s_state t_state;
@ -34,14 +35,14 @@ typedef struct s_args
typedef struct s_dongle typedef struct s_dongle
{ {
int index; int idx;
pthread_mutex_t lock; pthread_mutex_t lock;
long last_used; long last_used;
} t_dongle; } t_dongle;
typedef struct s_coder typedef struct s_coder
{ {
int coder_id; int idx;
pthread_t thread; pthread_t thread;
t_dongle *right_dongle; t_dongle *right_dongle;
t_dongle *left_dongle; t_dongle *left_dongle;
@ -56,7 +57,7 @@ typedef struct s_state
t_coder *coders; t_coder *coders;
t_dongle *dongles; t_dongle *dongles;
long start; long start;
int is_over; bool is_over;
pthread_mutex_t over_mutex; pthread_mutex_t over_mutex;
pthread_mutex_t print_mutex; pthread_mutex_t print_mutex;
pthread_t monitor; pthread_t monitor;

View file

@ -12,6 +12,7 @@
#include "codexion.h" #include "codexion.h"
#include <pthread.h> #include <pthread.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/time.h> #include <sys/time.h>
@ -25,10 +26,19 @@ long now(void)
return (current.tv_sec * 1000L + current.tv_usec / 1000); 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) void compile_op(t_coder *coder, t_state *state)
{ {
t_dongle *first, *second; t_dongle *first;
if (coder->right_dongle->index < coder->left_dongle->index) t_dongle *second;
if (coder->right_dongle->idx < coder->left_dongle->idx)
{ {
first = coder->left_dongle; first = coder->left_dongle;
second = coder->right_dongle; second = coder->right_dongle;
@ -38,26 +48,15 @@ void compile_op(t_coder *coder, t_state *state)
first = coder->right_dongle; first = coder->right_dongle;
second = coder->left_dongle; second = coder->left_dongle;
} }
// acquire first dongle
pthread_mutex_lock(&first->lock); pthread_mutex_lock(&first->lock);
first->last_used = now(); first->last_used = now();
pthread_mutex_lock(&state->print_mutex); print("%ld %d has taken a dongle\n", state, coder->idx);
printf("%ld %d has taken a dongle\n", now() - state->start,
coder->coder_id);
pthread_mutex_unlock(&state->print_mutex);
// acquire second dongle
pthread_mutex_lock(&second->lock); pthread_mutex_lock(&second->lock);
second->last_used = now(); second->last_used = now();
pthread_mutex_lock(&state->print_mutex); print("%ld %d has taken a dongle\n", state, coder->idx);
printf("%ld %d has taken a dongle\n", now() - state->start,
coder->coder_id);
pthread_mutex_unlock(&state->print_mutex);
coder->last_compile = now(); coder->last_compile = now();
pthread_mutex_lock(&state->print_mutex); print("%ld %d is compiling\n", state, coder->idx);
printf("%ld %d is compiling\n", now() - state->start, coder->coder_id);
pthread_mutex_unlock(&state->print_mutex);
usleep(state->args.time_to_compile * 1000L); usleep(state->args.time_to_compile * 1000L);
// release dongles
pthread_mutex_unlock(&first->lock); pthread_mutex_unlock(&first->lock);
pthread_mutex_unlock(&second->lock); pthread_mutex_unlock(&second->lock);
coder->compiles_done += 1; coder->compiles_done += 1;
@ -65,17 +64,13 @@ void compile_op(t_coder *coder, t_state *state)
void debug_op(t_coder *coder, t_state *state) void debug_op(t_coder *coder, t_state *state)
{ {
pthread_mutex_lock(&state->print_mutex); print("%ld %d is debugging\n", state, coder->idx);
printf("%ld %d is debugging\n", now() - state->start, coder->coder_id);
pthread_mutex_unlock(&state->print_mutex);
usleep(state->args.time_to_debug * 1000L); usleep(state->args.time_to_debug * 1000L);
} }
void refactor_op(t_coder *coder, t_state *state) void refactor_op(t_coder *coder, t_state *state)
{ {
pthread_mutex_lock(&state->print_mutex); print("%ld %d is refactoring\n", state, coder->idx);
printf("%ld %d is refactoring\n", now() - state->start, coder->coder_id);
pthread_mutex_unlock(&state->print_mutex);
usleep(state->args.time_to_refactor * 1000L); usleep(state->args.time_to_refactor * 1000L);
} }
@ -115,55 +110,79 @@ int cleanup(t_args *args, t_coder *coders, t_dongle *dongles)
return (0); return (0);
} }
int main(int argc, char **argv) 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; int i;
t_args *args;
t_coder *coders;
t_dongle *dongles; t_dongle *dongles;
t_state state;
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]); args = parse_arguments(argc - 1, &argv[1]);
if (!args) if (!args)
return (cleanup(args, NULL, NULL)); return (cleanup(args, NULL, NULL));
coders = malloc(sizeof(t_coder) * args->number_of_coders); state = init_state(args);
dongles = malloc(sizeof(t_dongle) * args->number_of_coders); state.dongles = init_dongles(args, &state);
if (!coders || !dongles) state.coders = init_coders(args, &state);
return (cleanup(args, coders, dongles)); if (!state.coders || !state.dongles)
state.start = now(); return (cleanup(args, state.coders, state.dongles));
state.args = *args; i = -1;
state.is_over = 0; while (++i < args->number_of_coders)
state.coders = coders; pthread_create(&state.coders[i].thread, NULL, run, &state.coders[i]);
state.dongles = dongles;
pthread_mutex_init(&state.print_mutex, NULL);
pthread_mutex_init(&state.over_mutex, NULL);
i = 0;
while (i < args->number_of_coders)
{
dongles[i].index = i;
pthread_mutex_init(&dongles[i].lock, NULL);
dongles[i].last_used = state.start - args->dongle_cooldown;
i++;
}
i = 0;
while (i < args->number_of_coders)
{
coders[i].coder_id = i + 1;
coders[i].compiles_done = 0;
coders[i].last_compile = state.start;
coders[i].left_dongle = &dongles[i];
coders[i].right_dongle = &dongles[(i + 1) % args->number_of_coders];
coders[i].state = &state;
pthread_create(&coders[i].thread, NULL, run, &coders[i]);
i++;
}
pthread_create(&state.monitor, NULL, monitor, &state); pthread_create(&state.monitor, NULL, monitor, &state);
i = 0; i = -1;
while (i < args->number_of_coders) while (++i < args->number_of_coders)
{ pthread_join(state.coders[i].thread, NULL);
pthread_join(coders[i].thread, NULL);
i++;
}
pthread_join(state.monitor, NULL); pthread_join(state.monitor, NULL);
cleanup(args, coders, dongles); cleanup(args, state.coders, state.dongles);
} }

View file

@ -38,18 +38,14 @@ t_args *parse_arguments(int count, char **args)
data = malloc(sizeof(t_args)); data = malloc(sizeof(t_args));
if (!data) if (!data)
return (NULL); return (NULL);
i = 0; i = -1;
while (i < 7) while (++i < 7)
{ {
if (!isnumeric(args[i])) if (!isnumeric(args[i]))
return (NULL); return (NULL);
args_int[i] = atoi(args[i]); args_int[i] = atoi(args[i]);
i++;
} }
if (!strcmp(args[7], "fifo")) data->scheduler = args[7];
data->scheduler = "fifo";
else if (!strcmp(args[7], "edf"))
data->scheduler = "edf";
data->number_of_coders = args_int[0]; data->number_of_coders = args_int[0];
data->time_to_burnout = args_int[1]; data->time_to_burnout = args_int[1];
data->time_to_compile = args_int[2]; data->time_to_compile = args_int[2];