diff --git a/config.h.in b/config.h.in index 08e2f9c483..8fccd17b65 100644 --- a/config.h.in +++ b/config.h.in @@ -75,6 +75,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_CMOCKA_H +/* Define to 1 if you have the `cpuset_setaffinty' function. */ +#undef HAVE_CPUSET_SETAFFINITY + /* Define to 1 if you have the `CRYPTO_zalloc' function. */ #undef HAVE_CRYPTO_ZALLOC @@ -285,6 +288,9 @@ /* define if OpenSSL supports Ed25519 */ #undef HAVE_OPENSSL_ED25519 +/* Define to 1 if you have the `processor_bind' function. */ +#undef HAVE_PROCESSOR_BIND + /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD @@ -303,6 +309,9 @@ /* Have PTHREAD_PRIO_INHERIT. */ #undef HAVE_PTHREAD_PRIO_INHERIT +/* Define to 1 if you have the `pthread_setaffinity_np' function. */ +#undef HAVE_PTHREAD_SETAFFINITY_NP + /* Define to 1 if you have the `pthread_setname_np' function. */ #undef HAVE_PTHREAD_SETNAME_NP @@ -333,6 +342,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SCHED_H +/* Define to 1 if you have the `sched_setaffinity' function. */ +#undef HAVE_SCHED_SETAFFINITY + /* Define to 1 if you have the `sched_yield' function. */ #undef HAVE_SCHED_YIELD @@ -387,6 +399,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CAPABILITY_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_CPUSET_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DEVPOLL_H @@ -396,6 +411,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PRCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PROCSET_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H diff --git a/configure b/configure index 6ed2702470..b6a780f78f 100755 --- a/configure +++ b/configure @@ -844,6 +844,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -1003,6 +1004,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1255,6 +1257,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1392,7 +1403,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1545,6 +1556,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -15235,6 +15247,43 @@ fi done +for ac_header in sys/cpuset.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/cpuset.h" "ac_cv_header_sys_cpuset_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_cpuset_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_CPUSET_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/procset.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/procset.h" "ac_cv_header_sys_procset_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_procset_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_PROCSET_H 1 +_ACEOF + +fi + +done + +for ac_func in pthread_setaffinity_np cpuset_setaffinity processor_bind sched_setaffinity +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + # Look for functions relating to thread naming for ac_func in pthread_setname_np pthread_set_name_np do : diff --git a/configure.ac b/configure.ac index 941053b8a5..2b27558a6e 100644 --- a/configure.ac +++ b/configure.ac @@ -701,6 +701,10 @@ AC_CHECK_HEADERS([sched.h]) AC_SEARCH_LIBS([sched_yield],[rt]) AC_CHECK_FUNCS([sched_yield pthread_yield pthread_yield_np]) +AC_CHECK_HEADERS([sys/cpuset.h]) +AC_CHECK_HEADERS([sys/procset.h]) +AC_CHECK_FUNCS([pthread_setaffinity_np cpuset_setaffinity processor_bind sched_setaffinity]) + # Look for functions relating to thread naming AC_CHECK_FUNCS([pthread_setname_np pthread_set_name_np]) AC_CHECK_HEADERS([pthread_np.h], [], [], [#include ]) diff --git a/lib/isc/pthreads/include/isc/thread.h b/lib/isc/pthreads/include/isc/thread.h index 798af338ac..6d96950028 100644 --- a/lib/isc/pthreads/include/isc/thread.h +++ b/lib/isc/pthreads/include/isc/thread.h @@ -44,6 +44,9 @@ isc_thread_yield(void); void isc_thread_setname(isc_thread_t thread, const char *name); +isc_result_t +isc_thread_setaffinity(int cpu); + /* XXX We could do fancier error handling... */ #define isc_thread_join(t, rp) \ diff --git a/lib/isc/pthreads/thread.c b/lib/isc/pthreads/thread.c index ba7ae52daa..f8029e26ed 100644 --- a/lib/isc/pthreads/thread.c +++ b/lib/isc/pthreads/thread.c @@ -18,6 +18,17 @@ #include #endif +#if defined(HAVE_CPUSET_H) +#include +#include +#endif + +#if defined(HAVE_SYS_PROCESET_H) +#include +#include +#include +#endif + #include #include @@ -91,3 +102,31 @@ isc_thread_yield(void) { pthread_yield_np(); #endif } + +isc_result_t +isc_thread_setaffinity(int cpu) { +#if defined(HAVE_CPUSET_SETAFFINITY) + cpuset_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(cpu, &cpuset); + if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, + &cpuset, sizeof(cpuset)) != 0) { + return (ISC_R_FAILURE); + } +#elif defined(HAVE_PTHREAD_SETAFFINITY_NP) + cpu_set_t set; + CPU_ZERO(&set); + CPU_SET(cpu, &set); + if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), + &set) != 0) { + return (ISC_R_FAILURE); + } +#elif defined(HAVE_PROCESSOR_BIND) + if (processor_bind(P_LWPID, P_MYID, cpu, NULL) != 0) { + return (ISC_R_FAILURE); + } +#else + UNUSED(cpu); +#endif + return (ISC_R_SUCCESS); +} diff --git a/lib/isc/win32/include/isc/thread.h b/lib/isc/win32/include/isc/thread.h index be1343afcb..25b83af073 100644 --- a/lib/isc/win32/include/isc/thread.h +++ b/lib/isc/win32/include/isc/thread.h @@ -79,6 +79,9 @@ isc_thread_setconcurrency(unsigned int level); void isc_thread_setname(isc_thread_t, const char *); +isc_result_t +isc_thread_setaffinity(int cpu); + int isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *)); diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 88faffb193..c468a89fe2 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -609,6 +609,7 @@ isc_thread_key_create isc_thread_key_delete isc_thread_key_getspecific isc_thread_key_setspecific +isc_thread_setaffinity isc_thread_setconcurrency isc_thread_setname isc_time_add diff --git a/lib/isc/win32/thread.c b/lib/isc/win32/thread.c index ebc2f2936f..7c147164d2 100644 --- a/lib/isc/win32/thread.c +++ b/lib/isc/win32/thread.c @@ -66,6 +66,12 @@ isc_thread_setname(isc_thread_t thread, const char *name) { UNUSED(name); } +isc_result_t +isc_thread_setaffinity(int cpu) { + /* no-op on Windows for now */ + return (ISC_R_SUCCESS); +} + void * isc_thread_key_getspecific(isc_thread_key_t key) { return(TlsGetValue(key));