summaryrefslogtreecommitdiff
path: root/lib/libzpool/common/taskq.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libzpool/common/taskq.c')
-rw-r--r--lib/libzpool/common/taskq.c103
1 files changed, 34 insertions, 69 deletions
diff --git a/lib/libzpool/common/taskq.c b/lib/libzpool/common/taskq.c
index 2c5dfd86dcc0..8db5d11c1327 100644
--- a/lib/libzpool/common/taskq.c
+++ b/lib/libzpool/common/taskq.c
@@ -22,16 +22,19 @@
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
- */
#include <sys/zfs_context.h>
int taskq_now;
taskq_t *system_taskq;
+typedef struct task {
+ struct task *task_next;
+ struct task *task_prev;
+ task_func_t *task_func;
+ void *task_arg;
+} task_t;
+
#define TASKQ_ACTIVE 0x00010000
struct taskq {
@@ -48,18 +51,18 @@ struct taskq {
int tq_maxalloc;
kcondvar_t tq_maxalloc_cv;
int tq_maxalloc_wait;
- taskq_ent_t *tq_freelist;
- taskq_ent_t tq_task;
+ task_t *tq_freelist;
+ task_t tq_task;
};
-static taskq_ent_t *
+static task_t *
task_alloc(taskq_t *tq, int tqflags)
{
- taskq_ent_t *t;
+ task_t *t;
int rv;
again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
- tq->tq_freelist = t->tqent_next;
+ tq->tq_freelist = t->task_next;
} else {
if (tq->tq_nalloc >= tq->tq_maxalloc) {
if (!(tqflags & KM_SLEEP))
@@ -84,7 +87,7 @@ again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
}
mutex_exit(&tq->tq_lock);
- t = kmem_alloc(sizeof (taskq_ent_t), tqflags);
+ t = kmem_alloc(sizeof (task_t), tqflags);
mutex_enter(&tq->tq_lock);
if (t != NULL)
@@ -94,15 +97,15 @@ again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
}
static void
-task_free(taskq_t *tq, taskq_ent_t *t)
+task_free(taskq_t *tq, task_t *t)
{
if (tq->tq_nalloc <= tq->tq_minalloc) {
- t->tqent_next = tq->tq_freelist;
+ t->task_next = tq->tq_freelist;
tq->tq_freelist = t;
} else {
tq->tq_nalloc--;
mutex_exit(&tq->tq_lock);
- kmem_free(t, sizeof (taskq_ent_t));
+ kmem_free(t, sizeof (task_t));
mutex_enter(&tq->tq_lock);
}
@@ -113,7 +116,7 @@ task_free(taskq_t *tq, taskq_ent_t *t)
taskqid_t
taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
{
- taskq_ent_t *t;
+ task_t *t;
if (taskq_now) {
func(arg);
@@ -127,59 +130,26 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
return (0);
}
if (tqflags & TQ_FRONT) {
- t->tqent_next = tq->tq_task.tqent_next;
- t->tqent_prev = &tq->tq_task;
+ t->task_next = tq->tq_task.task_next;
+ t->task_prev = &tq->tq_task;
} else {
- t->tqent_next = &tq->tq_task;
- t->tqent_prev = tq->tq_task.tqent_prev;
+ t->task_next = &tq->tq_task;
+ t->task_prev = tq->tq_task.task_prev;
}
- t->tqent_next->tqent_prev = t;
- t->tqent_prev->tqent_next = t;
- t->tqent_func = func;
- t->tqent_arg = arg;
- t->tqent_flags = 0;
+ t->task_next->task_prev = t;
+ t->task_prev->task_next = t;
+ t->task_func = func;
+ t->task_arg = arg;
cv_signal(&tq->tq_dispatch_cv);
mutex_exit(&tq->tq_lock);
return (1);
}
void
-taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
- taskq_ent_t *t)
-{
- ASSERT(func != NULL);
- ASSERT(!(tq->tq_flags & TASKQ_DYNAMIC));
-
- /*
- * Mark it as a prealloc'd task. This is important
- * to ensure that we don't free it later.
- */
- t->tqent_flags |= TQENT_FLAG_PREALLOC;
- /*
- * Enqueue the task to the underlying queue.
- */
- mutex_enter(&tq->tq_lock);
-
- if (flags & TQ_FRONT) {
- t->tqent_next = tq->tq_task.tqent_next;
- t->tqent_prev = &tq->tq_task;
- } else {
- t->tqent_next = &tq->tq_task;
- t->tqent_prev = tq->tq_task.tqent_prev;
- }
- t->tqent_next->tqent_prev = t;
- t->tqent_prev->tqent_next = t;
- t->tqent_func = func;
- t->tqent_arg = arg;
- cv_signal(&tq->tq_dispatch_cv);
- mutex_exit(&tq->tq_lock);
-}
-
-void
taskq_wait(taskq_t *tq)
{
mutex_enter(&tq->tq_lock);
- while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0)
+ while (tq->tq_task.task_next != &tq->tq_task || tq->tq_active != 0)
cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
mutex_exit(&tq->tq_lock);
}
@@ -188,32 +158,27 @@ static void *
taskq_thread(void *arg)
{
taskq_t *tq = arg;
- taskq_ent_t *t;
- boolean_t prealloc;
+ task_t *t;
mutex_enter(&tq->tq_lock);
while (tq->tq_flags & TASKQ_ACTIVE) {
- if ((t = tq->tq_task.tqent_next) == &tq->tq_task) {
+ if ((t = tq->tq_task.task_next) == &tq->tq_task) {
if (--tq->tq_active == 0)
cv_broadcast(&tq->tq_wait_cv);
cv_wait(&tq->tq_dispatch_cv, &tq->tq_lock);
tq->tq_active++;
continue;
}
- t->tqent_prev->tqent_next = t->tqent_next;
- t->tqent_next->tqent_prev = t->tqent_prev;
- t->tqent_next = NULL;
- t->tqent_prev = NULL;
- prealloc = t->tqent_flags & TQENT_FLAG_PREALLOC;
+ t->task_prev->task_next = t->task_next;
+ t->task_next->task_prev = t->task_prev;
mutex_exit(&tq->tq_lock);
rw_enter(&tq->tq_threadlock, RW_READER);
- t->tqent_func(t->tqent_arg);
+ t->task_func(t->task_arg);
rw_exit(&tq->tq_threadlock);
mutex_enter(&tq->tq_lock);
- if (!prealloc)
- task_free(tq, t);
+ task_free(tq, t);
}
tq->tq_nthreads--;
cv_broadcast(&tq->tq_wait_cv);
@@ -252,8 +217,8 @@ taskq_create(const char *name, int nthreads, pri_t pri,
tq->tq_nthreads = nthreads;
tq->tq_minalloc = minalloc;
tq->tq_maxalloc = maxalloc;
- tq->tq_task.tqent_next = &tq->tq_task;
- tq->tq_task.tqent_prev = &tq->tq_task;
+ tq->tq_task.task_next = &tq->tq_task;
+ tq->tq_task.task_prev = &tq->tq_task;
tq->tq_threadlist = kmem_alloc(nthreads * sizeof (thread_t), KM_SLEEP);
if (flags & TASKQ_PREPOPULATE) {