gnu: add sched_getcpu()
on x86_64 implemented with rdtscp or rdpid, generically with a syscall. Change-Id: I8f776848bf35575abec8a8c612c4a25d8550daea Reviewed-on: https://review.haiku-os.org/c/haiku/+/6866 Reviewed-by: waddlesplash <waddlesplash@gmail.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
449929ad0e
commit
efbeada748
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2023 Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _GNU_SCHED_H_
|
||||
#define _GNU_SCHED_H_
|
||||
|
||||
|
||||
#include_next <sched.h>
|
||||
|
||||
|
||||
#ifdef _GNU_SOURCE
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int sched_getcpu(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _GNU_SCHED_H_ */
|
|
@ -159,6 +159,7 @@ status_t _user_receive_data(thread_id *_sender, void *buffer, size_t buffer_size
|
|||
thread_id _user_find_thread(const char *name);
|
||||
status_t _user_get_thread_info(thread_id id, thread_info *info);
|
||||
status_t _user_get_next_thread_info(team_id team, int32 *cookie, thread_info *info);
|
||||
int _user_get_cpu();
|
||||
|
||||
status_t _user_block_thread(uint32 flags, bigtime_t timeout);
|
||||
status_t _user_unblock_thread(thread_id thread, status_t status);
|
||||
|
|
|
@ -196,6 +196,7 @@ extern status_t _kern_get_team_usage_info(team_id team, int32 who,
|
|||
team_usage_info *info, size_t size);
|
||||
extern status_t _kern_get_extended_team_info(team_id teamID, uint32 flags,
|
||||
void* buffer, size_t size, size_t* _sizeNeeded);
|
||||
extern int _kern_get_cpu();
|
||||
|
||||
extern status_t _kern_start_watching_system(int32 object, uint32 flags,
|
||||
port_id port, int32 token);
|
||||
|
|
|
@ -10,10 +10,16 @@ SubDirC++Flags [ FDefines _GNU_SOURCE=1 ] ;
|
|||
local architectureObject ;
|
||||
for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
on $(architectureObject) {
|
||||
UsePrivateSystemHeaders ;
|
||||
if $(TARGET_ARCH) = x86_64 {
|
||||
SubDirC++Flags -mrdpid ;
|
||||
}
|
||||
|
||||
SharedLibrary [ MultiArchDefaultGristFiles libgnu.so ] :
|
||||
crypt.cpp
|
||||
memmem.c
|
||||
qsort.c
|
||||
sched_getcpu.cpp
|
||||
xattr.cpp
|
||||
;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright 2023, Jérôme Duval, jerome.duval@gmail.com. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <sched.h>
|
||||
|
||||
#include <syscalls.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <x86intrin.h>
|
||||
|
||||
#define IA32_FEATURE_RDPID (1 << 22) // RDPID Instruction
|
||||
#define IA32_FEATURE_AMD_EXT_RDTSCP (1 << 27) // rdtscp instruction
|
||||
|
||||
|
||||
typedef int (*sched_cpu_func)();
|
||||
static pthread_once_t sSchedCpuInitOnce = PTHREAD_ONCE_INIT;
|
||||
static sched_cpu_func sSchedCpuFunc = NULL;
|
||||
|
||||
|
||||
static int
|
||||
__sched_cpu_syscall()
|
||||
{
|
||||
return _kern_get_cpu();
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
__sched_cpu_rdtscp()
|
||||
{
|
||||
uint32_t aux;
|
||||
__rdtscp(&aux);
|
||||
return aux;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
__sched_cpu_rdpid()
|
||||
{
|
||||
return _rdpid_u32();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
initSchedCpuFunc()
|
||||
{
|
||||
cpuid_info cpuInfo;
|
||||
get_cpuid(&cpuInfo, 0, 0);
|
||||
if (cpuInfo.eax_0.max_eax >= 0x7) {
|
||||
get_cpuid(&cpuInfo, 0x7, 0);
|
||||
if ((cpuInfo.regs.ecx & IA32_FEATURE_RDPID) != 0) {
|
||||
sSchedCpuFunc = __sched_cpu_rdpid;
|
||||
return;
|
||||
}
|
||||
}
|
||||
get_cpuid(&cpuInfo, 0x80000000, 0);
|
||||
if (cpuInfo.eax_0.max_eax >= 0x80000001) {
|
||||
get_cpuid(&cpuInfo, 0x80000001, 0);
|
||||
if ((cpuInfo.regs.edx & IA32_FEATURE_AMD_EXT_RDTSCP)!= 0) {
|
||||
sSchedCpuFunc = __sched_cpu_rdtscp;
|
||||
return;
|
||||
}
|
||||
}
|
||||
sSchedCpuFunc = __sched_cpu_syscall;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sched_getcpu()
|
||||
{
|
||||
if (sSchedCpuFunc == NULL) {
|
||||
pthread_once(&sSchedCpuInitOnce, &initSchedCpuFunc);
|
||||
}
|
||||
return sSchedCpuFunc();
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
int
|
||||
sched_getcpu()
|
||||
{
|
||||
return _kern_get_cpu();
|
||||
}
|
||||
#endif
|
||||
|
|
@ -3915,3 +3915,11 @@ _user_setrlimit(int resource, const struct rlimit *userResourceLimit)
|
|||
|
||||
return common_setrlimit(resource, &resourceLimit);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_user_get_cpu()
|
||||
{
|
||||
Thread* thread = thread_get_current_thread();
|
||||
return thread->cpu->cpu_num;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
SubDir HAIKU_TOP src tests libs gnu ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility gnu ] : true ;
|
||||
SubDirC++Flags [ FDefines _GNU_SOURCE=1 ] ;
|
||||
|
||||
SimpleTest sched_getcpu_test : sched_getcpu_test.cpp : libgnu.so ;
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright 2023, Jérôme Duval, jerome.duval@gmail.com. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
int cpu = sched_getcpu();
|
||||
printf("cpu: %d\n", cpu);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue