https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=362b98b49af53496f07c36a8b946a3be584a370e
commit 362b98b49af53496f07c36a8b946a3be584a370e Author: Mark Geisert <m...@maxrnd.com> Date: Sun Aug 4 15:45:46 2019 -0700 Cygwin: Implement CPU_SET(3) macros This patch supplies an implementation of the CPU_SET(3) processor affinity macros as documented on the relevant Linux man page. There is a mostly superset implementation of cpusets under newlib's libc/sys/RTEMS/include/sys that has Linux and FreeBSD compatibility and is built on top of FreeBSD bitsets. This Cygwin implementation and the RTEMS one could be combined if desired at some future point. Diff: --- winsup/cygwin/include/sys/cpuset.h | 64 ++++++++++++++++++++++++++++++++++++-- winsup/cygwin/release/3.1.0 | 2 +- winsup/doc/new-features.xml | 8 +---- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/winsup/cygwin/include/sys/cpuset.h b/winsup/cygwin/include/sys/cpuset.h index 4857b87..2056f6a 100644 --- a/winsup/cygwin/include/sys/cpuset.h +++ b/winsup/cygwin/include/sys/cpuset.h @@ -18,8 +18,8 @@ typedef __SIZE_TYPE__ __cpu_mask; #define __NCPUBITS (8 * sizeof (__cpu_mask)) // max size of processor group #define __CPU_GROUPMAX (__CPU_SETSIZE / __NCPUBITS) // maximum group number -#define __CPUELT(cpu) ((cpu) / __NCPUBITS) -#define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS)) +#define __CPUELT(cpu) ((cpu) / __NCPUBITS) +#define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS)) typedef struct { @@ -28,6 +28,66 @@ typedef struct int __sched_getaffinity_sys (pid_t, size_t, cpu_set_t *); +/* These macros alloc or free dynamically-sized cpu sets of size 'num' cpus. + Allocations are padded such that full-word operations can be done easily. */ +#define CPU_ALLOC_SIZE(num) ((num+__NCPUBITS-1) / __NCPUBITS) * sizeof (__cpu_mask) +#define CPU_ALLOC(num) __builtin_malloc (CPU_ALLOC_SIZE(num)) +#define CPU_FREE(set) __builtin_free (set) + +/* These _S macros operate on dynamically-sized cpu sets of size 'siz' bytes */ +#define CPU_ZERO_S(siz, set) __builtin_memset (set, 0, siz) + +#define CPU_SET_S(cpu,siz,set) \ + if (cpu < 8 * siz) \ + (set)->__bits[__CPUELT(cpu)] |= __CPUMASK(cpu); + +#define CPU_CLR_S(cpu,siz,set) \ + if (cpu < 8 * siz) \ + (set)->__bits[__CPUELT(cpu)] &= ~(__CPUMASK(cpu)); + +#define CPU_ISSET_S(cpu,siz,set) \ + ({int res = 0; \ + if (cpu < 8 * siz) \ + res = !!((set)->__bits[__CPUELT(cpu)] & __CPUMASK(cpu)); \ + res;}) + +#define CPU_COUNT_S(siz, set) \ + ({int tot = 0;\ + for (int i = 0; i < siz / sizeof (__cpu_mask); i++) \ + tot += __builtin_popcountl ((set)->__bits[i]); \ + tot;}) + +#define CPU_AND_S(siz, dst, src1, src2) \ + for (int i = 0; i < siz / sizeof (__cpu_mask); i++) \ + (dst)->__bits[i] = (src1)->__bits[i] & (src2)->__bits[i]; + +#define CPU_OR_S(siz, dst, src1, src2) \ + for (int i = 0; i < siz / sizeof (__cpu_mask); i++) \ + (dst)->__bits[i] = (src1)->__bits[i] | (src2)->__bits[i]; + +#define CPU_XOR_S(siz, dst, src1, src2) \ + for (int i = 0; i < siz / sizeof (__cpu_mask); i++) \ + (dst)->__bits[i] = (src1)->__bits[i] ^ (src2)->__bits[i]; + +#define CPU_EQUAL_S(siz, src1, src2) \ + ({int res = 1; \ + for (int i = 0; res && i < siz / sizeof (__cpu_mask); i++) \ + res &= (src1)->__bits[i] == (src2)->__bits[i]; \ + res;}) + +/* These macros operate on fixed-size cpu sets of size __CPU_SETSIZE cpus */ +#define CPU_ZERO(set) CPU_ZERO_S(sizeof (cpu_set_t), set) + +#define CPU_SET(cpu, set) CPU_SET_S(cpu, sizeof (cpu_set_t), set) +#define CPU_CLR(cpu, set) CPU_CLR_S(cpu, sizeof (cpu_set_t), set) +#define CPU_ISSET(cpu, set) CPU_ISSET_S(cpu, sizeof (cpu_set_t), set) + +#define CPU_COUNT(set) CPU_COUNT_S(sizeof (cpu_set_t), set) +#define CPU_AND(dst, src1, src2) CPU_AND_S(sizeof (cpu_set_t), dst, src1, src2) +#define CPU_OR(dst, src1, src2) CPU_OR_S(sizeof (cpu_set_t), dst, src1, src2) +#define CPU_XOR(dst, src1, src2) CPU_XOR_S(sizeof (cpu_set_t), dst, src1, src2) +#define CPU_EQUAL(src1, src2) CPU_EQUAL_S(sizeof (cpu_set_t), src1, src2) + #ifdef __cplusplus } #endif diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index d5d3129..2c1e8d2 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -6,7 +6,7 @@ What's new: which uses the nearest color from 16 system colors. - New APIs: sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, - pthread_setaffinity_np. + pthread_setaffinity_np, plus CPU_SET macros. - New APIs: dbm_clearerr, dbm_close, dbm_delete, dbm_dirfno, dbm_error, dbm_fetch, dbm_firstkey, dbm_nextkey, dbm_open, dbm_store. diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index a5dcfb5..5fee581 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -30,14 +30,8 @@ third parameter, follow it after returning from the handler. </para></listitem> <listitem><para> -Support for getting and setting process and thread affinities. New APIs: -sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, -pthread_setaffinity_np. -</para></listitem> - -<listitem><para> New APIs: sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, -pthread_setaffinity_np. +pthread_setaffinity_np, plus CPU_SET macros. </para></listitem> <listitem><para>