MFC r196295:
Remove OpenSolaris taskq port (it performs very poorly in our kernel) and replace it with wrappers around our taskqueue(9). To make it possible implement taskqueue_member() function which returns 1 if the given thread was created by the given taskqueue. Approved by: re (kib)
This commit is contained in:
parent
ea5f504fed
commit
e43f173602
@ -28,7 +28,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 13, 2008
|
||||
.Dd August 17, 2009
|
||||
.Dt TASKQUEUE 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -71,6 +71,8 @@ struct task {
|
||||
.Fn taskqueue_run_fast "struct taskqueue *queue"
|
||||
.Ft void
|
||||
.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
|
||||
.Ft int
|
||||
.Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
|
||||
.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context"
|
||||
.Fn TASKQUEUE_DECLARE "name"
|
||||
.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
|
||||
@ -182,6 +184,18 @@ There is no guarantee that the task will not be
|
||||
enqueued after call to
|
||||
.Fn taskqueue_drain .
|
||||
.Pp
|
||||
The
|
||||
.Fn taskqueue_member
|
||||
function returns
|
||||
.No 1
|
||||
is the given thread
|
||||
.Fa td
|
||||
is part of the given taskqeueue
|
||||
.Fa queue
|
||||
and
|
||||
.No 0
|
||||
otherwise.
|
||||
.Pp
|
||||
A convenience macro,
|
||||
.Fn TASK_INIT "task" "priority" "func" "context"
|
||||
is provided to initialise a
|
||||
|
135
sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
Normal file
135
sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <sys/taskq.h>
|
||||
|
||||
#include <vm/uma.h>
|
||||
|
||||
static uma_zone_t taskq_zone;
|
||||
|
||||
struct ostask {
|
||||
struct task ost_task;
|
||||
task_func_t *ost_func;
|
||||
void *ost_arg;
|
||||
};
|
||||
|
||||
taskq_t *system_taskq = NULL;
|
||||
|
||||
static void
|
||||
system_taskq_init(void *arg)
|
||||
{
|
||||
|
||||
system_taskq = (taskq_t *)taskqueue_thread;
|
||||
taskq_zone = uma_zcreate("taskq_zone", sizeof(struct ostask),
|
||||
NULL, NULL, NULL, NULL, 0, 0);
|
||||
}
|
||||
SYSINIT(system_taskq_init, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_init, NULL);
|
||||
|
||||
static void
|
||||
system_taskq_fini(void *arg)
|
||||
{
|
||||
|
||||
uma_zdestroy(taskq_zone);
|
||||
}
|
||||
SYSUNINIT(system_taskq_fini, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_fini, NULL);
|
||||
|
||||
taskq_t *
|
||||
taskq_create(const char *name, int nthreads, pri_t pri, int minalloc __unused,
|
||||
int maxalloc __unused, uint_t flags)
|
||||
{
|
||||
taskq_t *tq;
|
||||
|
||||
if ((flags & TASKQ_THREADS_CPU_PCT) != 0) {
|
||||
/* TODO: Calculate number od threads. */
|
||||
printf("%s: TASKQ_THREADS_CPU_PCT\n", __func__);
|
||||
}
|
||||
|
||||
tq = kmem_alloc(sizeof(*tq), KM_SLEEP);
|
||||
tq->tq_queue = taskqueue_create(name, M_WAITOK, taskqueue_thread_enqueue,
|
||||
&tq->tq_queue);
|
||||
(void) taskqueue_start_threads(&tq->tq_queue, nthreads, pri, name);
|
||||
|
||||
return ((taskq_t *)tq);
|
||||
}
|
||||
|
||||
void
|
||||
taskq_destroy(taskq_t *tq)
|
||||
{
|
||||
|
||||
taskqueue_free(tq->tq_queue);
|
||||
kmem_free(tq, sizeof(*tq));
|
||||
}
|
||||
|
||||
int
|
||||
taskq_member(taskq_t *tq, kthread_t *thread)
|
||||
{
|
||||
|
||||
return (taskqueue_member(tq->tq_queue, thread));
|
||||
}
|
||||
|
||||
static void
|
||||
taskq_run(void *arg, int pending __unused)
|
||||
{
|
||||
struct ostask *task = arg;
|
||||
|
||||
task->ost_func(task->ost_arg);
|
||||
|
||||
uma_zfree(taskq_zone, task);
|
||||
}
|
||||
|
||||
taskqid_t
|
||||
taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
|
||||
{
|
||||
struct ostask *task;
|
||||
int mflag;
|
||||
|
||||
if ((flags & (TQ_SLEEP | TQ_NOQUEUE)) == TQ_SLEEP)
|
||||
mflag = M_WAITOK;
|
||||
else
|
||||
mflag = M_NOWAIT;
|
||||
|
||||
task = uma_zalloc(taskq_zone, mflag);
|
||||
if (task == NULL)
|
||||
return (0);
|
||||
|
||||
task->ost_func = func;
|
||||
task->ost_arg = arg;
|
||||
|
||||
TASK_INIT(&task->ost_task, 0, taskq_run, task);
|
||||
taskqueue_enqueue(tq->tq_queue, &task->ost_task);
|
||||
|
||||
return ((taskqid_t)(void *)task);
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TASKQ_IMPL_H
|
||||
#define _SYS_TASKQ_IMPL_H
|
||||
|
||||
#pragma ident "@(#)taskq_impl.h 1.6 05/06/08 SMI"
|
||||
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/rwlock.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/taskq.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct taskq_bucket taskq_bucket_t;
|
||||
|
||||
typedef struct taskq_ent {
|
||||
struct taskq_ent *tqent_next;
|
||||
struct taskq_ent *tqent_prev;
|
||||
task_func_t *tqent_func;
|
||||
void *tqent_arg;
|
||||
taskq_bucket_t *tqent_bucket;
|
||||
kthread_t *tqent_thread;
|
||||
kcondvar_t tqent_cv;
|
||||
} taskq_ent_t;
|
||||
|
||||
/*
|
||||
* Taskq Statistics fields are not protected by any locks.
|
||||
*/
|
||||
typedef struct tqstat {
|
||||
uint_t tqs_hits;
|
||||
uint_t tqs_misses;
|
||||
uint_t tqs_overflow; /* no threads to allocate */
|
||||
uint_t tqs_tcreates; /* threads created */
|
||||
uint_t tqs_tdeaths; /* threads died */
|
||||
uint_t tqs_maxthreads; /* max # of alive threads */
|
||||
uint_t tqs_nomem; /* # of times there were no memory */
|
||||
uint_t tqs_disptcreates;
|
||||
} tqstat_t;
|
||||
|
||||
/*
|
||||
* Per-CPU hash bucket manages taskq_bent_t structures using freelist.
|
||||
*/
|
||||
struct taskq_bucket {
|
||||
kmutex_t tqbucket_lock;
|
||||
taskq_t *tqbucket_taskq; /* Enclosing taskq */
|
||||
taskq_ent_t tqbucket_freelist;
|
||||
uint_t tqbucket_nalloc; /* # of allocated entries */
|
||||
uint_t tqbucket_nfree; /* # of free entries */
|
||||
kcondvar_t tqbucket_cv;
|
||||
ushort_t tqbucket_flags;
|
||||
hrtime_t tqbucket_totaltime;
|
||||
tqstat_t tqbucket_stat;
|
||||
};
|
||||
|
||||
/*
|
||||
* Bucket flags.
|
||||
*/
|
||||
#define TQBUCKET_CLOSE 0x01
|
||||
#define TQBUCKET_SUSPEND 0x02
|
||||
|
||||
/*
|
||||
* taskq implementation flags: bit range 16-31
|
||||
*/
|
||||
#define TASKQ_ACTIVE 0x00010000
|
||||
#define TASKQ_SUSPENDED 0x00020000
|
||||
#define TASKQ_NOINSTANCE 0x00040000
|
||||
|
||||
struct taskq {
|
||||
char tq_name[TASKQ_NAMELEN + 1];
|
||||
kmutex_t tq_lock;
|
||||
krwlock_t tq_threadlock;
|
||||
kcondvar_t tq_dispatch_cv;
|
||||
kcondvar_t tq_wait_cv;
|
||||
uint_t tq_flags;
|
||||
int tq_active;
|
||||
int tq_nthreads;
|
||||
int tq_nalloc;
|
||||
int tq_minalloc;
|
||||
int tq_maxalloc;
|
||||
taskq_ent_t *tq_freelist;
|
||||
taskq_ent_t tq_task;
|
||||
int tq_maxsize;
|
||||
pri_t tq_pri; /* Scheduling priority */
|
||||
taskq_bucket_t *tq_buckets; /* Per-cpu array of buckets */
|
||||
uint_t tq_nbuckets; /* # of buckets (2^n) */
|
||||
union {
|
||||
kthread_t *_tq_thread;
|
||||
kthread_t **_tq_threadlist;
|
||||
} tq_thr;
|
||||
/*
|
||||
* Statistics.
|
||||
*/
|
||||
hrtime_t tq_totaltime; /* Time spent processing tasks */
|
||||
int tq_tasks; /* Total # of tasks posted */
|
||||
int tq_executed; /* Total # of tasks executed */
|
||||
int tq_maxtasks; /* Max number of tasks in the queue */
|
||||
int tq_tcreates;
|
||||
int tq_tdeaths;
|
||||
};
|
||||
|
||||
#define tq_thread tq_thr._tq_thread
|
||||
#define tq_threadlist tq_thr._tq_threadlist
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_TASKQ_IMPL_H */
|
@ -49,6 +49,7 @@ extern "C" {
|
||||
#include <sys/conf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/rwlock.h>
|
||||
#include <sys/kcondvar.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <sys/systm.h>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,9 +2,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
@ -18,22 +17,18 @@
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TASKQ_H
|
||||
#define _SYS_TASKQ_H
|
||||
|
||||
#pragma ident "@(#)taskq.h 1.5 05/06/08 SMI"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kcondvar.h>
|
||||
#include <sys/taskqueue.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -41,6 +36,11 @@ extern "C" {
|
||||
|
||||
#define TASKQ_NAMELEN 31
|
||||
|
||||
struct taskqueue;
|
||||
struct taskq {
|
||||
struct taskqueue *tq_queue;
|
||||
};
|
||||
|
||||
typedef struct taskq taskq_t;
|
||||
typedef uintptr_t taskqid_t;
|
||||
typedef void (task_func_t)(void *);
|
||||
@ -51,6 +51,7 @@ typedef void (task_func_t)(void *);
|
||||
#define TASKQ_PREPOPULATE 0x0001 /* Prepopulate with threads and data */
|
||||
#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
|
||||
#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
|
||||
#define TASKQ_THREADS_CPU_PCT 0x0008 /* number of threads as % of ncpu */
|
||||
|
||||
/*
|
||||
* Flags for taskq_dispatch. TQ_SLEEP/TQ_NOSLEEP should be same as
|
||||
@ -65,6 +66,9 @@ typedef void (task_func_t)(void *);
|
||||
|
||||
extern taskq_t *system_taskq;
|
||||
|
||||
extern void taskq_init(void);
|
||||
extern void taskq_mp_init(void);
|
||||
|
||||
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
||||
extern taskq_t *taskq_create_instance(const char *, int, int, pri_t, int,
|
||||
int, uint_t);
|
@ -472,3 +472,23 @@ taskqueue_fast_run(void *dummy)
|
||||
TASKQUEUE_FAST_DEFINE(fast, taskqueue_fast_enqueue, NULL,
|
||||
swi_add(NULL, "Fast task queue", taskqueue_fast_run, NULL,
|
||||
SWI_TQ_FAST, INTR_MPSAFE, &taskqueue_fast_ih));
|
||||
|
||||
int
|
||||
taskqueue_member(struct taskqueue *queue, struct thread *td)
|
||||
{
|
||||
int i, j, ret = 0;
|
||||
|
||||
TQ_LOCK(queue);
|
||||
for (i = 0, j = 0; ; i++) {
|
||||
if (queue->tq_threads[i] == NULL)
|
||||
continue;
|
||||
if (queue->tq_threads[i] == td) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
if (++j >= queue->tq_tcount)
|
||||
break;
|
||||
}
|
||||
TQ_UNLOCK(queue);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ SRCS+= opensolaris_kstat.c
|
||||
SRCS+= opensolaris_lookup.c
|
||||
SRCS+= opensolaris_policy.c
|
||||
SRCS+= opensolaris_string.c
|
||||
SRCS+= opensolaris_taskq.c
|
||||
SRCS+= opensolaris_vfs.c
|
||||
SRCS+= opensolaris_zone.c
|
||||
|
||||
@ -42,7 +43,6 @@ SRCS+= vnode.c
|
||||
SRCS+= callb.c
|
||||
SRCS+= list.c
|
||||
SRCS+= nvpair_alloc_system.c
|
||||
SRCS+= taskq.c
|
||||
|
||||
.PATH: ${SUNW}/uts/common/zmod
|
||||
SRCS+= adler32.c
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <sys/_task.h>
|
||||
|
||||
struct taskqueue;
|
||||
struct thread;
|
||||
|
||||
/*
|
||||
* A notification callback function which is called from
|
||||
@ -60,6 +61,7 @@ void taskqueue_free(struct taskqueue *queue);
|
||||
void taskqueue_run(struct taskqueue *queue);
|
||||
void taskqueue_block(struct taskqueue *queue);
|
||||
void taskqueue_unblock(struct taskqueue *queue);
|
||||
int taskqueue_member(struct taskqueue *queue, struct thread *td);
|
||||
|
||||
/*
|
||||
* Functions for dedicated thread taskqueues
|
||||
|
Loading…
x
Reference in New Issue
Block a user