From e82e390295d16f535921f1378e4214aaf40ec8df Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 27 Jul 2011 16:40:52 +1000 Subject: [PATCH] If work has been cloned it is already at the head of the list and when being reinserted into the queue it should be placed back at the head of the list. --- main.c | 11 ++++++++++- miner.h | 1 + util.c | 27 +++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/main.c b/main.c index 139ce466..3f87c341 100644 --- a/main.c +++ b/main.c @@ -1478,7 +1478,16 @@ static void *stage_thread(void *userdata) if (!work->cloned && !work->clone) gettimeofday(&work->tv_staged, NULL); - if (unlikely(!tq_push(getq, work))) { + /* If the work is cloned it has already gone to get_work once + * so it must be used ASAP before it goes stale so put it at + * the head of the list */ + if (work->cloned) { + if (unlikely(!tq_push_head(getq, work))) { + applog(LOG_ERR, "Failed to tq_push work in stage_thread"); + ok = false; + break; + } + } else if (unlikely(!tq_push(getq, work))) { applog(LOG_ERR, "Failed to tq_push work in stage_thread"); ok = false; break; diff --git a/miner.h b/miner.h index 0b6eacb3..53e20696 100644 --- a/miner.h +++ b/miner.h @@ -346,6 +346,7 @@ extern void vapplog(int prio, const char *fmt, va_list ap); extern void applog(int prio, const char *fmt, ...); extern struct thread_q *tq_new(void); extern void tq_free(struct thread_q *tq); +extern bool tq_push_head(struct thread_q *tq, void *data); extern bool tq_push(struct thread_q *tq, void *data); extern void *tq_pop(struct thread_q *tq, const struct timespec *abstime); extern void tq_freeze(struct thread_q *tq); diff --git a/util.c b/util.c index f726b4a4..1b2295ea 100644 --- a/util.c +++ b/util.c @@ -618,6 +618,33 @@ void tq_thaw(struct thread_q *tq) tq_freezethaw(tq, false); } +bool tq_push_head(struct thread_q *tq, void *data) +{ + struct tq_ent *ent; + bool rc = true; + + ent = calloc(1, sizeof(*ent)); + if (!ent) + return false; + + ent->data = data; + INIT_LIST_HEAD(&ent->q_node); + + mutex_lock(&tq->mutex); + + if (!tq->frozen) { + list_add(&ent->q_node, &tq->q); + } else { + free(ent); + rc = false; + } + + pthread_cond_signal(&tq->cond); + mutex_unlock(&tq->mutex); + + return rc; +} + bool tq_push(struct thread_q *tq, void *data) { struct tq_ent *ent;