Skip to content
Snippets Groups Projects
Commit 8044adb1 authored by Pedro Gonnet's avatar Pedro Gonnet
Browse files

added timers.

parent 1dc6966f
Branches
No related tags found
No related merge requests found
...@@ -20,7 +20,7 @@ AUTOMAKE_OPTIONS=gnu ...@@ -20,7 +20,7 @@ AUTOMAKE_OPTIONS=gnu
# Add the debug flag to the whole thing # Add the debug flag to the whole thing
AM_CFLAGS = -g -O3 -Wall -Werror -ffast-math -fstrict-aliasing -ftree-vectorize \ AM_CFLAGS = -g -O3 -Wall -Werror -ffast-math -fstrict-aliasing -ftree-vectorize \
-funroll-loops $(SIMD_FLAGS) $(OPENMP_CFLAGS) \ -funroll-loops $(SIMD_FLAGS) $(OPENMP_CFLAGS) -DTIMERS \
-fsanitize=address -fno-omit-frame-pointer -fsanitize=address -fno-omit-frame-pointer
# Assign a "safe" version number # Assign a "safe" version number
......
...@@ -296,7 +296,7 @@ AUTOMAKE_OPTIONS = gnu ...@@ -296,7 +296,7 @@ AUTOMAKE_OPTIONS = gnu
# Add the debug flag to the whole thing # Add the debug flag to the whole thing
AM_CFLAGS = -g -O3 -Wall -Werror -ffast-math -fstrict-aliasing -ftree-vectorize \ AM_CFLAGS = -g -O3 -Wall -Werror -ffast-math -fstrict-aliasing -ftree-vectorize \
-funroll-loops $(SIMD_FLAGS) $(OPENMP_CFLAGS) \ -funroll-loops $(SIMD_FLAGS) $(OPENMP_CFLAGS) -DTIMERS \
-fsanitize=address -fno-omit-frame-pointer -fsanitize=address -fno-omit-frame-pointer
......
...@@ -46,6 +46,11 @@ ...@@ -46,6 +46,11 @@
#include "queue.h" #include "queue.h"
/** Timer names. */
char *qsched_timer_names[ qsched_timer_count ] =
{ "queue" , "lock" , "gettask" , "done" , "prepare" };
/** /**
* @brief Change the owner of a resource. * @brief Change the owner of a resource.
* *
...@@ -263,6 +268,11 @@ void qsched_reset ( struct qsched *s ) { ...@@ -263,6 +268,11 @@ void qsched_reset ( struct qsched *s ) {
s->count_uses = 0; s->count_uses = 0;
s->count_res = 0; s->count_res = 0;
/* Clear the timers. */
#ifdef TIMERS
bzero( s->timers , sizeof(ticks) * qsched_timer_count );
#endif
} }
...@@ -486,6 +496,8 @@ void qsched_done ( struct qsched *s , struct task *t ) { ...@@ -486,6 +496,8 @@ void qsched_done ( struct qsched *s , struct task *t ) {
int k; int k;
struct task *t2; struct task *t2;
TIMER_TIC
/* Release this task's locks. */ /* Release this task's locks. */
for ( k = 0 ; k < t->nr_locks ; k++ ) for ( k = 0 ; k < t->nr_locks ; k++ )
...@@ -518,6 +530,10 @@ void qsched_done ( struct qsched *s , struct task *t ) { ...@@ -518,6 +530,10 @@ void qsched_done ( struct qsched *s , struct task *t ) {
pthread_mutex_unlock( &s->mutex ); pthread_mutex_unlock( &s->mutex );
} }
#endif #endif
/* Careful, this may pick up duplicate timers if virtual
tasks are used. */
TIMER_TOC( s , qsched_timer_done )
} }
...@@ -610,6 +626,8 @@ int qsched_locktask ( struct qsched *s , int tid ) { ...@@ -610,6 +626,8 @@ int qsched_locktask ( struct qsched *s , int tid ) {
int k; int k;
struct task *t; struct task *t;
TIMER_TIC
/* Get a pointer on the task. */ /* Get a pointer on the task. */
t = &s->tasks[tid]; t = &s->tasks[tid];
...@@ -627,13 +645,16 @@ int qsched_locktask ( struct qsched *s , int tid ) { ...@@ -627,13 +645,16 @@ int qsched_locktask ( struct qsched *s , int tid ) {
qsched_unlockres( s , t->locks[k] ); qsched_unlockres( s , t->locks[k] );
/* Fail. */ /* Fail. */
TIMER_TOC( s , qsched_timer_lock )
return 0; return 0;
} }
/* Otherwise, all went well. */ /* Otherwise, all went well. */
else else {
TIMER_TOC( s , qsched_timer_lock )
return 1; return 1;
}
} }
...@@ -649,6 +670,8 @@ void qsched_unlocktask ( struct qsched *s , int tid ) { ...@@ -649,6 +670,8 @@ void qsched_unlocktask ( struct qsched *s , int tid ) {
int k; int k;
struct task *t; struct task *t;
TIMER_TIC
/* Get a pointer on the task. */ /* Get a pointer on the task. */
t = &s->tasks[tid]; t = &s->tasks[tid];
...@@ -656,6 +679,8 @@ void qsched_unlocktask ( struct qsched *s , int tid ) { ...@@ -656,6 +679,8 @@ void qsched_unlocktask ( struct qsched *s , int tid ) {
/* Unlock the used resources. */ /* Unlock the used resources. */
for ( k = 0 ; k < t->nr_locks ; k++ ) for ( k = 0 ; k < t->nr_locks ; k++ )
qsched_unlockres( s , t->locks[k] ); qsched_unlockres( s , t->locks[k] );
TIMER_TOC( s , qsched_timer_lock )
} }
...@@ -677,6 +702,8 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) { ...@@ -677,6 +702,8 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) {
int naq, k, tid, qids[ s->nr_queues ]; int naq, k, tid, qids[ s->nr_queues ];
struct task *t; struct task *t;
TIMER_TIC
/* Check if the sched is ok. */ /* Check if the sched is ok. */
if ( s->flags & qsched_flag_dirty || !(s->flags & qsched_flag_ready) ) if ( s->flags & qsched_flag_dirty || !(s->flags & qsched_flag_ready) )
...@@ -690,20 +717,28 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) { ...@@ -690,20 +717,28 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) {
while ( s->waiting ) { while ( s->waiting ) {
/* Try to get a task from my own queue. */ /* Try to get a task from my own queue. */
if ( ( tid = queue_get( &s->queues[qid] , s ) ) < 0 ) { {
TIMER_TIC
/* Otherwise, hit the other queues. */ tid = queue_get( &s->queues[qid] , s );
for ( naq = 0 , k = 0 ; k < s->nr_queues ; k++ ) TIMER_TOC( s , qsched_timer_queue )
if ( k != qid && s->queues[k].count > 0 ) if ( tid < 0 ) {
qids[ naq++ ] = k;
while ( naq > 0 ) { /* Otherwise, hit the other queues. */
k = rand() % naq; for ( naq = 0 , k = 0 ; k < s->nr_queues ; k++ )
if ( ( tid = queue_get( &s->queues[ qids[k] ] , s ) ) < 0 ) if ( k != qid && s->queues[k].count > 0 )
qids[k] = qids[ --naq ]; qids[ naq++ ] = k;
else while ( naq > 0 ) {
break; k = rand() % naq;
TIMER_TIC2
tid = queue_get( &s->queues[ qids[k] ] , s );
TIMER_TOC( s , qsched_timer_queue )
if ( tid < 0 )
qids[k] = qids[ --naq ];
else
break;
}
} }
} }
/* Bail if a valid task ID was returned. */ /* Bail if a valid task ID was returned. */
...@@ -725,6 +760,7 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) { ...@@ -725,6 +760,7 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) {
t->qid = qid; t->qid = qid;
/* Return the task. */ /* Return the task. */
TIMER_TOC( s , qsched_timer_gettask )
return t; return t;
} }
...@@ -732,16 +768,19 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) { ...@@ -732,16 +768,19 @@ struct task *qsched_gettask ( struct qsched *s , int qid ) {
/* Otherwise, take a nap? */ /* Otherwise, take a nap? */
#ifdef HAVE_PTHREAD #ifdef HAVE_PTHREAD
else if ( s->flags & qsched_flag_yield ) { else if ( s->flags & qsched_flag_yield ) {
TIMER_TOC( s , qsched_timer_gettask )
pthread_mutex_lock( &s->mutex ); pthread_mutex_lock( &s->mutex );
if ( s->waiting ) if ( s->waiting )
pthread_cond_wait( &s->cond , &s->mutex ); pthread_cond_wait( &s->cond , &s->mutex );
pthread_mutex_unlock( &s->mutex ); pthread_mutex_unlock( &s->mutex );
TIMER_TIC2
} }
#endif #endif
} }
/* Return empty-handed. */ /* Return empty-handed. No toc here as we don't want to
count the final wait when all tasks have been executed. */
return NULL; return NULL;
} }
...@@ -840,6 +879,8 @@ void qsched_prepare ( struct qsched *s ) { ...@@ -840,6 +879,8 @@ void qsched_prepare ( struct qsched *s ) {
int j, k, count; int j, k, count;
struct task *t, *tasks; struct task *t, *tasks;
TIMER_TIC
/* Lock the sched. */ /* Lock the sched. */
lock_lock( &s->lock ); lock_lock( &s->lock );
...@@ -946,6 +987,8 @@ void qsched_prepare ( struct qsched *s ) { ...@@ -946,6 +987,8 @@ void qsched_prepare ( struct qsched *s ) {
/* Unlock the sched. */ /* Unlock the sched. */
lock_unlock_blind( &s->lock ); lock_unlock_blind( &s->lock );
TIMER_TOC( s , qsched_timer_prepare )
} }
...@@ -1384,6 +1427,11 @@ void qsched_init ( struct qsched *s , int nr_queues , int flags ) { ...@@ -1384,6 +1427,11 @@ void qsched_init ( struct qsched *s , int nr_queues , int flags ) {
error( "Error initializing cond/mutex pair." ); error( "Error initializing cond/mutex pair." );
#endif #endif
/* Clear the timers. */
#ifdef TIMERS
bzero( s->timers , sizeof(ticks) * qsched_timer_count );
#endif
/* Init the sched lock. */ /* Init the sched lock. */
lock_init( &s->lock ); lock_init( &s->lock );
......
...@@ -51,6 +51,30 @@ typedef int qsched_res_t; ...@@ -51,6 +51,30 @@ typedef int qsched_res_t;
typedef void (*qsched_funtype)( int , void * ); typedef void (*qsched_funtype)( int , void * );
/** Timer types. */
enum qsched_timer {
qsched_timer_queue = 0,
qsched_timer_lock,
qsched_timer_gettask,
qsched_timer_done,
qsched_timer_prepare,
qsched_timer_count
};
extern char *qsched_timer_names[];
/* Timer macros. */
#ifdef TIMERS
#define TIMER_TIC ticks __tic = getticks();
#define TIMER_TIC2 __tic = getticks();
#define TIMER_TOC(s,tid) atomic_add( &s->timers[tid] , getticks() - __tic );
#else
#define TIMER_TIC
#define TIMER_TIC2
#define TIMER_TOC
#endif
/* The sched data structre. */ /* The sched data structre. */
struct qsched { struct qsched {
...@@ -128,6 +152,11 @@ struct qsched { ...@@ -128,6 +152,11 @@ struct qsched {
pthread_mutex_t mutex; pthread_mutex_t mutex;
#endif #endif
/* Timers. */
#ifdef TIMERS
ticks timers[ qsched_timer_count ];
#endif
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment