From f18fd724312b3ee29a41b0333b3af898db20d805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Sat, 17 Dec 2022 18:04:37 -0800 Subject: [PATCH] affinity: remove darwin implementation and make it no-op It seems it is not possible to actually set affinity on macOS so we make it a no-op and make all CPU cores available https://developer.apple.com/forums/thread/44002 --- .gitignore | 1 + Makefile.am | 28 ++-- configure.ac | 3 - extensions/darwin/affinity.c | 153 ------------------ extensions/generic/affinity.c | 4 - fibers/affinity-darwin.scm | 37 +++++ fibers/{affinity.scm => affinity-generic.scm} | 13 +- 7 files changed, 53 insertions(+), 186 deletions(-) delete mode 100644 extensions/darwin/affinity.c delete mode 100644 extensions/generic/affinity.c create mode 100644 fibers/affinity-darwin.scm rename fibers/{affinity.scm => affinity-generic.scm} (68%) diff --git a/.gitignore b/.gitignore index c21e212..43a4deb 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ build/ /build-aux/depcomp /build-aux/texinfo.tex /fibers.info +/fibers/affinity.scm /fibers/config.scm /fibers/posix-clocks.scm /fibers/events-impl.scm diff --git a/Makefile.am b/Makefile.am index a604562..c38c987 100644 --- a/Makefile.am +++ b/Makefile.am @@ -28,7 +28,6 @@ info_TEXINFOS=fibers.texi SOURCES = \ fibers.scm \ - fibers/affinity.scm \ fibers/channels.scm \ fibers/conditions.scm \ fibers/config.scm \ @@ -40,7 +39,6 @@ SOURCES = \ fibers/nameset.scm \ fibers/operations.scm \ fibers/psq.scm \ - fibers/posix-clocks.scm \ fibers/repl.scm \ fibers/scheduler.scm \ fibers/stack.scm \ @@ -49,9 +47,10 @@ SOURCES = \ web/server/fibers.scm BUILT_SOURCES = \ + fibers/affinity.scm \ fibers/config.scm \ - fibers/posix-clocks.scm \ - fibers/events-impl.scm + fibers/events-impl.scm \ + fibers/posix-clocks.scm extlibdir = $(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/extensions AM_CFLAGS = -I$(srcdir) $(WARN_CFLAGS) $(DEBUG_CFLAGS) @@ -81,13 +80,6 @@ fibers/events-impl.scm: Makefile fibers/epoll.scm endif endif -if ! GUILE_HAVE_AFFINITY -extlib_LTLIBRARIES += fibers-affinity.la -fibers_affinity_la_SOURCES = extensions/$(PLATFORM)/affinity.c -fibers_affinity_la_CFLAGS = $(AM_CFLAGS) $(GUILE_CFLAGS) -Iextensions -fibers_affinity_la_LDFLAGS = -module -no-undefined $(GUILE_LDFLAGS) -endif - if ! HAVE_CLOCK_NANOSLEEP extlib_LTLIBRARIES += fibers-clocks.la fibers_clocks_la_SOURCES = extensions/$(PLATFORM)/clock-nanosleep.c @@ -100,10 +92,17 @@ fibers/config.scm: Makefile fibers/config.scm.in sed -e "s|@extlibdir\@|$(extlibdir)|" \ $(srcdir)/fibers/config.scm.in > fibers/config.scm +fibers/affinity.scm: Makefile fibers/affinity-$(PLATFORM).scm + cp -f $(abs_top_srcdir)/fibers/affinity-$(PLATFORM).scm $(abs_top_builddir)/fibers/affinity.scm + fibers/posix-clocks.scm: Makefile fibers/posix-clocks-$(PLATFORM).scm cp -f $(abs_top_srcdir)/fibers/posix-clocks-$(PLATFORM).scm $(abs_top_builddir)/fibers/posix-clocks.scm -CLEANFILES += fibers/config.scm fibers/posix-clocks.scm fibers/events-impl.scm +CLEANFILES += \ + fibers/affinity.scm \ + fibers/config.scm \ + fibers/events-impl.scm \ + fibers/posix-clocks.scm TESTS = \ tests/basic.scm \ @@ -136,6 +135,8 @@ EXTRA_DIST += \ fibers/config.scm.in \ fibers/epoll.scm \ fibers/libevent.scm \ + fibers/affinity-darwin.scm \ + fibers/affinity-generic.scm \ fibers/posix-clocks-darwin.scm \ fibers/posix-clocks-generic.scm \ examples @@ -144,7 +145,6 @@ EXTRA_DIST += \ EXTRA_DIST += \ extensions/epoll.c \ extensions/libevent.c \ - extensions/darwin/affinity.c \ + extensions/clock-nanosleep.h \ extensions/darwin/clock-nanosleep.c \ - extensions/generic/affinity.c \ extensions/generic/clock-nanosleep.c diff --git a/configure.ac b/configure.ac index d6aa9a1..537c271 100644 --- a/configure.ac +++ b/configure.ac @@ -53,9 +53,6 @@ AC_ARG_ENABLE([epoll], AS_HELP_STRING([--disable-epoll],[Disable epoll support]) AC_CHECK_FUNCS(epoll_wait) AM_CONDITIONAL([HAVE_EPOLL_WAIT], [test "x$ac_cv_func_epoll_wait" = "xyes"]) -GUILE_CHECK([GUILE_HAVE_AFFINITY], (exit (or (defined? 'setaffinity) 2))) -AM_CONDITIONAL([GUILE_HAVE_AFFINITY], [test "x$GUILE_HAVE_AFFINITY" = "x0"]) - AC_CHECK_FUNCS(clock_nanosleep) AM_CONDITIONAL([HAVE_CLOCK_NANOSLEEP], [test "x$ac_cv_func_clock_nanosleep" = "xyes"]) diff --git a/extensions/darwin/affinity.c b/extensions/darwin/affinity.c deleted file mode 100644 index cea3b07..0000000 --- a/extensions/darwin/affinity.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -/* - * Custom implementation of the getaffinty and setffinity scheme procedures - * for Mac OSX taken from: - * http://www.hybridkernel.com/2015/01/18/binding_threads_to_cores_osx.html - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define SYSCTL_CORE_COUNT "machdep.cpu.core_count" - -typedef struct cpu_set -{ - uint32_t count; -} cpu_set_t; - -static inline void -CPU_ZERO (cpu_set_t *cs) { cs->count = 0; } - -static inline void -CPU_SET (int num, cpu_set_t *cs) { cs->count |= (1 << num); } - -static inline int -CPU_ISSET (int num, cpu_set_t *cs) { return (cs->count & (1 << num)); } - -static int sched_getaffinity(size_t cpu_size, cpu_set_t *cpu_set) -{ - int32_t core_count = 0; - size_t len = sizeof (core_count); - // sysctlbyname() sets global errno if an error is returned. - int ret = sysctlbyname (SYSCTL_CORE_COUNT, &core_count, &len, 0, 0); - - if (ret) - return -1; - - cpu_set->count = 0; - for (int i = 0; i < core_count; i++) - { - cpu_set->count |= (1 << i); - } - - return 0; -} - -static int pthread_setaffinity_np (size_t cpu_size, cpu_set_t *cpu_set) -{ - thread_port_t mach_thread; - int core = 0; - - pthread_t thread = pthread_self(); - - for(core = 0; core < 8 * cpu_size; core++) - { - if (CPU_ISSET(core, cpu_set)) - { - break; - } - } - - thread_affinity_policy_data_t policy = {core}; - mach_thread = pthread_mach_thread_np(thread); - thread_policy_set (mach_thread, THREAD_AFFINITY_POLICY, - (thread_policy_t) &policy, 1); - - return 0; -} - -// We are currently only interested in the current thread, so we are ignoring -// the id (since currently we are always passing 0, which means the running -// thread). -static SCM scm_primitive_getaffinity (SCM id) -#define FUNC_NAME "getaffinity" -{ - cpu_set_t cs; - CPU_ZERO(&cs); - size_t cpu_size = sizeof(cs); - - int ret = sched_getaffinity (cpu_size, &cs); - - if (ret) - SCM_SYSERROR; - - SCM bv = scm_c_make_bitvector (cpu_size, scm_from_int (0)); - - for (int core = 0; core < cpu_size; core++) - { - if(CPU_ISSET(core, &cs)) - { - scm_c_bitvector_set_bit_x (bv, core); - } - } - - return bv; -} -#undef FUNC_NAME - -// We are currently only interested in the current thread, so we are ignoring -// the id (since currently we are always passing 0, which means the running -// thread). -static SCM scm_primitive_setaffinity (SCM id, SCM mask) -#define FUNC_NAME "getaffinity" -{ - cpu_set_t cs; - CPU_ZERO(&cs); - - int num; - for (size_t i = 0; i < scm_c_bitvector_length (mask); i++) - { - num = scm_c_bitvector_bit_is_set (mask, i); - CPU_SET (num, &cs); - } - - int ret = pthread_setaffinity_np (sizeof (cpu_set_t), &cs); - - if (ret) - SCM_SYSERROR; - - return SCM_UNSPECIFIED; -} -#undef FUNC_NAME - -void init_fibers_affinity (void) -{ - scm_c_define_gsubr ("getaffinity", 1, 0, 0, scm_primitive_getaffinity); - scm_c_define_gsubr ("setaffinity", 2, 0, 0, scm_primitive_setaffinity); -} - -/* - Local Variables: - c-file-style: "gnu" - End: -*/ diff --git a/extensions/generic/affinity.c b/extensions/generic/affinity.c deleted file mode 100644 index 8e34be7..0000000 --- a/extensions/generic/affinity.c +++ /dev/null @@ -1,4 +0,0 @@ -// Generic no-op implementation for setaffinity/getaffinity assuming they are -// provided by Guile. - -// This is just a placeholder for "make distcheck". diff --git a/fibers/affinity-darwin.scm b/fibers/affinity-darwin.scm new file mode 100644 index 0000000..234ed22 --- /dev/null +++ b/fibers/affinity-darwin.scm @@ -0,0 +1,37 @@ +;; CPU affinity (Darwin) + +;;;; Copyright (C) 2022 Aleix Conchillo FlaquƩ +;;;; +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public License +;;;; along with this program. If not, see . + +;;; Guile defines setaffinity and getaffinity in some systems (e.g. Linux). For +;;; those systems where those procedures are not available there should be a +;;; Fibers' specific implementation available through the fibers-affinity +;;; library. + +(define-module (fibers affinity) + #:use-module (ice-9 threads) + #:export (getaffinity* setaffinity*)) + +;; +;; It seems it is not possible to link a thread to a specific core on +;; macOS. See, for example: https://developer.apple.com/forums/thread/44002. +;; +;; So for now getaffinity/setaffinity are no-ops. +;; + +(define (getaffinity* pid) + (make-bitvector (current-processor-count) 1)) + +(define (setaffinity* pid affinity) *unspecified*) diff --git a/fibers/affinity.scm b/fibers/affinity-generic.scm similarity index 68% rename from fibers/affinity.scm rename to fibers/affinity-generic.scm index f3f1b7e..d757570 100644 --- a/fibers/affinity.scm +++ b/fibers/affinity-generic.scm @@ -25,17 +25,6 @@ #:use-module (fibers config) #:export (getaffinity* setaffinity*)) -(eval-when (eval load compile) - (unless (defined? 'getaffinity) - ;; When cross-compiling, the cross-compiled 'fibers-affinity.so' cannot be - ;; loaded by the 'guild compile' process; skip it. - (unless (getenv "FIBERS_CROSS_COMPILING") - (catch #t - (lambda () - (dynamic-call "init_fibers_affinity" (dynamic-link (extension-library "fibers-affinity")))) - (lambda _ (error "Ooops, getaffinity/setaffinity are not available in this platform and we were \ -unable to load fibers-affinity extension.")))))) - -;; getaffinity/setaffinity should be loaded at this point. +;; getaffinity/setaffinity should be defined in Guile (define getaffinity* (if (defined? 'getaffinity) getaffinity)) (define setaffinity* (if (defined? 'setaffinity) setaffinity))