deadlock broken by taking the lower index dongle first; no monitor and scheduling yet
This commit is contained in:
parent
13019ac0bc
commit
7748a53eb2
2 changed files with 58 additions and 39 deletions
|
|
@ -15,47 +15,53 @@
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
|
|
||||||
|
typedef struct s_state t_state;
|
||||||
|
typedef struct s_args t_args;
|
||||||
|
typedef struct s_dongle t_dongle;
|
||||||
|
typedef struct s_coder t_coder;
|
||||||
|
|
||||||
typedef struct s_args
|
typedef struct s_args
|
||||||
{
|
{
|
||||||
int number_of_coders;
|
int number_of_coders;
|
||||||
int time_to_burnout;
|
int time_to_burnout;
|
||||||
int time_to_compile;
|
int time_to_compile;
|
||||||
int time_to_debug;
|
int time_to_debug;
|
||||||
int time_to_refactor;
|
int time_to_refactor;
|
||||||
int number_of_compiles_required;
|
int number_of_compiles_required;
|
||||||
int dongle_cooldown;
|
int dongle_cooldown;
|
||||||
char *scheduler;
|
char *scheduler;
|
||||||
} t_args;
|
} t_args;
|
||||||
|
|
||||||
typedef struct s_dongle
|
typedef struct s_dongle
|
||||||
{
|
{
|
||||||
pthread_mutex_t lock;
|
int index;
|
||||||
long last_used;
|
pthread_mutex_t lock;
|
||||||
} t_dongle;
|
long last_used;
|
||||||
|
} t_dongle;
|
||||||
|
|
||||||
typedef struct s_coder
|
typedef struct s_coder
|
||||||
{
|
{
|
||||||
int coder_id;
|
int coder_id;
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
t_dongle *right_dongle;
|
t_dongle *right_dongle;
|
||||||
t_dongle *left_dongle;
|
t_dongle *left_dongle;
|
||||||
long last_compile;
|
long last_compile;
|
||||||
int compiles_done;
|
int compiles_done;
|
||||||
void *state;
|
t_state *state;
|
||||||
} t_coder;
|
} t_coder;
|
||||||
|
|
||||||
typedef struct s_state
|
typedef struct s_state
|
||||||
{
|
{
|
||||||
t_args args;
|
t_args args;
|
||||||
t_coder *coders;
|
t_coder *coders;
|
||||||
t_dongle *dongles;
|
t_dongle *dongles;
|
||||||
long start;
|
long start;
|
||||||
int is_over;
|
int 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;
|
||||||
} t_state;
|
} t_state;
|
||||||
|
|
||||||
t_args *parse_arguments(int count, char **args);
|
t_args *parse_arguments(int count, char **args);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -27,16 +27,27 @@ long now(void)
|
||||||
|
|
||||||
void compile_op(t_coder *coder, t_state *state)
|
void compile_op(t_coder *coder, t_state *state)
|
||||||
{
|
{
|
||||||
// acquire right dongle
|
t_dongle *first, *second;
|
||||||
pthread_mutex_lock(&coder->left_dongle->lock);
|
if (coder->right_dongle->index < coder->left_dongle->index)
|
||||||
coder->left_dongle->last_used = now();
|
{
|
||||||
|
first = coder->left_dongle;
|
||||||
|
second = coder->right_dongle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
first = coder->right_dongle;
|
||||||
|
second = coder->left_dongle;
|
||||||
|
}
|
||||||
|
// acquire first dongle
|
||||||
|
pthread_mutex_lock(&first->lock);
|
||||||
|
first->last_used = now();
|
||||||
pthread_mutex_lock(&state->print_mutex);
|
pthread_mutex_lock(&state->print_mutex);
|
||||||
printf("%ld %d has taken a dongle\n", now() - state->start,
|
printf("%ld %d has taken a dongle\n", now() - state->start,
|
||||||
coder->coder_id);
|
coder->coder_id);
|
||||||
pthread_mutex_unlock(&state->print_mutex);
|
pthread_mutex_unlock(&state->print_mutex);
|
||||||
// acquire right dongle
|
// acquire second dongle
|
||||||
pthread_mutex_lock(&coder->right_dongle->lock);
|
pthread_mutex_lock(&second->lock);
|
||||||
coder->right_dongle->last_used = now();
|
second->last_used = now();
|
||||||
pthread_mutex_lock(&state->print_mutex);
|
pthread_mutex_lock(&state->print_mutex);
|
||||||
printf("%ld %d has taken a dongle\n", now() - state->start,
|
printf("%ld %d has taken a dongle\n", now() - state->start,
|
||||||
coder->coder_id);
|
coder->coder_id);
|
||||||
|
|
@ -46,8 +57,9 @@ void compile_op(t_coder *coder, t_state *state)
|
||||||
printf("%ld %d is compiling\n", now() - state->start, coder->coder_id);
|
printf("%ld %d is compiling\n", now() - state->start, coder->coder_id);
|
||||||
pthread_mutex_unlock(&state->print_mutex);
|
pthread_mutex_unlock(&state->print_mutex);
|
||||||
usleep(state->args.time_to_compile * 1000L);
|
usleep(state->args.time_to_compile * 1000L);
|
||||||
pthread_mutex_unlock(&coder->left_dongle->lock);
|
// release dongles
|
||||||
pthread_mutex_unlock(&coder->right_dongle->lock);
|
pthread_mutex_unlock(&first->lock);
|
||||||
|
pthread_mutex_unlock(&second->lock);
|
||||||
coder->compiles_done += 1;
|
coder->compiles_done += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +86,7 @@ void *run(void *param)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
coder = param;
|
coder = param;
|
||||||
state = (t_state *)(coder->state);
|
state = coder->state;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < state->args.number_of_compiles_required)
|
while (i < state->args.number_of_compiles_required)
|
||||||
{
|
{
|
||||||
|
|
@ -128,6 +140,7 @@ int main(int argc, char **argv)
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < args->number_of_coders)
|
while (i < args->number_of_coders)
|
||||||
{
|
{
|
||||||
|
dongles[i].index = i;
|
||||||
pthread_mutex_init(&dongles[i].lock, NULL);
|
pthread_mutex_init(&dongles[i].lock, NULL);
|
||||||
dongles[i].last_used = state.start - args->dongle_cooldown;
|
dongles[i].last_used = state.start - args->dongle_cooldown;
|
||||||
i++;
|
i++;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue