refactored main; monitoring & scheduling not done yet
This commit is contained in:
parent
7748a53eb2
commit
f08c635390
4 changed files with 93 additions and 77 deletions
6
Makefile
6
Makefile
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
147
coders/main.c
147
coders/main.c
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue