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.
This commit is contained in:
Mark Geisert 2019-08-04 15:45:46 -07:00 committed by Corinna Vinschen
parent 654398db84
commit 362b98b49a
3 changed files with 64 additions and 10 deletions

View File

@ -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

View File

@ -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.

View File

@ -29,15 +29,9 @@ If a SA_SIGINFO signal handler changes the ucontext_t pointed to by the
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>