Commit 137cd5fc authored by Peter W. Draper's avatar Peter W. Draper
Browse files

Merge branch 'rewait_fixes' into 'master'

Rewait fixes

Fixes the deadlock described in #125.

See merge request !122
parents c4d1b553 51dec77e
......@@ -136,9 +136,6 @@ struct task *queue_gettask(struct queue *q, const struct task *prev,
lock_type *qlock = &q->lock;
struct task *res = NULL;
/* If there are no tasks, leave immediately. */
if (q->count == 0) return NULL;
/* Grab the task lock. */
if (blocking) {
if (lock_lock(qlock) != 0) error("Locking the qlock failed.\n");
......@@ -146,6 +143,12 @@ struct task *queue_gettask(struct queue *q, const struct task *prev,
if (lock_trylock(qlock) != 0) return NULL;
}
/* If there are no tasks, leave immediately. */
if (q->count == 0) {
lock_unlock_blind(qlock);
return NULL;
}
/* Set some pointers we will use often. */
int *qtid = q->tid;
struct task *qtasks = q->tasks;
......
......@@ -983,8 +983,7 @@ void scheduler_start(struct scheduler *s, unsigned int mask,
const int waiting_old = s->waiting;
/* We are going to use the task structure in a modified way to pass
information
to the task. Don't do this at home !
information to the task. Don't do this at home !
- ci and cj will give the range of tasks to which the waits will be applied
- the flags will be used to transfer the mask
- the rank will be used to transfer the submask
......@@ -1009,6 +1008,7 @@ void scheduler_start(struct scheduler *s, unsigned int mask,
/* Wait for the rewait tasks to have executed. */
pthread_mutex_lock(&s->sleep_mutex);
pthread_cond_broadcast(&s->sleep_cond);
while (s->waiting > waiting_old) {
pthread_cond_wait(&s->sleep_cond, &s->sleep_mutex);
}
......@@ -1030,6 +1030,11 @@ void scheduler_start(struct scheduler *s, unsigned int mask,
}
}
/* To be safe, fire of one last sleep_cond in a safe way. */
pthread_mutex_lock(&s->sleep_mutex);
pthread_cond_broadcast(&s->sleep_cond);
pthread_mutex_unlock(&s->sleep_mutex);
// message( "enqueueing tasks took %.3f %s." ,
// clocks_from_ticks( getticks() - tic ), clocks_getunit());
}
......@@ -1125,7 +1130,7 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
if (qid >= s->nr_queues) error("Bad computed qid.");
/* If no previous owner, find the shortest queue. */
/* If no previous owner, pick a random queue. */
if (qid < 0) qid = rand() % s->nr_queues;
/* Increase the waiting counter. */
......@@ -1279,7 +1284,10 @@ struct task *scheduler_gettask(struct scheduler *s, int qid,
if (res == NULL) {
#endif
pthread_mutex_lock(&s->sleep_mutex);
if (s->waiting > 0) pthread_cond_wait(&s->sleep_cond, &s->sleep_mutex);
res = queue_gettask(&s->queues[qid], prev, 1);
if (res == NULL && s->waiting > 0) {
pthread_cond_wait(&s->sleep_cond, &s->sleep_mutex);
}
pthread_mutex_unlock(&s->sleep_mutex);
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment