Home | History | Annotate | Line # | Download | only in isc
thread.c revision 1.2
      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