diff --git a/src/engine.c b/src/engine.c index 93481aca3d25fd9755b7c7f69ef25ddb4d9d9d06..8a82aaf6a3647c6c0c298338fe8331dcd97a164f 100644 --- a/src/engine.c +++ b/src/engine.c @@ -4496,7 +4496,7 @@ void engine_init(struct engine *e, struct space *s, collectgroup_init(); /* Initialize the threadpool. */ - threadpool_init(&e->threadpool, e->nr_threads); + threadpool_init(&e->threadpool, e->nr_threads, e); /* First of all, init the barrier and lock it. */ if (pthread_barrier_init(&e->wait_barrier, NULL, e->nr_threads + 1) != 0 || diff --git a/src/scheduler.c b/src/scheduler.c index 6705f410f424d1b58c33f4f9ad6cea1bac5eba0f..9aa6d5f446688631937ed5d5537944985cf44de6 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1377,9 +1377,15 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) { if (qid >= s->nr_queues) error("Bad computed qid."); /* If no previous owner, pick a random queue. */ - if (qid < 0) - qid = rand_r((unsigned int *)pthread_getspecific(s->local_seed_pointer)) % - s->nr_queues; + if (qid < 0){ + unsigned int *seed = (unsigned int*) pthread_getspecific(s->local_seed_pointer); + /* Threadpool thread 0 is not a pthread so has to use rand (is fine as its the only thread + * to do so*/ + if(seed == NULL) + qid = rand() % s->nr_queues; + else + qid = rand_r(seed) % s->nr_queues; + } /* Increase the waiting counter. */ atomic_inc(&s->waiting); diff --git a/src/threadpool.c b/src/threadpool.c index 465756f71d88df81921a880edf8cdb1ee17f6026..24c86f5b21400b9c50b174889907d491d3ec688b 100644 --- a/src/threadpool.c +++ b/src/threadpool.c @@ -36,7 +36,9 @@ /* Local headers. */ #include "atomic.h" #include "clocks.h" +#include "engine.h" #include "error.h" +#include "scheduler.h" #include "minmax.h" #ifdef SWIFT_DEBUG_THREADPOOL @@ -163,8 +165,10 @@ void threadpool_chomp(struct threadpool *tp, int tid) { void *threadpool_runner(void *data) { /* Our threadpool. */ - struct threadpool *tp = (struct threadpool *)data; - + struct threadpool_runner *tpr = (struct threadpool_runner *)data; + struct threadpool *tp = tpr->tp; + struct engine *e = tpr->e; + pthread_setspecific(e->sched.local_seed_pointer, &tpr->id); /* Main loop. */ while (1) { @@ -189,7 +193,7 @@ void *threadpool_runner(void *data) { * @param tp The #threadpool. * @param num_threads The number of threads. */ -void threadpool_init(struct threadpool *tp, int num_threads) { +void threadpool_init(struct threadpool *tp, int num_threads, struct engine *e) { /* Initialize the thread counters. */ tp->num_threads = num_threads; @@ -229,10 +233,17 @@ void threadpool_init(struct threadpool *tp, int num_threads) { (num_threads - 1))) == NULL) { error("Failed to allocate thread array."); } + if ((tp->runners = (struct threadpool_runner *)malloc(sizeof(struct threadpool_runner) * + (num_threads-1))) == NULL) { + error("Failed to allocated runner array."); + } /* Create and start the threads. */ for (int k = 0; k < num_threads - 1; k++) { - if (pthread_create(&tp->threads[k], NULL, &threadpool_runner, tp) != 0) + tp->runners[k].tp = tp; + tp->runners[k].e = e; + tp->runners[k].id = k+1; + if (pthread_create(&tp->threads[k], NULL, &threadpool_runner, &tp->runners[k]) != 0) error("Failed to create threadpool runner thread."); } diff --git a/src/threadpool.h b/src/threadpool.h index 019403f658a22d36c4a6e1ec1ae1fdc47c62658d..315aed479ea8319964030258207f981724479ef4 100644 --- a/src/threadpool.h +++ b/src/threadpool.h @@ -63,12 +63,26 @@ struct mapper_log { int count; }; +/* Data of a threadpool runner */ +struct threadpool_runner{ + + /* The containing threadpool. */ + struct threadpool *tp; + /* The engine... */ + struct engine *e; + /* The thread ID*/ + int id; +}; + /* Data of a threadpool. */ struct threadpool { /* The threads themselves. */ pthread_t *threads; + /* The runner data associated with each thread. */ + struct threadpool_runner *runners; + /* This is where threads go to rest. */ pthread_barrier_t wait_barrier; pthread_barrier_t run_barrier; @@ -91,7 +105,7 @@ struct threadpool { }; /* Function prototypes. */ -void threadpool_init(struct threadpool *tp, int num_threads); +void threadpool_init(struct threadpool *tp, int num_threads, struct engine *e); void threadpool_map(struct threadpool *tp, threadpool_map_function map_function, void *map_data, size_t N, int stride, int chunk, void *extra_data);