gnu: add pthread_setaffinity_np()/pthread_getaffinity_np()
* also sched_setaffinity/sched_getaffinity() added. * add a test Change-Id: Id8c308788f6364f5340b4991def2fbb9a05da728 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7675 Reviewed-by: waddlesplash <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
f7a85eea15
commit
c5a740cdb2
@@ -12,6 +12,9 @@
|
|||||||
#ifdef _GNU_SOURCE
|
#ifdef _GNU_SOURCE
|
||||||
|
|
||||||
|
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -22,6 +25,9 @@ extern int pthread_getattr_np(pthread_t thread, pthread_attr_t* attr);
|
|||||||
extern int pthread_getname_np(pthread_t thread, char* buffer, size_t length);
|
extern int pthread_getname_np(pthread_t thread, char* buffer, size_t length);
|
||||||
extern int pthread_setname_np(pthread_t thread, const char* name);
|
extern int pthread_setname_np(pthread_t thread, const char* name);
|
||||||
|
|
||||||
|
extern int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpuset_t* mask);
|
||||||
|
extern int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpuset_t* mask);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,51 @@
|
|||||||
|
|
||||||
#include_next <sched.h>
|
#include_next <sched.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef _GNU_SOURCE
|
#ifdef _GNU_SOURCE
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CPU_SETSIZE
|
||||||
|
#define CPU_SETSIZE 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef __haiku_uint32 cpuset_mask;
|
||||||
|
|
||||||
|
#ifndef _howmany
|
||||||
|
#define _howmany(x, y) (((x) + ((y) - 1)) / (y))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NCPUSETBITS (sizeof(cpuset_mask) * 8) /* bits per mask */
|
||||||
|
|
||||||
|
typedef struct _cpuset {
|
||||||
|
cpuset_mask bits[_howmany(CPU_SETSIZE, NCPUSETBITS)];
|
||||||
|
} cpuset_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define _CPUSET_BITSINDEX(cpu) ((cpu) / NCPUSETBITS)
|
||||||
|
#define _CPUSET_BIT(cpu) (1L << ((cpu) % NCPUSETBITS))
|
||||||
|
|
||||||
|
/* FD_ZERO uses memset */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define CPUSET_ZERO(set) memset((set), 0, sizeof(cpuset_t))
|
||||||
|
#define CPUSET_SET(cpu, set) ((set)->bits[_CPUSET_BITSINDEX(cpu)] |= _CPUSET_BIT(cpu))
|
||||||
|
#define CPUSET_CLR(cpu, set) ((set)->bits[_CPUSET_BITSINDEX(cpu)] &= ~_CPUSET_BIT(cpu))
|
||||||
|
#define CPUSET_ISSET(cpu, set) ((set)->bits[_CPUSET_BITSINDEX(cpu)] & _CPUSET_BIT(cpu))
|
||||||
|
#define CPUSET_COPY(source, target) (*(target) = *(source))
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int sched_getcpu(void);
|
extern int sched_getcpu(void);
|
||||||
|
extern int sched_setaffinity(pid_t id, size_t cpusetsize, const cpuset_t* mask);
|
||||||
|
extern int sched_getaffinity(pid_t id, size_t cpusetsize, cpuset_t* mask);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ SubDir HAIKU_TOP src libs gnu ;
|
|||||||
|
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility gnu ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility gnu ] : true ;
|
||||||
UsePrivateHeaders shared ;
|
UsePrivateHeaders libroot shared ;
|
||||||
|
|
||||||
SubDirCcFlags [ FDefines _GNU_SOURCE=1 ] ;
|
SubDirCcFlags [ FDefines _GNU_SOURCE=1 ] ;
|
||||||
SubDirC++Flags [ FDefines _GNU_SOURCE=1 ] ;
|
SubDirC++Flags [ FDefines _GNU_SOURCE=1 ] ;
|
||||||
@@ -19,6 +19,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
crypt.cpp
|
crypt.cpp
|
||||||
memmem.c
|
memmem.c
|
||||||
qsort.c
|
qsort.c
|
||||||
|
sched_affinity.cpp
|
||||||
sched_getcpu.cpp
|
sched_getcpu.cpp
|
||||||
xattr.cpp
|
xattr.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023, Jérôme Duval, [email protected]. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
|
#include <pthread_private.h>
|
||||||
|
#include <syscalls.h>
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpuset_t* mask)
|
||||||
|
{
|
||||||
|
return _kern_set_thread_affinity(thread->id, mask, cpusetsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpuset_t* mask)
|
||||||
|
{
|
||||||
|
status_t status = _kern_get_thread_affinity(thread->id, mask, cpusetsize);
|
||||||
|
if (status != B_OK) {
|
||||||
|
if (status == B_BAD_THREAD_ID)
|
||||||
|
return ESRCH;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
sched_setaffinity(pid_t id, size_t cpusetsize, const cpuset_t* mask)
|
||||||
|
{
|
||||||
|
status_t status = _kern_set_thread_affinity(id, mask, cpusetsize);
|
||||||
|
if (status != B_OK) {
|
||||||
|
if (status == B_BAD_THREAD_ID)
|
||||||
|
return ESRCH;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
sched_getaffinity(pid_t id, size_t cpusetsize, cpuset_t* mask)
|
||||||
|
{
|
||||||
|
status_t status = _kern_get_thread_affinity(id, mask, cpusetsize);
|
||||||
|
if (status != B_OK) {
|
||||||
|
if (status == B_BAD_THREAD_ID)
|
||||||
|
return ESRCH;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -2,5 +2,6 @@ SubDir HAIKU_TOP src tests libs ;
|
|||||||
|
|
||||||
SubInclude HAIKU_TOP src tests libs alm ;
|
SubInclude HAIKU_TOP src tests libs alm ;
|
||||||
SubInclude HAIKU_TOP src tests libs bsd ;
|
SubInclude HAIKU_TOP src tests libs bsd ;
|
||||||
|
SubInclude HAIKU_TOP src tests libs gnu ;
|
||||||
SubInclude HAIKU_TOP src tests libs linprog ;
|
SubInclude HAIKU_TOP src tests libs linprog ;
|
||||||
|
|
||||||
|
|||||||
@@ -4,5 +4,6 @@ UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility gnu ] : true ;
|
|||||||
SubDirC++Flags [ FDefines _GNU_SOURCE=1 ] ;
|
SubDirC++Flags [ FDefines _GNU_SOURCE=1 ] ;
|
||||||
|
|
||||||
SimpleTest sched_getcpu_test : sched_getcpu_test.cpp : libgnu.so ;
|
SimpleTest sched_getcpu_test : sched_getcpu_test.cpp : libgnu.so ;
|
||||||
|
SimpleTest sched_affinity_test : sched_affinity_test.cpp : libgnu.so ;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023, Jérôme Duval, [email protected]. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
exit(1);
|
||||||
|
if (strcmp(argv[1], "off") != 0) {
|
||||||
|
printf("with affinity on CPU 1\n");
|
||||||
|
pthread_t thread = pthread_self();
|
||||||
|
cpuset_t cpuset;
|
||||||
|
CPUSET_ZERO(&cpuset);
|
||||||
|
CPUSET_SET(1, &cpuset);
|
||||||
|
if (pthread_setaffinity_np(thread, sizeof(cpuset_t), &cpuset) != 0) {
|
||||||
|
fprintf(stderr, "pthread_setaffinity_np failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (pthread_getaffinity_np(thread, sizeof(cpuset_t), &cpuset) != 0) {
|
||||||
|
fprintf(stderr, "pthread_getaffinity_np failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!CPUSET_ISSET(1, &cpuset))
|
||||||
|
fprintf(stderr, "affinity not on CPU 1\n");
|
||||||
|
if (sched_getcpu() != 1)
|
||||||
|
fprintf(stderr, "not running on CPU 1\n");
|
||||||
|
} else {
|
||||||
|
printf("without affinity\n");
|
||||||
|
}
|
||||||
|
int* p;
|
||||||
|
while (true)
|
||||||
|
(*p)++;
|
||||||
|
return *p;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user