Path: blob/main/sys/contrib/openzfs/lib/libspl/thread.c
96339 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* Common Development and Distribution License (the "License").6* You may not use this file except in compliance with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or https://opensource.org/licenses/CDDL-1.0.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/21/*22* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.23* Copyright (c) 2012, 2018 by Delphix. All rights reserved.24* Copyright (c) 2016 Actifio, Inc. All rights reserved.25* Copyright (c) 2025, Klara, Inc.26*/2728#include <assert.h>29#include <pthread.h>30#include <string.h>31#include <sys/thread.h>3233/* this only exists to have its address taken */34void p0(void) {}3536/*37* =========================================================================38* threads39* =========================================================================40*41* TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While42* TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for43* the expected stack depth while small enough to avoid exhausting address44* space with high thread counts.45*/46#define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768)47#define TS_STACK_MAX (256 * 1024)4849struct zk_thread_wrapper {50void (*func)(void *);51void *arg;52};5354static void *55zk_thread_wrapper(void *arg)56{57struct zk_thread_wrapper ztw;58memcpy(&ztw, arg, sizeof (ztw));59free(arg);60ztw.func(ztw.arg);61return (NULL);62}6364kthread_t *65zk_thread_create(const char *name, void (*func)(void *), void *arg,66size_t stksize, int state)67{68pthread_attr_t attr;69pthread_t tid;70char *stkstr;71struct zk_thread_wrapper *ztw;72int detachstate = PTHREAD_CREATE_DETACHED;7374VERIFY0(pthread_attr_init(&attr));7576if (state & TS_JOINABLE)77detachstate = PTHREAD_CREATE_JOINABLE;7879VERIFY0(pthread_attr_setdetachstate(&attr, detachstate));8081/*82* We allow the default stack size in user space to be specified by83* setting the ZFS_STACK_SIZE environment variable. This allows us84* the convenience of observing and debugging stack overruns in85* user space. Explicitly specified stack sizes will be honored.86* The usage of ZFS_STACK_SIZE is discussed further in the87* ENVIRONMENT VARIABLES sections of the ztest(1) man page.88*/89if (stksize == 0) {90stkstr = getenv("ZFS_STACK_SIZE");9192if (stkstr == NULL)93stksize = TS_STACK_MAX;94else95stksize = MAX(atoi(stkstr), TS_STACK_MIN);96}9798VERIFY3S(stksize, >, 0);99stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE);100101/*102* If this ever fails, it may be because the stack size is not a103* multiple of system page size.104*/105VERIFY0(pthread_attr_setstacksize(&attr, stksize));106VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));107108VERIFY(ztw = malloc(sizeof (*ztw)));109ztw->func = func;110ztw->arg = arg;111VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw));112VERIFY0(pthread_attr_destroy(&attr));113114pthread_setname_np(tid, name);115116return ((void *)(uintptr_t)tid);117}118119120