Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/lib/libspl/thread.c
96339 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* The contents of this file are subject to the terms of the
6
* Common Development and Distribution License (the "License").
7
* You may not use this file except in compliance with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or https://opensource.org/licenses/CDDL-1.0.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
/*
23
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
25
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
26
* Copyright (c) 2025, Klara, Inc.
27
*/
28
29
#include <assert.h>
30
#include <pthread.h>
31
#include <string.h>
32
#include <sys/thread.h>
33
34
/* this only exists to have its address taken */
35
void p0(void) {}
36
37
/*
38
* =========================================================================
39
* threads
40
* =========================================================================
41
*
42
* TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While
43
* TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for
44
* the expected stack depth while small enough to avoid exhausting address
45
* space with high thread counts.
46
*/
47
#define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768)
48
#define TS_STACK_MAX (256 * 1024)
49
50
struct zk_thread_wrapper {
51
void (*func)(void *);
52
void *arg;
53
};
54
55
static void *
56
zk_thread_wrapper(void *arg)
57
{
58
struct zk_thread_wrapper ztw;
59
memcpy(&ztw, arg, sizeof (ztw));
60
free(arg);
61
ztw.func(ztw.arg);
62
return (NULL);
63
}
64
65
kthread_t *
66
zk_thread_create(const char *name, void (*func)(void *), void *arg,
67
size_t stksize, int state)
68
{
69
pthread_attr_t attr;
70
pthread_t tid;
71
char *stkstr;
72
struct zk_thread_wrapper *ztw;
73
int detachstate = PTHREAD_CREATE_DETACHED;
74
75
VERIFY0(pthread_attr_init(&attr));
76
77
if (state & TS_JOINABLE)
78
detachstate = PTHREAD_CREATE_JOINABLE;
79
80
VERIFY0(pthread_attr_setdetachstate(&attr, detachstate));
81
82
/*
83
* We allow the default stack size in user space to be specified by
84
* setting the ZFS_STACK_SIZE environment variable. This allows us
85
* the convenience of observing and debugging stack overruns in
86
* user space. Explicitly specified stack sizes will be honored.
87
* The usage of ZFS_STACK_SIZE is discussed further in the
88
* ENVIRONMENT VARIABLES sections of the ztest(1) man page.
89
*/
90
if (stksize == 0) {
91
stkstr = getenv("ZFS_STACK_SIZE");
92
93
if (stkstr == NULL)
94
stksize = TS_STACK_MAX;
95
else
96
stksize = MAX(atoi(stkstr), TS_STACK_MIN);
97
}
98
99
VERIFY3S(stksize, >, 0);
100
stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE);
101
102
/*
103
* If this ever fails, it may be because the stack size is not a
104
* multiple of system page size.
105
*/
106
VERIFY0(pthread_attr_setstacksize(&attr, stksize));
107
VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));
108
109
VERIFY(ztw = malloc(sizeof (*ztw)));
110
ztw->func = func;
111
ztw->arg = arg;
112
VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw));
113
VERIFY0(pthread_attr_destroy(&attr));
114
115
pthread_setname_np(tid, name);
116
117
return ((void *)(uintptr_t)tid);
118
}
119
120