summaryrefslogtreecommitdiffstats
path: root/zfs/lib/libdmu-ctl/dctl_thrpool.c
diff options
context:
space:
mode:
Diffstat (limited to 'zfs/lib/libdmu-ctl/dctl_thrpool.c')
-rw-r--r--zfs/lib/libdmu-ctl/dctl_thrpool.c253
1 files changed, 0 insertions, 253 deletions
diff --git a/zfs/lib/libdmu-ctl/dctl_thrpool.c b/zfs/lib/libdmu-ctl/dctl_thrpool.c
deleted file mode 100644
index 7b2f9b4c2..000000000
--- a/zfs/lib/libdmu-ctl/dctl_thrpool.c
+++ /dev/null
@@ -1,253 +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
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <time.h>
-#include <pthread.h>
-#include <errno.h>
-#include <sys/list.h>
-#include <sys/debug.h>
-
-#include <sys/dmu_ctl.h>
-#include <sys/dmu_ctl_impl.h>
-
-static dctl_thr_info_t thr_pool = {
- .dti_mtx = PTHREAD_MUTEX_INITIALIZER
-};
-
-/*
- * Create n threads.
- * Callers must acquire thr_pool.dti_mtx first.
- */
-static int dctl_thr_create(int n)
-{
- dctl_thr_info_t *p = &thr_pool;
- int error;
-
- for (int i = 0; i < n; i++) {
- wthr_info_t *thr = malloc(sizeof(wthr_info_t));
- if (thr == NULL)
- return ENOMEM;
-
- thr->wthr_exit = B_FALSE;
- thr->wthr_free = B_TRUE;
-
- error = pthread_create(&thr->wthr_id, NULL, p->dti_thr_func,
- thr);
- if (error) {
- free(thr);
- return error;
- }
-
- p->dti_free++;
-
- list_insert_tail(&p->dti_list, thr);
- }
- return 0;
-}
-
-/*
- * Mark the thread as dead.
- * Must be called right before exiting the main thread function.
- */
-void dctl_thr_die(wthr_info_t *thr)
-{
- dctl_thr_info_t *p = &thr_pool;
-
- thr->wthr_exit = B_TRUE;
- dctl_thr_rebalance(thr, B_FALSE);
-
- pthread_mutex_lock(&p->dti_mtx);
-
- list_remove(&p->dti_list, thr);
- list_insert_tail(&p->dti_join_list, thr);
-
- pthread_mutex_unlock(&p->dti_mtx);
-}
-
-/*
- * Clean-up dead threads.
- */
-void dctl_thr_join()
-{
- dctl_thr_info_t *p = &thr_pool;
- wthr_info_t *thr;
-
- pthread_mutex_lock(&p->dti_mtx);
-
- while ((thr = list_head(&p->dti_join_list))) {
- list_remove(&p->dti_join_list, thr);
-
- ASSERT(!pthread_equal(thr->wthr_id, pthread_self()));
-
- /*
- * This should not block because all the threads
- * on this list should have died already.
- *
- * pthread_join() can only return an error if
- * we made a programming mistake.
- */
- VERIFY(pthread_join(thr->wthr_id, NULL) == 0);
-
- ASSERT(thr->wthr_exit);
- ASSERT(!thr->wthr_free);
-
- free(thr);
- }
-
- pthread_mutex_unlock(&p->dti_mtx);
-}
-
-/*
- * Adjust the number of free threads in the pool and the thread status.
- *
- * Callers must acquire thr_pool.dti_mtx first.
- */
-static void dctl_thr_adjust_free(wthr_info_t *thr, boolean_t set_free)
-{
- dctl_thr_info_t *p = &thr_pool;
-
- ASSERT(p->dti_free >= 0);
-
- if (!thr->wthr_free && set_free)
- p->dti_free++;
- else if (thr->wthr_free && !set_free)
- p->dti_free--;
-
- ASSERT(p->dti_free >= 0);
-
- thr->wthr_free = set_free;
-}
-
-/*
- * Rebalance threads. Also adjusts the free status of the thread.
- * Will set the thread exit flag if the number of free threads is above
- * the limit.
- */
-void dctl_thr_rebalance(wthr_info_t *thr, boolean_t set_free)
-{
- dctl_thr_info_t *p = &thr_pool;
-
- pthread_mutex_lock(&p->dti_mtx);
-
- if (p->dti_exit || p->dti_free > p->dti_max_free)
- thr->wthr_exit = B_TRUE;
-
- if (thr->wthr_exit)
- set_free = B_FALSE;
-
- dctl_thr_adjust_free(thr, set_free);
-
- if (!p->dti_exit && p->dti_free == 0)
- dctl_thr_create(1);
-
- pthread_mutex_unlock(&p->dti_mtx);
-}
-
-/*
- * Stop the thread pool.
- *
- * This can take a while since it actually waits for all threads to exit.
- */
-void dctl_thr_pool_stop()
-{
- dctl_thr_info_t *p = &thr_pool;
- wthr_info_t *thr;
- struct timespec ts;
-
- pthread_mutex_lock(&p->dti_mtx);
-
- ASSERT(!p->dti_exit);
- p->dti_exit = B_TRUE;
-
- /* Let's flag the threads first */
- thr = list_head(&p->dti_list);
- while (thr != NULL) {
- thr->wthr_exit = B_TRUE;
- dctl_thr_adjust_free(thr, B_FALSE);
-
- thr = list_next(&p->dti_list, thr);
- }
-
- pthread_mutex_unlock(&p->dti_mtx);
-
- /* Now let's wait for them to exit */
- ts.tv_sec = 0;
- ts.tv_nsec = 50000000; /* 50ms */
- do {
- nanosleep(&ts, NULL);
-
- pthread_mutex_lock(&p->dti_mtx);
- thr = list_head(&p->dti_list);
- pthread_mutex_unlock(&p->dti_mtx);
-
- dctl_thr_join();
- } while(thr != NULL);
-
- ASSERT(p->dti_free == 0);
-
- ASSERT(list_is_empty(&p->dti_list));
- ASSERT(list_is_empty(&p->dti_join_list));
-
- list_destroy(&p->dti_list);
- list_destroy(&p->dti_join_list);
-}
-
-/*
- * Create thread pool.
- *
- * If at least one thread creation fails, it will stop all previous
- * threads and return a non-zero value.
- */
-int dctl_thr_pool_create(int min_thr, int max_free_thr,
- thr_func_t *thr_func)
-{
- int error;
- dctl_thr_info_t *p = &thr_pool;
-
- ASSERT(p->dti_free == 0);
-
- /* Initialize global variables */
- p->dti_min = min_thr;
- p->dti_max_free = max_free_thr;
- p->dti_exit = B_FALSE;
- p->dti_thr_func = thr_func;
-
- list_create(&p->dti_list, sizeof(wthr_info_t), offsetof(wthr_info_t,
- wthr_node));
- list_create(&p->dti_join_list, sizeof(wthr_info_t),
- offsetof(wthr_info_t, wthr_node));
-
- pthread_mutex_lock(&p->dti_mtx);
- error = dctl_thr_create(min_thr);
- pthread_mutex_unlock(&p->dti_mtx);
-
- if (error)
- dctl_thr_pool_stop();
-
- return error;
-}