restructured the program; doesn't handle deadlocks yet
This commit is contained in:
parent
ebe57f783d
commit
13019ac0bc
4 changed files with 145 additions and 59 deletions
10
Makefile
10
Makefile
|
|
@ -7,6 +7,7 @@ OBJS = $(SRCS:.c=.o)
|
|||
|
||||
CC = cc
|
||||
CFLAGS = -Wall -Wextra -Werror -pthread
|
||||
# CFLAGS = -Wall -Wextra -Werror -pthread -g -fsanitize=thread
|
||||
|
||||
all: $(NAME)
|
||||
|
||||
|
|
@ -24,8 +25,15 @@ $(NAME): $(OBJS)
|
|||
# number_of_compiles_required
|
||||
# dongle_cooldown
|
||||
# scheduler
|
||||
|
||||
test: $(NAME)
|
||||
./$(NAME) 10 2000 500 200 300 5 50 1
|
||||
./$(NAME) 2 800 200 100 10 5 0 edf
|
||||
|
||||
test-val: $(NAME)
|
||||
valgrind --leak-check=full --show-leak-kinds=all ./$(NAME) 2 800 200 100 10 5 0 edf
|
||||
|
||||
test-hel: $(NAME)
|
||||
valgrind --tool=helgrind ./$(NAME) 2 800 200 100 10 5 0 edf
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS)
|
||||
|
|
|
|||
|
|
@ -24,17 +24,37 @@ typedef struct s_args
|
|||
int time_to_refactor;
|
||||
int number_of_compiles_required;
|
||||
int dongle_cooldown;
|
||||
int scheduler;
|
||||
char *scheduler;
|
||||
} t_args;
|
||||
|
||||
typedef struct s_data
|
||||
typedef struct s_dongle
|
||||
{
|
||||
pthread_mutex_t lock;
|
||||
long last_used;
|
||||
} t_dongle;
|
||||
|
||||
typedef struct s_coder
|
||||
{
|
||||
struct timeval start;
|
||||
int coder_id;
|
||||
pthread_t thread;
|
||||
t_dongle *right_dongle;
|
||||
t_dongle *left_dongle;
|
||||
long last_compile;
|
||||
int compiles_done;
|
||||
void *state;
|
||||
} t_coder;
|
||||
|
||||
typedef struct s_state
|
||||
{
|
||||
t_args args;
|
||||
pthread_mutex_t *left_dongle;
|
||||
pthread_mutex_t *right_dongle;
|
||||
} t_data;
|
||||
t_coder *coders;
|
||||
t_dongle *dongles;
|
||||
long start;
|
||||
int is_over;
|
||||
pthread_mutex_t over_mutex;
|
||||
pthread_mutex_t print_mutex;
|
||||
pthread_t monitor;
|
||||
} t_state;
|
||||
|
||||
t_args *parse_arguments(int count, char **args);
|
||||
|
||||
|
|
|
|||
147
coders/main.c
147
coders/main.c
|
|
@ -17,87 +17,140 @@
|
|||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void compile_op(t_data *data)
|
||||
long now(void)
|
||||
{
|
||||
struct timeval now;
|
||||
int diff;
|
||||
struct timeval current;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
diff = (now.tv_sec - data->start.tv_sec) * 1000L + (now.tv_usec
|
||||
- data->start.tv_usec) / 1000;
|
||||
printf("%d %d is compiling\n", diff, data->coder_id);
|
||||
usleep(data->args.time_to_compile * 1000L);
|
||||
gettimeofday(¤t, NULL);
|
||||
return (current.tv_sec * 1000L + current.tv_usec / 1000);
|
||||
}
|
||||
|
||||
void debug_op(t_data *data)
|
||||
void compile_op(t_coder *coder, t_state *state)
|
||||
{
|
||||
struct timeval now;
|
||||
int diff;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
diff = (now.tv_sec - data->start.tv_sec) * 1000L + (now.tv_usec
|
||||
- data->start.tv_usec) / 1000;
|
||||
printf("%d %d is debugging\n", diff, data->coder_id);
|
||||
usleep(data->args.time_to_debug * 1000L);
|
||||
// acquire right dongle
|
||||
pthread_mutex_lock(&coder->left_dongle->lock);
|
||||
coder->left_dongle->last_used = now();
|
||||
pthread_mutex_lock(&state->print_mutex);
|
||||
printf("%ld %d has taken a dongle\n", now() - state->start,
|
||||
coder->coder_id);
|
||||
pthread_mutex_unlock(&state->print_mutex);
|
||||
// acquire right dongle
|
||||
pthread_mutex_lock(&coder->right_dongle->lock);
|
||||
coder->right_dongle->last_used = now();
|
||||
pthread_mutex_lock(&state->print_mutex);
|
||||
printf("%ld %d has taken a dongle\n", now() - state->start,
|
||||
coder->coder_id);
|
||||
pthread_mutex_unlock(&state->print_mutex);
|
||||
coder->last_compile = now();
|
||||
pthread_mutex_lock(&state->print_mutex);
|
||||
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);
|
||||
pthread_mutex_unlock(&coder->left_dongle->lock);
|
||||
pthread_mutex_unlock(&coder->right_dongle->lock);
|
||||
coder->compiles_done += 1;
|
||||
}
|
||||
|
||||
void refactor_op(t_data *data)
|
||||
void debug_op(t_coder *coder, t_state *state)
|
||||
{
|
||||
struct timeval now;
|
||||
int diff;
|
||||
pthread_mutex_lock(&state->print_mutex);
|
||||
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);
|
||||
}
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
diff = (now.tv_sec - data->start.tv_sec) * 1000L + (now.tv_usec
|
||||
- data->start.tv_usec) / 1000;
|
||||
printf("%d %d is refactoring\n", diff, data->coder_id);
|
||||
usleep(data->args.time_to_refactor * 1000L);
|
||||
void refactor_op(t_coder *coder, t_state *state)
|
||||
{
|
||||
pthread_mutex_lock(&state->print_mutex);
|
||||
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);
|
||||
}
|
||||
|
||||
void *run(void *param)
|
||||
{
|
||||
t_coder *coder;
|
||||
t_state *state;
|
||||
int i;
|
||||
t_data *data;
|
||||
|
||||
data = param;
|
||||
coder = param;
|
||||
state = (t_state *)(coder->state);
|
||||
i = 0;
|
||||
while (i < 5)
|
||||
while (i < state->args.number_of_compiles_required)
|
||||
{
|
||||
compile_op(data);
|
||||
debug_op(data);
|
||||
refactor_op(data);
|
||||
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);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
t_args *args;
|
||||
pthread_t *coders;
|
||||
pthread_mutex_t *dongles;
|
||||
int i;
|
||||
struct timeval start;
|
||||
t_data *data;
|
||||
int i;
|
||||
t_args *args;
|
||||
t_coder *coders;
|
||||
t_dongle *dongles;
|
||||
t_state state;
|
||||
|
||||
args = parse_arguments(argc - 1, &argv[1]);
|
||||
coders = malloc(sizeof(pthread_t) * args->number_of_coders);
|
||||
dongles = malloc(sizeof(pthread_mutex_t) * args->number_of_coders);
|
||||
data = malloc(sizeof(t_data) * args->number_of_coders);
|
||||
if (!args)
|
||||
return (cleanup(args, NULL, NULL));
|
||||
coders = malloc(sizeof(t_coder) * args->number_of_coders);
|
||||
dongles = malloc(sizeof(t_dongle) * args->number_of_coders);
|
||||
if (!coders || !dongles)
|
||||
return (cleanup(args, coders, dongles));
|
||||
state.start = now();
|
||||
state.args = *args;
|
||||
state.is_over = 0;
|
||||
state.coders = coders;
|
||||
state.dongles = dongles;
|
||||
pthread_mutex_init(&state.print_mutex, NULL);
|
||||
pthread_mutex_init(&state.over_mutex, NULL);
|
||||
i = 0;
|
||||
gettimeofday(&start, NULL);
|
||||
while (i < args->number_of_coders)
|
||||
{
|
||||
data[i].args = *args;
|
||||
data[i].coder_id = i + 1;
|
||||
data[i].start = start;
|
||||
pthread_create(&coders[i], NULL, run, (void *)&data[i]);
|
||||
pthread_mutex_init(&dongles[i], NULL);
|
||||
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)
|
||||
{
|
||||
pthread_join(coders[i], NULL);
|
||||
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);
|
||||
i = 0;
|
||||
while (i < args->number_of_coders)
|
||||
{
|
||||
pthread_join(coders[i].thread, NULL);
|
||||
i++;
|
||||
}
|
||||
pthread_join(state.monitor, NULL);
|
||||
cleanup(args, coders, dongles);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "codexion.h"
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -28,22 +29,27 @@ int isnumeric(char *str)
|
|||
|
||||
t_args *parse_arguments(int count, char **args)
|
||||
{
|
||||
int args_int[8];
|
||||
int args_int[7];
|
||||
t_args *data;
|
||||
int i;
|
||||
|
||||
if (count != 8)
|
||||
if (count != 8 || !(!strcmp(args[7], "fifo") || (!strcmp(args[7], "edf"))))
|
||||
return (NULL);
|
||||
data = malloc(sizeof(t_args));
|
||||
if (!data)
|
||||
return (NULL);
|
||||
i = -1;
|
||||
while (++i < 8)
|
||||
i = 0;
|
||||
while (i < 7)
|
||||
{
|
||||
if (!isnumeric(args[i]))
|
||||
return (NULL);
|
||||
args_int[i] = atoi(args[i]);
|
||||
i++;
|
||||
}
|
||||
if (!strcmp(args[7], "fifo"))
|
||||
data->scheduler = "fifo";
|
||||
else if (!strcmp(args[7], "edf"))
|
||||
data->scheduler = "edf";
|
||||
data->number_of_coders = args_int[0];
|
||||
data->time_to_burnout = args_int[1];
|
||||
data->time_to_compile = args_int[2];
|
||||
|
|
@ -51,6 +57,5 @@ t_args *parse_arguments(int count, char **args)
|
|||
data->time_to_refactor = args_int[4];
|
||||
data->number_of_compiles_required = args_int[5];
|
||||
data->dongle_cooldown = args_int[6];
|
||||
data->scheduler = args_int[7];
|
||||
return (data);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue