From d130a177a49c89dbe96190a254f6efbdaf4e982c Mon Sep 17 00:00:00 2001
From:  <aidan@DESKTOP-CO5CLN1.localdomain>
Date: Wed, 26 Apr 2017 23:16:52 +0100
Subject: [PATCH] Draft version of a fix for #302. There is no obvious reused
 variable to use a temporary seed for each thread, so instead each thread has
 a thread-local variable which is uses to seed the rand_r call in
 scheduler_enqueue. I need to test this doesn't fail at any point (e.g. if
 we're not in a pthread region) but I'm not sure if it would be encountered
 outside of a pthread @nnrw56?

---
 src/runner.c    | 3 ++-
 src/scheduler.c | 3 ++-
 src/scheduler.h | 2 ++
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/runner.c b/src/runner.c
index 512a4f362f..dc6cc865a6 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -1656,7 +1656,8 @@ void *runner_main(void *data) {
   struct runner *r = (struct runner *)data;
   struct engine *e = r->e;
   struct scheduler *sched = &e->sched;
-
+  int seed = r->id
+  pthread_setspecific(sched->local_seed_pointer, &seed);
   /* Main loop. */
   while (1) {
 
diff --git a/src/scheduler.c b/src/scheduler.c
index 62fce53762..b75119ffba 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -1305,7 +1305,7 @@ 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() % s->nr_queues;
+    if (qid < 0) qid = rand_r((int*)pthread_getspecific(s->local_seed_pointer) ) % s->nr_queues;
 
     /* Increase the waiting counter. */
     atomic_inc(&s->waiting);
@@ -1537,6 +1537,7 @@ void scheduler_init(struct scheduler *s, struct space *space, int nr_tasks,
   s->size = 0;
   s->tasks = NULL;
   s->tasks_ind = NULL;
+  pthread_key_create(&s->local_seed_pointer);
   scheduler_reset(s, nr_tasks);
 }
 
diff --git a/src/scheduler.h b/src/scheduler.h
index f2225f5f5b..24bf5f105d 100644
--- a/src/scheduler.h
+++ b/src/scheduler.h
@@ -102,6 +102,8 @@ struct scheduler {
 
   /* The node we are working on. */
   int nodeID;
+
+  pthread_key_t local_seed_pointer;
 };
 
 /* Inlined functions (for speed). */
-- 
GitLab