1 /* $NetBSD: thread.c,v 1.2 2024/02/21 22:52:29 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #if defined(HAVE_SCHED_H) 19 #include <sched.h> 20 #endif /* if defined(HAVE_SCHED_H) */ 21 22 #if defined(HAVE_CPUSET_H) 23 #include <sys/cpuset.h> 24 #include <sys/param.h> 25 #endif /* if defined(HAVE_CPUSET_H) */ 26 27 #if defined(HAVE_SYS_PROCSET_H) 28 #include <sys/processor.h> 29 #include <sys/procset.h> 30 #include <sys/types.h> 31 #endif /* if defined(HAVE_SYS_PROCSET_H) */ 32 33 #include <isc/thread.h> 34 #include <isc/util.h> 35 36 #include "trampoline_p.h" 37 38 #ifndef THREAD_MINSTACKSIZE 39 #define THREAD_MINSTACKSIZE (1024U * 1024) 40 #endif /* ifndef THREAD_MINSTACKSIZE */ 41 42 void 43 isc_thread_create(isc_threadfunc_t func, isc_threadarg_t arg, 44 isc_thread_t *thread) { 45 pthread_attr_t attr; 46 isc__trampoline_t *trampoline_arg; 47 48 trampoline_arg = isc__trampoline_get(func, arg); 49 50 #if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ 51 defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) 52 size_t stacksize; 53 #endif /* if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ 54 * defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) */ 55 int ret; 56 57 pthread_attr_init(&attr); 58 59 #if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ 60 defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) 61 ret = pthread_attr_getstacksize(&attr, &stacksize); 62 if (ret != 0) { 63 FATAL_SYSERROR(ret, "pthread_attr_getstacksize()"); 64 } 65 66 if (stacksize < THREAD_MINSTACKSIZE) { 67 ret = pthread_attr_setstacksize(&attr, THREAD_MINSTACKSIZE); 68 if (ret != 0) { 69 FATAL_SYSERROR(ret, "pthread_attr_setstacksize()"); 70 } 71 } 72 #endif /* if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ 73 * defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) */ 74 75 ret = pthread_create(thread, &attr, isc__trampoline_run, 76 trampoline_arg); 77 if (ret != 0) { 78 FATAL_SYSERROR(ret, "pthread_create()"); 79 } 80 81 pthread_attr_destroy(&attr); 82 83 return; 84 } 85 86 void 87 isc_thread_join(isc_thread_t thread, isc_threadresult_t *result) { 88 int ret = pthread_join(thread, result); 89 if (ret != 0) { 90 FATAL_SYSERROR(ret, "pthread_join()"); 91 } 92 } 93 94 void 95 isc_thread_setname(isc_thread_t thread, const char *name) { 96 #if defined(HAVE_PTHREAD_SETNAME_NP) && !defined(__APPLE__) 97 /* 98 * macOS has pthread_setname_np but only works on the 99 * current thread so it's not used here 100 */ 101 #if defined(__NetBSD__) 102 (void)pthread_setname_np(thread, name, NULL); 103 #else /* if defined(__NetBSD__) */ 104 (void)pthread_setname_np(thread, name); 105 #endif /* if defined(__NetBSD__) */ 106 #elif defined(HAVE_PTHREAD_SET_NAME_NP) 107 (void)pthread_set_name_np(thread, name); 108 #else /* if defined(HAVE_PTHREAD_SETNAME_NP) && !defined(__APPLE__) */ 109 UNUSED(thread); 110 UNUSED(name); 111 #endif /* if defined(HAVE_PTHREAD_SETNAME_NP) && !defined(__APPLE__) */ 112 } 113 114 void 115 isc_thread_yield(void) { 116 #if defined(HAVE_SCHED_YIELD) 117 sched_yield(); 118 #elif defined(HAVE_PTHREAD_YIELD) 119 pthread_yield(); 120 #elif defined(HAVE_PTHREAD_YIELD_NP) 121 pthread_yield_np(); 122 #endif /* if defined(HAVE_SCHED_YIELD) */ 123 } 124