diff options
author | pjd <pjd@FreeBSD.org> | 2009-08-17 09:03:47 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2009-08-17 09:03:47 +0000 |
commit | fee81fb7eb14e8e534808a06b7455bab8868d3be (patch) | |
tree | 5cecd6c9f52336c4e919e1f9fa0000d39c7a5ec4 /sys/cddl/compat | |
parent | ac62a9f0337a961791a384249e07f05c5ba0400b (diff) | |
download | FreeBSD-src-fee81fb7eb14e8e534808a06b7455bab8868d3be.zip FreeBSD-src-fee81fb7eb14e8e534808a06b7455bab8868d3be.tar.gz |
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)
Diffstat (limited to 'sys/cddl/compat')
-rw-r--r-- | sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c | 135 | ||||
-rw-r--r-- | sys/cddl/compat/opensolaris/sys/taskq.h | 86 | ||||
-rw-r--r-- | sys/cddl/compat/opensolaris/sys/taskq_impl.h | 137 |
3 files changed, 135 insertions, 223 deletions
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c new file mode 100644 index 0000000..584be24 --- /dev/null +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c @@ -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); +} diff --git a/sys/cddl/compat/opensolaris/sys/taskq.h b/sys/cddl/compat/opensolaris/sys/taskq.h deleted file mode 100644 index 174018a..0000000 --- a/sys/cddl/compat/opensolaris/sys/taskq.h +++ /dev/null @@ -1,86 +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_H -#define _SYS_TASKQ_H - -#pragma ident "@(#)taskq.h 1.5 05/06/08 SMI" - -#include <sys/param.h> -#include <sys/proc.h> -#include <sys/kcondvar.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define TASKQ_NAMELEN 31 - -typedef struct taskq taskq_t; -typedef uintptr_t taskqid_t; -typedef void (task_func_t)(void *); - -/* - * Public flags for taskq_create(): bit range 0-15 - */ -#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 */ - -/* - * Flags for taskq_dispatch. TQ_SLEEP/TQ_NOSLEEP should be same as - * KM_SLEEP/KM_NOSLEEP. - */ -#define TQ_SLEEP 0x00 /* Can block for memory */ -#define TQ_NOSLEEP 0x01 /* cannot block for memory; may fail */ -#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */ -#define TQ_NOALLOC 0x04 /* cannot allocate memory; may fail */ - -#ifdef _KERNEL - -extern taskq_t *system_taskq; - -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); -extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t); -extern void nulltask(void *); -extern void taskq_destroy(taskq_t *); -extern void taskq_wait(taskq_t *); -extern void taskq_suspend(taskq_t *); -extern int taskq_suspended(taskq_t *); -extern void taskq_resume(taskq_t *); -extern int taskq_member(taskq_t *, kthread_t *); - -#endif /* _KERNEL */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_TASKQ_H */ diff --git a/sys/cddl/compat/opensolaris/sys/taskq_impl.h b/sys/cddl/compat/opensolaris/sys/taskq_impl.h deleted file mode 100644 index a9b59bb..0000000 --- a/sys/cddl/compat/opensolaris/sys/taskq_impl.h +++ /dev/null @@ -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 */ |