diff --git a/src/scheduler.c b/src/scheduler.c index 8ffc16a48057e4042f5e6a967c2a3f88848905c2..a100d55039e3d24b325dd18f966f07b05997ee58 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -25,6 +25,7 @@ #include <stdlib.h> #include <string.h> #include <math.h> +#include <pthread.h> /* Local headers. */ #include "error.h" @@ -627,7 +628,10 @@ void scheduler_done ( struct scheduler *s , struct task *t ) { } /* Task definitely done. */ + pthread_mutex_lock( &s->sleep_mutex ); atomic_dec( &s->waiting ); + pthread_cond_broadcast( &s->sleep_cond ); + pthread_mutex_unlock( &s->sleep_mutex ); } @@ -664,6 +668,12 @@ struct task *scheduler_gettask ( struct scheduler *s , int qid ) { if ( max_count > 0 && ( res = queue_gettask( &s->queues[ max_ind ] , qid , 0 ) ) != NULL ) return res; } + + /* If we failed, take a short nap. */ + pthread_mutex_lock( &s->sleep_mutex ); + if ( s->waiting > 0 ) + pthread_cond_wait( &s->sleep_cond , &s->sleep_mutex ); + pthread_mutex_unlock( &s->sleep_mutex ); } @@ -696,6 +706,11 @@ void scheduler_init ( struct scheduler *s , struct space *space , int nr_queues for ( k = 0 ; k < nr_queues ; k++ ) queue_init( &s->queues[k] , NULL ); + /* Init the sleep mutex and cond. */ + if ( pthread_cond_init( &s->sleep_cond , NULL ) != 0 || + pthread_mutex_init( &s->sleep_mutex , NULL ) != 0 ) + error( "Failed to initialize sleep barrier." ); + /* Set the scheduler variables. */ s->nr_queues = nr_queues; s->flags = flags; diff --git a/src/scheduler.h b/src/scheduler.h index 485c9b101b25cb699b7f24e1589884bc94986b72..f38929d72e96f27a3e7f0409502639664a17a929 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -56,6 +56,10 @@ struct scheduler { /* Lock for this scheduler. */ lock_type lock; + /* Waiting queue. */ + pthread_mutex_t sleep_mutex; + pthread_cond_t sleep_cond; + /* The space associated with this scheduler. */ struct space *space;