mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-31 11:14:09 +03:00
libspl: move thread implementation from libzpool
Sponsored-by: https://despairlabs.com/sponsor/ Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <robn@despairlabs.com> Closes #17861
This commit is contained in:
committed by
Brian Behlendorf
parent
21ae59a53b
commit
0c60920d09
@@ -25,6 +25,7 @@ libspl_la_SOURCES = \
|
|||||||
%D%/rwlock.c \
|
%D%/rwlock.c \
|
||||||
%D%/strlcat.c \
|
%D%/strlcat.c \
|
||||||
%D%/strlcpy.c \
|
%D%/strlcpy.c \
|
||||||
|
%D%/thread.c \
|
||||||
%D%/timestamp.c \
|
%D%/timestamp.c \
|
||||||
%D%/tunables.c \
|
%D%/tunables.c \
|
||||||
%D%/include/sys/list.h \
|
%D%/include/sys/list.h \
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
// SPDX-License-Identifier: CDDL-1.0
|
||||||
|
/*
|
||||||
|
* CDDL HEADER START
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the terms of the
|
||||||
|
* 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 https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
* 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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||||
|
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 2025, Klara, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/thread.h>
|
||||||
|
|
||||||
|
/* this only exists to have its address taken */
|
||||||
|
struct proc p0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =========================================================================
|
||||||
|
* threads
|
||||||
|
* =========================================================================
|
||||||
|
*
|
||||||
|
* TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While
|
||||||
|
* TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for
|
||||||
|
* the expected stack depth while small enough to avoid exhausting address
|
||||||
|
* space with high thread counts.
|
||||||
|
*/
|
||||||
|
#define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768)
|
||||||
|
#define TS_STACK_MAX (256 * 1024)
|
||||||
|
|
||||||
|
struct zk_thread_wrapper {
|
||||||
|
void (*func)(void *);
|
||||||
|
void *arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *
|
||||||
|
zk_thread_wrapper(void *arg)
|
||||||
|
{
|
||||||
|
struct zk_thread_wrapper ztw;
|
||||||
|
memcpy(&ztw, arg, sizeof (ztw));
|
||||||
|
free(arg);
|
||||||
|
ztw.func(ztw.arg);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
kthread_t *
|
||||||
|
zk_thread_create(const char *name, void (*func)(void *), void *arg,
|
||||||
|
size_t stksize, int state)
|
||||||
|
{
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_t tid;
|
||||||
|
char *stkstr;
|
||||||
|
struct zk_thread_wrapper *ztw;
|
||||||
|
int detachstate = PTHREAD_CREATE_DETACHED;
|
||||||
|
|
||||||
|
VERIFY0(pthread_attr_init(&attr));
|
||||||
|
|
||||||
|
if (state & TS_JOINABLE)
|
||||||
|
detachstate = PTHREAD_CREATE_JOINABLE;
|
||||||
|
|
||||||
|
VERIFY0(pthread_attr_setdetachstate(&attr, detachstate));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We allow the default stack size in user space to be specified by
|
||||||
|
* setting the ZFS_STACK_SIZE environment variable. This allows us
|
||||||
|
* the convenience of observing and debugging stack overruns in
|
||||||
|
* user space. Explicitly specified stack sizes will be honored.
|
||||||
|
* The usage of ZFS_STACK_SIZE is discussed further in the
|
||||||
|
* ENVIRONMENT VARIABLES sections of the ztest(1) man page.
|
||||||
|
*/
|
||||||
|
if (stksize == 0) {
|
||||||
|
stkstr = getenv("ZFS_STACK_SIZE");
|
||||||
|
|
||||||
|
if (stkstr == NULL)
|
||||||
|
stksize = TS_STACK_MAX;
|
||||||
|
else
|
||||||
|
stksize = MAX(atoi(stkstr), TS_STACK_MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
VERIFY3S(stksize, >, 0);
|
||||||
|
stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this ever fails, it may be because the stack size is not a
|
||||||
|
* multiple of system page size.
|
||||||
|
*/
|
||||||
|
VERIFY0(pthread_attr_setstacksize(&attr, stksize));
|
||||||
|
VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));
|
||||||
|
|
||||||
|
VERIFY(ztw = malloc(sizeof (*ztw)));
|
||||||
|
ztw->func = func;
|
||||||
|
ztw->arg = arg;
|
||||||
|
VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw));
|
||||||
|
VERIFY0(pthread_attr_destroy(&attr));
|
||||||
|
|
||||||
|
pthread_setname_np(tid, name);
|
||||||
|
|
||||||
|
return ((void *)(uintptr_t)tid);
|
||||||
|
}
|
||||||
@@ -63,92 +63,6 @@ struct utsname hw_utsname;
|
|||||||
/* If set, all blocks read will be copied to the specified directory. */
|
/* If set, all blocks read will be copied to the specified directory. */
|
||||||
char *vn_dumpdir = NULL;
|
char *vn_dumpdir = NULL;
|
||||||
|
|
||||||
/* this only exists to have its address taken */
|
|
||||||
struct proc p0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* =========================================================================
|
|
||||||
* threads
|
|
||||||
* =========================================================================
|
|
||||||
*
|
|
||||||
* TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While
|
|
||||||
* TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for
|
|
||||||
* the expected stack depth while small enough to avoid exhausting address
|
|
||||||
* space with high thread counts.
|
|
||||||
*/
|
|
||||||
#define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768)
|
|
||||||
#define TS_STACK_MAX (256 * 1024)
|
|
||||||
|
|
||||||
struct zk_thread_wrapper {
|
|
||||||
void (*func)(void *);
|
|
||||||
void *arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void *
|
|
||||||
zk_thread_wrapper(void *arg)
|
|
||||||
{
|
|
||||||
struct zk_thread_wrapper ztw;
|
|
||||||
memcpy(&ztw, arg, sizeof (ztw));
|
|
||||||
free(arg);
|
|
||||||
ztw.func(ztw.arg);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
kthread_t *
|
|
||||||
zk_thread_create(const char *name, void (*func)(void *), void *arg,
|
|
||||||
size_t stksize, int state)
|
|
||||||
{
|
|
||||||
pthread_attr_t attr;
|
|
||||||
pthread_t tid;
|
|
||||||
char *stkstr;
|
|
||||||
struct zk_thread_wrapper *ztw;
|
|
||||||
int detachstate = PTHREAD_CREATE_DETACHED;
|
|
||||||
|
|
||||||
VERIFY0(pthread_attr_init(&attr));
|
|
||||||
|
|
||||||
if (state & TS_JOINABLE)
|
|
||||||
detachstate = PTHREAD_CREATE_JOINABLE;
|
|
||||||
|
|
||||||
VERIFY0(pthread_attr_setdetachstate(&attr, detachstate));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We allow the default stack size in user space to be specified by
|
|
||||||
* setting the ZFS_STACK_SIZE environment variable. This allows us
|
|
||||||
* the convenience of observing and debugging stack overruns in
|
|
||||||
* user space. Explicitly specified stack sizes will be honored.
|
|
||||||
* The usage of ZFS_STACK_SIZE is discussed further in the
|
|
||||||
* ENVIRONMENT VARIABLES sections of the ztest(1) man page.
|
|
||||||
*/
|
|
||||||
if (stksize == 0) {
|
|
||||||
stkstr = getenv("ZFS_STACK_SIZE");
|
|
||||||
|
|
||||||
if (stkstr == NULL)
|
|
||||||
stksize = TS_STACK_MAX;
|
|
||||||
else
|
|
||||||
stksize = MAX(atoi(stkstr), TS_STACK_MIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
VERIFY3S(stksize, >, 0);
|
|
||||||
stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If this ever fails, it may be because the stack size is not a
|
|
||||||
* multiple of system page size.
|
|
||||||
*/
|
|
||||||
VERIFY0(pthread_attr_setstacksize(&attr, stksize));
|
|
||||||
VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));
|
|
||||||
|
|
||||||
VERIFY(ztw = malloc(sizeof (*ztw)));
|
|
||||||
ztw->func = func;
|
|
||||||
ztw->arg = arg;
|
|
||||||
VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw));
|
|
||||||
VERIFY0(pthread_attr_destroy(&attr));
|
|
||||||
|
|
||||||
pthread_setname_np(tid, name);
|
|
||||||
|
|
||||||
return ((void *)(uintptr_t)tid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =========================================================================
|
* =========================================================================
|
||||||
* kstats
|
* kstats
|
||||||
|
|||||||
Reference in New Issue
Block a user