diff --git a/examples/Makefile.am b/examples/Makefile.am index c95e2bc95f82a37b5c3035ddd532d627bf3483ec..4cc4cd3ddef9d72cb08c2f11a19c5156ad226aee 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -19,12 +19,12 @@ # Add the source directory and debug to CFLAGS AM_CFLAGS = -I../src -DCPU_TPS=2.67e9 -DTIMERS -AM_LDFLAGS = -lcblas - # Set-up the library -bin_PROGRAMS = test test_bh test_bh_sorted test_fmm_sorted +bin_PROGRAMS = test test_bh test_bh_sorted test_fmm_sorted thread_test pthread_test if HAVECBLAS bin_PROGRAMS += test_qr + +AM_LDFLAGS = -lcblas endif # Sources for test @@ -32,6 +32,14 @@ test_SOURCES = test.c test_CFLAGS = $(AM_CFLAGS) test_LDADD = ../src/.libs/libquicksched.a +thread_test_SOURCES = thread_test.c +thread_test_CFLAGS = $(AM_CFLAGS) +thread_test_LDADD = ../src/.libs/libquicksched.a + +pthread_test_SOURCES = thread_test.c +pthread_test_CFLAGS = $(AM_CFLAGS) -DFLAGS=qsched_flag_pthread +pthread_test_LDADD = ../src/.libs/libquicksched.a + # Sources for test_qr test_qr_SOURCES = test_qr.c test_qr_CFLAGS = $(AM_CFLAGS) diff --git a/examples/thread_test.c b/examples/thread_test.c new file mode 100644 index 0000000000000000000000000000000000000000..8ee63e0a9f6adb2cf590b1dbaf369bc885b3a4b5 --- /dev/null +++ b/examples/thread_test.c @@ -0,0 +1,34 @@ +#include "../config.h" +/* Local includes. */ +#include <stdio.h> +#include <stdlib.h> + +#include "quicksched.h" + +#ifndef FLAGS +#define FLAGS 0 +#endif + + struct qsched s; + + void runner(int type, void* data) + { + printf("%i\n", qsched_get_tid(&s)); + } + + +void main() +{ + qsched_init(&s, 4, FLAGS); + + for(int i =0; i < 1000; i++) + { + qsched_addtask(&s, 0, 0, NULL, 0, 0); + } + + qsched_run(&s, 4, &runner); + + qsched_free(&s); +} + + diff --git a/src/fqsched.F90 b/src/fqsched.F90 index 9ea8d25b3cc47d154824c1fc10613116d3b4b194..22822d33e912ab4def6258534288276bd9904267 100644 --- a/src/fqsched.F90 +++ b/src/fqsched.F90 @@ -25,7 +25,11 @@ Module quicksched Interface - !!TODO May need a qsched_get_qsched to get a pointer? + Integer(Kind=C_INT) Function qsched_get_tid(s) BIND(C) + Use, Intrinsic :: ISO_C_BINDING + Implicit None + Type(C_PTR), VALUE :: s + End Function Type(C_PTR) Function f_qsched_create() BIND(C) Use, Intrinsic :: ISO_C_BINDING diff --git a/src/qsched.c b/src/qsched.c index 45e0dac9f483ad82967c7a07773e623cd95436c7..5fb406afcb3949bd6f39887c26a95cb52915c985 100644 --- a/src/qsched.c +++ b/src/qsched.c @@ -410,7 +410,9 @@ void *qsched_pthread_run ( void *in ) { struct qsched *s = r->s; int tid = r->tid; struct task *t; - + #if defined ( HAVE_PTHREAD ) + pthread_setspecific(s->thread_id_key, &r->tid); + #endif /* Main loop. */ while ( 1 ) { @@ -527,6 +529,13 @@ void qsched_run ( struct qsched *s , int nr_threads , qsched_funtype fun ) { } +int qsched_get_tid(struct qsched *s) { + if( !HAVE_OPENMP || s->flags & (qsched_flag_yield | qsched_flag_pthread ) ) + return *(int*)pthread_getspecific(s->thread_id_key); + else + return omp_get_thread_num(); +} + /** * @brief Fetch the data pointer of a task. @@ -1521,7 +1530,7 @@ void qsched_free ( struct qsched *s ) { /* Destroy the mutex and condition. */ #ifdef HAVE_PTHREAD - if ( s->flags & qsched_flag_pthread ) { + if ( !HAVE_OPENMP || s->flags & ( qsched_flag_yield | qsched_flag_pthread ) ) { /* Start all the threads on an empty function, to kill them. */ s->fun = NULL; @@ -1547,6 +1556,7 @@ void qsched_free ( struct qsched *s ) { s->runners_size = 0; s->runners_count = 0; } + pthread_key_delete(s->thread_id_key); #endif /* Clear the flags. */ @@ -1618,7 +1628,7 @@ void qsched_init ( struct qsched *s , int nr_queues , int flags ) { /* Init the pthread stuff. */ #ifdef HAVE_PTHREAD - if ( flags & qsched_flag_pthread ) { + if ( !HAVE_OPENMP || s->flags & ( qsched_flag_yield | qsched_flag_pthread ) ) { if ( pthread_cond_init( &s->cond , NULL ) != 0 || pthread_mutex_init( &s->mutex , NULL ) != 0 ) error( "Error initializing yield cond/mutex pair." ); @@ -1635,6 +1645,7 @@ void qsched_init ( struct qsched *s , int nr_queues , int flags ) { if ( pthread_mutex_lock( &s->barrier_mutex ) != 0 ) error( "Failed to lock barrier mutex." ); } + pthread_key_create(&s->thread_id_key, NULL); #endif /* Clear the timers. */ diff --git a/src/qsched.h b/src/qsched.h index fa424b41f8e6d2c20893aea11ecf083e2597880f..b92c67d81d5378204345c8b3b224241965de2c63 100644 --- a/src/qsched.h +++ b/src/qsched.h @@ -158,6 +158,7 @@ struct qsched { int runners_count, runners_size; int barrier_running, barrier_count, barrier_launchcount; qsched_funtype fun; + pthread_key_t thread_id_key; #endif /* Timers. */ @@ -211,6 +212,7 @@ void qsched_reset ( struct qsched *s ); void qsched_addtask_dynamic ( struct qsched *s , int type , unsigned int flags , void *data , int data_size , int cost , qsched_res_t *locks , int nr_locks , qsched_res_t *uses , int nr_uses ); void qsched_ensure ( struct qsched *s , int nr_tasks , int nr_res , int nr_deps , int nr_locks , int nr_uses , int size_data ); void qsched_res_own ( struct qsched *s , qsched_res_t res , int owner ); +int qsched_get_tid(struct qsched *s); struct qsched * f_qsched_create(); void f_qsched_destroy( struct qsched *s);