From d6e43153db186f9d6067de63eac03d489ed44feb Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sun, 5 Jul 2026 16:32:47 +0200 Subject: [PATCH] Introducing BOX64_SKIPCPU to skip N first cores, (to avoid little cores in big.LITTLE SoC) --- CMakeLists.txt | 1 + docs/USAGE.md | 7 ++ docs/USAGE_CN.md | 7 ++ docs/box64.pod | 8 ++ docs/gen/usage.json | 19 +++++ src/core.c | 4 +- src/emu/x64printer.c | 6 +- src/emu/x64syscall.c | 53 ++++++++++++- src/include/cpumask.h | 12 +++ src/include/env.h | 2 + src/libtools/threads.c | 64 +++++++++++++-- src/libtools/threads32.c | 46 +++++++++-- src/os/sysinfo.c | 12 ++- src/tools/cpumask.c | 79 +++++++++++++++++++ src/tools/env.c | 11 ++- src/wrapped/generated/functions_list.txt | 6 +- src/wrapped/generated/wrappedlibctypes.h | 3 + .../generated/wrappedlibpthreadtypes.h | 1 + src/wrapped/generated/wrapper.c | 10 +-- src/wrapped/generated/wrapper.h | 5 +- src/wrapped/wrappedlibc.c | 35 ++++++++ src/wrapped/wrappedlibc_private.h | 6 +- src/wrapped/wrappedlibpthread_private.h | 3 +- src/wrapped32/generated/functions_list.txt | 5 +- src/wrapped32/generated/wrappedlibctypes32.h | 3 + .../generated/wrappedlibpthreadtypes32.h | 1 + src/wrapped32/generated/wrapper32.c | 2 - src/wrapped32/generated/wrapper32.h | 1 - src/wrapped32/wrappedlibc.c | 36 +++++++++ src/wrapped32/wrappedlibc_private.h | 6 +- src/wrapped32/wrappedlibpthread_private.h | 2 +- wine/wow64/CMakeLists.txt | 1 + 32 files changed, 411 insertions(+), 46 deletions(-) create mode 100644 src/include/cpumask.h create mode 100644 src/tools/cpumask.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 64c2ba930..b2fc3ec35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -477,6 +477,7 @@ set(ELFLOADER_SRC "${BOX64_ROOT}/src/tools/alternate.c" "${BOX64_ROOT}/src/tools/callback.c" "${BOX64_ROOT}/src/tools/cleanup.c" + "${BOX64_ROOT}/src/tools/cpumask.c" "${BOX64_ROOT}/src/tools/gdbjit.c" "${BOX64_ROOT}/src/tools/fileutils.c" "${BOX64_ROOT}/src/tools/pathcoll.c" diff --git a/docs/USAGE.md b/docs/USAGE.md index ffbf1aaf8..f27ecc121 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -214,6 +214,13 @@ Minimum size, in KB, for a DynaCache to be written to disk. Default size is 30KB * XXXX: Set a minimum size of XXXX KB of DynaRec code to write the dynacache to disk. Will not be saved to disk else. * 30: A size of 30 KB is the default value. [Default] +### BOX64_SKIPCPU + +Skip N first CPU cores (Is apply before MAXCPU) Available in WowBox64. + + * 0: Do not skip any CPU cores. [Default] + * XXXX: Skip XXXX first CPU cores (usefull for big.LITTLE configurations). + ### BOX64_MMAP32 Force 32-bit compatible memory mappings on 64-bit programs that run 32-bit code (like Wine WOW64), can improve performance. diff --git a/docs/USAGE_CN.md b/docs/USAGE_CN.md index b9ce494ed..0c718292d 100644 --- a/docs/USAGE_CN.md +++ b/docs/USAGE_CN.md @@ -214,6 +214,13 @@ DynaCache 写入磁盘的最小大小(KB)。默认大小为 30KB。 * XXXX: 设置将缓存写入磁盘的最小 DynaRec 代码大小(XXXX KB),小于此值将不会保存到磁盘。 * 30: 默认值为 30 KB。 [默认值] +### BOX64_SKIPCPU + +Skip N first CPU cores (Is apply before MAXCPU) 在 WowBox64 中可用。 + + * 0: Do not skip any CPU cores. [默认值] + * XXXX: Skip XXXX first CPU cores (usefull for big.LITTLE configurations). + ### BOX64_MMAP32 在运行 32 位代码的 64 位程序(如 Wine WOW64)上强制使用 32 位兼容的内存映射,可提高性能。 diff --git a/docs/box64.pod b/docs/box64.pod index 818af9c56..43432a5cd 100644 --- a/docs/box64.pod +++ b/docs/box64.pod @@ -650,6 +650,14 @@ Maximum CPU cores exposed. Available in WowBox64. * XXXX : Use XXXX CPU cores. +=item B =I<0|XXXX> + +Skip N first CPU cores (Is apply before MAXCPU) Available in WowBox64. + + * 0 : Do not skip any CPU cores. [Default] + * XXXX : Skip XXXX first CPU cores (usefull for big.LITTLE configurations). + + =item B =I<0|1> Force 32-bit compatible memory mappings on 64-bit programs that run 32-bit code (like Wine WOW64), can improve performance. diff --git a/docs/gen/usage.json b/docs/gen/usage.json index 5bc3eeb0a..a7132c4cb 100644 --- a/docs/gen/usage.json +++ b/docs/gen/usage.json @@ -1498,6 +1498,25 @@ } ] }, + { + "name": "BOX64_SKIPCPU", + "description": "Skip N first CPU cores (Is apply before MAXCPU)", + "category": "Performance", + "wine": true, + "configurator": true, + "options": [ + { + "key": "0", + "description": "Do not skip any CPU cores.", + "default": true + }, + { + "key": "XXXX", + "description": "Skip XXXX first CPU cores (usefull for big.LITTLE configurations).", + "default": false + } + ] + }, { "name": "BOX64_MMAP32", "description": "Force 32-bit compatible memory mappings on 64-bit programs that run 32-bit code (like Wine WOW64), can improve performance.", diff --git a/src/core.c b/src/core.c index a842df60b..9b8011a01 100644 --- a/src/core.c +++ b/src/core.c @@ -234,7 +234,9 @@ static void displayMiscInfo(void) printf_log(LOG_INFO, "Running on %s with %d core%s, pagesize: %zd", box64_sysinfo.cpuname, box64_sysinfo.ncpu, box64_sysinfo.ncpu > 1 ? "s" : "", box64_pagesize); if (BOX64ENV(maxcpu)) - printf_log_prefix(0, LOG_INFO, ", emulating %d core%s\n", BOX64ENV(maxcpu), BOX64ENV(maxcpu) > 1 ? "s" : ""); + printf_log_prefix(0, LOG_INFO, ", emulating %d core%s", BOX64ENV(maxcpu), BOX64ENV(maxcpu) > 1 ? "s" : ""); + if (BOX64ENV(skipcpu)) + printf_log_prefix(0, LOG_INFO, " skipping %d core%s\n", BOX64ENV(skipcpu), BOX64ENV(skipcpu)>1? "s":""); else printf_log_prefix(0, LOG_INFO, "\n"); computeRDTSC(); diff --git a/src/emu/x64printer.c b/src/emu/x64printer.c index e96e0b876..634a85f3a 100644 --- a/src/emu/x64printer.c +++ b/src/emu/x64printer.c @@ -2075,6 +2075,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX); } else if (w == iFEiip) { snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX); + } else if (w == iFEiLp) { + snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX); } else if (w == iFEipp) { snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX); } else if (w == iFEipV) { @@ -7741,10 +7743,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti } else if (w == lFpLpdddddd) { snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, emu->xmm[0].d[0], emu->xmm[1].d[0], emu->xmm[2].d[0], emu->xmm[3].d[0], emu->xmm[4].d[0], emu->xmm[5].d[0]); #endif -#if defined(PPC64LE) - } else if (w == iFEiLp) { - snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX); -#endif #if !defined(PPC64LE) #endif } diff --git a/src/emu/x64syscall.c b/src/emu/x64syscall.c index 1938997e4..f4b0091cc 100644 --- a/src/emu/x64syscall.c +++ b/src/emu/x64syscall.c @@ -42,6 +42,7 @@ #include "elfloader.h" #include "x64int_private.h" #include "syscall_user_dispatch.h" +#include "cpumask.h" typedef struct x64_sigaction_s x64_sigaction_t; typedef struct x64_stack_s x64_stack_t; @@ -255,8 +256,8 @@ static const scwrap_t syscallwrap[] = { [201] = {__NR_time, 1}, #endif [202] = {__NR_futex, 6}, - [203] = {__NR_sched_setaffinity, 3}, - [204] = {__NR_sched_getaffinity, 3}, + //[203] = {__NR_sched_setaffinity, 3}, + //[204] = {__NR_sched_getaffinity, 3}, [206] = {__NR_io_setup, 2}, [207] = {__NR_io_destroy, 1}, [208] = {__NR_io_getevents, 4}, @@ -881,6 +882,30 @@ void EXPORT x64Syscall_linux(x64emu_t *emu) S_RAX = -errno; break; #endif + case 203: // sys_sched_setaffinity + { + uint8_t new_mask[R_ESI]; + memcpy(new_mask, (void*)R_RDX, R_ESI); + cpumask_maxcpu(new_mask, R_ESI, BOX64ENV(maxcpu)); + cpumask_shiftleft(new_mask, R_ESI, BOX64ENV(skipcpu)); + R_RAX = syscall(__NR_sched_setaffinity, S_EDI, R_ESI, new_mask); + } + if(S_RAX==-1) + S_RAX = -errno; + break; + case 204: // sys_sched_getaffinity + { + uint8_t new_mask[R_ESI]; + R_RAX = syscall(__NR_sched_getaffinity, S_EDI, R_ESI, new_mask); + if(S_RAX==-1) + S_RAX = -errno; + else { + cpumask_shiftright(new_mask, R_ESI, BOX64ENV(skipcpu)); + cpumask_maxcpu(new_mask, R_ESI, BOX64ENV(maxcpu)); + memcpy((void*)R_RDX, new_mask, R_ESI); + } + } + break; #if !defined(__NR_epoll_wait) || !defined(NOALIGN) case 232: R_RAX = my_epoll_wait(emu, S_EDI, (void*)R_RSI, S_EDX, S_R10d); @@ -1259,6 +1284,30 @@ long EXPORT my_syscall(x64emu_t *emu) case 201: // sys_time return (intptr_t)time((void*)R_RSI); #endif + case 203: // sys_sched_setaffinity + { + uint8_t new_mask[R_EDX]; + memcpy(new_mask, (void*)R_RCX, R_EDX); + cpumask_maxcpu(new_mask, R_EDX, BOX64ENV(maxcpu)); + cpumask_shiftleft(new_mask, R_EDX, BOX64ENV(skipcpu)); + R_RAX = syscall(__NR_sched_setaffinity, S_ESI, R_EDX, new_mask); + } + if(S_RAX==-1) + S_RAX = -errno; + break; + case 204: // sys_sched_getaffinity + { + uint8_t new_mask[R_EDX]; + R_RAX = syscall(__NR_sched_getaffinity, S_ESI, R_EDX, new_mask); + if(S_RAX==-1) + S_RAX = -errno; + else { + cpumask_shiftright(new_mask, R_EDX, BOX64ENV(skipcpu)); + cpumask_maxcpu(new_mask, R_EDX, BOX64ENV(maxcpu)); + memcpy((void*)R_RCX, new_mask, R_EDX); + } + } + break; #ifndef __NR_epoll_create case 213: return epoll_create(S_ESI); diff --git a/src/include/cpumask.h b/src/include/cpumask.h new file mode 100644 index 000000000..8bf0e85b8 --- /dev/null +++ b/src/include/cpumask.h @@ -0,0 +1,12 @@ +#ifndef __CPU_MASK__H__ +#define __CPU_MASK__H__ + +#include + +void cpumask_shiftleft(void* mask, uint32_t sz, uint32_t n); +void cpumask_shiftright(void* mask, uint32_t sz, uint32_t n); +void cpumask_maxcpu(void* mask, uint32_t sz, uint32_t n); + +void cpumask_apply(uint32_t skip, uint32_t max); + +#endif //__CPU_MASK__H__ diff --git a/src/include/env.h b/src/include/env.h index 53ef9b0d4..2062637e2 100644 --- a/src/include/env.h +++ b/src/include/env.h @@ -107,6 +107,7 @@ extern char* ftrace_name; INTEGER(BOX64_LOG, log, DEFAULT_LOG_LEVEL, 0, 3, 1, 0) \ INTEGER(BOX64_MALLOC_HACK, malloc_hack, 0, 0, 2, 0, 0) \ INTEGER(BOX64_MAXCPU, new_maxcpu, 0, 0, 100, 1, 0) \ + INTEGER(BOX64_SKIPCPU, new_skipcpu, 0, 0, 100, 1, 0) \ BOOLEAN(BOX64_MMAP32, mmap32, 1, 0, 0) \ BOOLEAN(BOX64_NOBANNER, nobanner, BOX64_NOBANNER_DEFAULT, 1, 0) \ STRING(BOX64_NODYNAREC, nodynarec, 1, 0) \ @@ -214,6 +215,7 @@ typedef struct box64env_s { int priority; /******** Custom ones ********/ int maxcpu; + int skipcpu; int dynarec_test; int rolling_log; int dynarec_perf_map_fd; diff --git a/src/libtools/threads.c b/src/libtools/threads.c index 2737c9bde..142ed7f6a 100644 --- a/src/libtools/threads.c +++ b/src/libtools/threads.c @@ -25,6 +25,7 @@ #include "bridge.h" #include "myalign.h" #include "x64tls.h" +#include "cpumask.h" #ifdef DYNAREC #include "dynablock.h" #include "dynarec/native_lock.h" @@ -475,17 +476,43 @@ EXPORT int my_pthread_attr_init(x64emu_t* emu, pthread_attr_t* attr) return ret; } #ifndef ANDROID -EXPORT int my_pthread_attr_setaffinity_np(x64emu_t* emu, pthread_attr_t* attr, size_t cpusize, void* cpuset) +EXPORT int my_pthread_attr_getaffinity_np(x64emu_t* emu, pthread_attr_t* attr, size_t cpusize, void* cpuset) { (void)emu; PTHREAD_ATTR_ALIGN(attr); - int ret = pthread_attr_setaffinity_np(PTHREAD_ATTR(attr), cpusize, cpuset); + int ret = pthread_attr_getaffinity_np(PTHREAD_ATTR(attr), cpusize, cpuset); + PTHREAD_ATTR_UNALIGN(attr); + if(BOX64ENV(skipcpu)) { + cpumask_shiftright(cpuset, cpusize, BOX64ENV(skipcpu)); + cpumask_maxcpu(cpuset, cpusize, BOX64ENV(maxcpu)); + } + return ret; +} +EXPORT int my_pthread_attr_setaffinity_np(x64emu_t* emu, pthread_attr_t* attr, size_t cpusize, void* cpuset) +{ + (void)emu; + uint8_t mask_[cpusize]; + cpu_set_t* cpuset_ = BOX64ENV(skipcpu)?(void*)mask_:cpuset; + if(BOX64ENV(skipcpu)) { + memcpy(mask_, cpuset, cpusize); + cpumask_maxcpu(mask_, cpusize, BOX64ENV(maxcpu)); + cpumask_shiftleft(mask_, cpusize, BOX64ENV(skipcpu)); + } + PTHREAD_ATTR_ALIGN(attr); + int ret = pthread_attr_setaffinity_np(PTHREAD_ATTR(attr), cpusize, cpuset_); PTHREAD_ATTR_UNALIGN(attr); return ret; } EXPORT int my_pthread_attr_setaffinity_np_old(x64emu_t* emu, pthread_attr_t* attr, void* cpuset) { - return my_pthread_attr_setaffinity_np(emu, attr, 128, cpuset); + uint8_t mask_[128]; + cpu_set_t* cpuset_ = BOX64ENV(skipcpu)?(void*)mask_:cpuset; + if(BOX64ENV(skipcpu)) { + memcpy(mask_, cpuset, 128); + cpumask_maxcpu(mask_, 128, BOX64ENV(maxcpu)); + cpumask_shiftleft(mask_, 128, BOX64ENV(skipcpu)); + } + return my_pthread_attr_setaffinity_np(emu, attr, 128, cpuset_); } #endif EXPORT int my_pthread_attr_setdetachstate(x64emu_t* emu, pthread_attr_t* attr, int state) @@ -903,20 +930,38 @@ EXPORT int my_pthread_getaffinity_np(x64emu_t* emu, pthread_t thread, size_t cpu int ret = pthread_getaffinity_np(thread, cpusetsize, cpuset); if(ret<0) { printf_log(LOG_INFO, "Warning, pthread_getaffinity_np(%p, %zd, %p) errored, with errno=%d\n", (void*)thread, cpusetsize, cpuset, errno); + } else { + if(BOX64ENV(skipcpu)) { + cpumask_shiftright(cpuset, cpusetsize, BOX64ENV(skipcpu)); + cpumask_maxcpu(cpuset, cpusetsize, BOX64ENV(maxcpu)); + } } return ret; } EXPORT int my_pthread_getaffinity_np_old(x64emu_t* emu, pthread_t thread, void* cpuset) { - return my_pthread_getaffinity_np(emu, thread, 128, cpuset); + int ret = my_pthread_getaffinity_np(emu, thread, 128, cpuset); + if(ret>=0) { + if(BOX64ENV(skipcpu)) { + cpumask_shiftright(cpuset, 128, BOX64ENV(skipcpu)); + cpumask_maxcpu(cpuset, 128, BOX64ENV(maxcpu)); + } + } } EXPORT int my_pthread_setaffinity_np(x64emu_t* emu, pthread_t thread, size_t cpusetsize, void* cpuset) { (void)emu; - int ret = pthread_setaffinity_np(thread, cpusetsize, cpuset); + uint8_t mask_[cpusetsize]; + cpu_set_t* cpuset_ = BOX64ENV(skipcpu)?(void*)mask_:cpuset; + if(BOX64ENV(skipcpu)) { + memcpy(mask_, cpuset, cpusetsize); + cpumask_maxcpu(mask_, cpusetsize, BOX64ENV(maxcpu)); + cpumask_shiftleft(mask_, cpusetsize, BOX64ENV(skipcpu)); + } + int ret = pthread_setaffinity_np(thread, cpusetsize, cpuset_); if(ret<0) { printf_log(LOG_INFO, "Warning, pthread_setaffinity_np(%p, %zd, %p) errored, with errno=%d\n", (void*)thread, cpusetsize, cpuset, errno); } @@ -925,7 +970,14 @@ EXPORT int my_pthread_setaffinity_np(x64emu_t* emu, pthread_t thread, size_t cpu } EXPORT int my_pthread_setaffinity_np_old(x64emu_t* emu, pthread_t thread, void* cpuset) { - return my_pthread_setaffinity_np(emu, thread, 128, cpuset); + uint8_t mask_[128]; + cpu_set_t* cpuset_ = BOX64ENV(skipcpu)?(void*)mask_:cpuset; + if(BOX64ENV(skipcpu)) { + memcpy(mask_, cpuset, 128); + cpumask_maxcpu(mask_, 128, BOX64ENV(maxcpu)); + cpumask_shiftleft(mask_, 128, BOX64ENV(skipcpu)); + } + return my_pthread_setaffinity_np(emu, thread, 128, cpuset_); } #endif diff --git a/src/libtools/threads32.c b/src/libtools/threads32.c index 689be6480..e4157a798 100755 --- a/src/libtools/threads32.c +++ b/src/libtools/threads32.c @@ -29,6 +29,7 @@ #include "threads32.h" #include "x64tls.h" #include "x64_signals.h" +#include "cpumask.h" #ifdef DYNAREC #include "dynablock.h" #endif @@ -833,12 +834,17 @@ EXPORT int my32_pthread_getaffinity_np(x64emu_t* emu, pthread_t thread, int cpus if(cpusetsize>0x1000) { // probably old version of the function, that didn't have cpusetsize.... cpuset = from_ptrv(cpusetsize); - cpusetsize = sizeof(cpu_set_t); + cpusetsize = 128;//sizeof(cpu_set_t); } int ret = pthread_getaffinity_np(thread, cpusetsize, cpuset); if(ret<0) { printf_log(LOG_INFO, "Warning, pthread_getaffinity_np(%p, %d, %p) errored, with errno=%d\n", (void*)thread, cpusetsize, cpuset, errno); + } else { + if(BOX64ENV(skipcpu)) { + cpumask_shiftright(cpuset, 128, BOX64ENV(skipcpu)); + cpumask_maxcpu(cpuset, 128, BOX64ENV(maxcpu)); + } } return ret; @@ -849,10 +855,17 @@ EXPORT int my32_pthread_setaffinity_np(x64emu_t* emu, pthread_t thread, int cpus if(cpusetsize>0x1000) { // probably old version of the function, that didn't have cpusetsize.... cpuset = from_ptrv(cpusetsize); - cpusetsize = sizeof(cpu_set_t); + cpusetsize = 128; //sizeof(cpu_set_t); } + uint8_t mask_[cpusetsize]; + cpu_set_t* cpuset_ = BOX64ENV(skipcpu)?(void*)mask_:cpuset; + if(BOX64ENV(skipcpu)) { + memcpy(mask_, cpuset, cpusetsize); + cpumask_maxcpu(mask_, cpusetsize, BOX64ENV(maxcpu)); + cpumask_shiftleft(mask_, cpusetsize, BOX64ENV(skipcpu)); + } - int ret = pthread_setaffinity_np(thread, cpusetsize, cpuset); + int ret = pthread_setaffinity_np(thread, cpusetsize, cpuset_); if(ret<0) { printf_log(LOG_INFO, "Warning, pthread_setaffinity_np(%p, %d, %p) errored, with errno=%d\n", (void*)thread, cpusetsize, cpuset, errno); } @@ -865,16 +878,37 @@ EXPORT int my32_pthread_attr_setaffinity_np(x64emu_t* emu, void* attr, uint32_t if(cpusetsize>0x1000) { // probably old version of the function, that didn't have cpusetsize.... cpuset = from_ptrv(cpusetsize); - cpusetsize = sizeof(cpu_set_t); + cpusetsize = 128; //sizeof(cpu_set_t); } - - int ret = pthread_attr_setaffinity_np(get_attr(attr), cpusetsize, cpuset); + uint8_t mask_[cpusetsize]; + cpu_set_t* cpuset_ = BOX64ENV(skipcpu)?(void*)mask_:cpuset; + if(BOX64ENV(skipcpu)) { + memcpy(mask_, cpuset, cpusetsize); + cpumask_maxcpu(mask_, cpusetsize, BOX64ENV(maxcpu)); + cpumask_shiftleft(mask_, cpusetsize, BOX64ENV(skipcpu)); + } + int ret = pthread_attr_setaffinity_np(get_attr(attr), cpusetsize, cpuset_); if(ret<0) { printf_log(LOG_INFO, "Warning, pthread_attr_setaffinity_np(%p, %d, %p) errored, with errno=%d\n", attr, cpusetsize, cpuset, errno); } return ret; } +EXPORT int my32_pthread_attr_getaffinity_np(x64emu_t* emu, void* attr, uint32_t cpusetsize, void* cpuset) +{ + if(cpusetsize>0x1000) { + // probably old version of the function, that didn't have cpusetsize.... + cpuset = from_ptrv(cpusetsize); + cpusetsize = 128; //sizeof(cpu_set_t); + } + int ret = pthread_attr_getaffinity_np(get_attr(attr), cpusetsize, cpuset); + if(BOX64ENV(skipcpu)) { + cpumask_shiftright(cpuset, cpusetsize, BOX64ENV(skipcpu)); + cpumask_maxcpu(cpuset, cpusetsize, BOX64ENV(maxcpu)); + } + return ret; +} + #endif EXPORT int my32_pthread_kill(x64emu_t* emu, void* thread, int sig) diff --git a/src/os/sysinfo.c b/src/os/sysinfo.c index 0fe663a55..76cf648b8 100644 --- a/src/os/sysinfo.c +++ b/src/os/sysinfo.c @@ -7,6 +7,7 @@ #include "debug.h" #include "sysinfo.h" #include "build_info.h" +#include "cpumask.h" #ifdef _WIN32 #include @@ -212,9 +213,18 @@ void InitializeSystemInfo(void) #endif box64_sysinfo.box64_ncpu = box64_sysinfo.ncpu; - if (BOX64ENV(maxcpu) && box64_sysinfo.ncpu > (uint64_t)BOX64ENV(maxcpu)) { + if (BOX64ENV(skipcpu) && box64_sysinfo.box64_ncpu > (uint64_t)BOX64ENV(skipcpu)) { + box64_sysinfo.box64_ncpu -= (uint64_t)BOX64ENV(skipcpu); + } + if (BOX64ENV(maxcpu) && box64_sysinfo.box64_ncpu > (uint64_t)BOX64ENV(maxcpu)) { box64_sysinfo.box64_ncpu = (uint64_t)BOX64ENV(maxcpu); } + while(box64env.skipcpu && box64_sysinfo.box64_ncpu+box64env.skipcpu>box64_sysinfo.ncpu) { + --box64_sysinfo.box64_ncpu; + box64env.maxcpu = box64_sysinfo.box64_ncpu; + } + if(box64env.skipcpu) + cpumask_apply(box64env.skipcpu, box64env.maxcpu); } uint32_t helper_getcpu(x64emu_t* emu) diff --git a/src/tools/cpumask.c b/src/tools/cpumask.c new file mode 100644 index 000000000..b8b33fefa --- /dev/null +++ b/src/tools/cpumask.c @@ -0,0 +1,79 @@ +#ifndef _WIN32 +#define _GNU_SOURCE +#include +#endif +#include +#include +#include "cpumask.h" + +void cpumask_shiftleft(void* mask, uint32_t sz, uint32_t n) +{ + if(!n || !mask || !sz) return; + uint8_t* m = (uint8_t*)mask; + uint32_t n_bytes = n/8; // number of bytes to shift + uint32_t n_bits = n%8; // number if bits to shift + // shift bytes + if(n_bytes) { + for(int i=sz-1; i>(8-n_bits); + m[i]=(m[i]<sz-n_bytes; ++i) + m[i] = m[i+n_bytes]; + for(int i=sz-n_bytes+1; i=0; --i) { + uint8_t new_down = m[i]<<(8-n_bits); + m[i]=(m[i]>>n_bits)|down; + down = new_down; + } + } +} + +void cpumask_maxcpu(void* mask, uint32_t sz, uint32_t n) +{ + if(!n || !mask || !sz) return; + uint8_t* m = (uint8_t*)mask; + // mask 8bits at a time first + for(int i=(n+7)/8; i (uint64_t)box64env.maxcpu) { box64_sysinfo.box64_ncpu = (uint64_t)box64env.maxcpu; } - } + if (box64env.new_skipcpu && (box64env.new_skipcpu < box64_sysinfo.ncpu)) { + box64env.skipcpu = box64env.new_skipcpu; + } + while(box64env.skipcpu && box64_sysinfo.box64_ncpu+box64env.skipcpu>box64_sysinfo.ncpu) { + --box64_sysinfo.box64_ncpu; + box64env.maxcpu = box64_sysinfo.box64_ncpu; + } + if(box64env.skipcpu) + cpumask_apply(box64env.skipcpu, box64env.maxcpu); #ifndef _WIN32 if (box64env.dynarec_perf_map) { diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt index c1479e4f6..813f68c14 100644 --- a/src/wrapped/generated/functions_list.txt +++ b/src/wrapped/generated/functions_list.txt @@ -1173,6 +1173,7 @@ #() iFEiiu #() iFEiip #() iFEiiN +#() iFEiLp #() iFEipp #() iFEipV #() iFEipA @@ -4211,7 +4212,6 @@ #!defined(STATICBUILD) iFEpipppL #!defined(STATICBUILD) iFiiULippp #!defined(STATICBUILD) lFpLpdddddd -#defined(PPC64LE) iFEiLp #!defined(PPC64LE) iFiLN #() vFEv -> vFE #() iFEv -> iFE @@ -5486,6 +5486,7 @@ wrappedlibc: - __cxa_finalize - iFv: - fork + - sched_getcpu - vfork - iFi: - iopl @@ -5632,6 +5633,8 @@ wrappedlibc: - fsmount - iFiLp: - ioctl + - sched_getaffinity + - sched_setaffinity - iFipu: - fspick - iFipp: @@ -6359,6 +6362,7 @@ wrappedlibpthread: - _pthread_cleanup_push - _pthread_cleanup_push_defer - iFpLp: + - pthread_attr_getaffinity_np - pthread_attr_setaffinity_np - pthread_getaffinity_np - pthread_setaffinity_np diff --git a/src/wrapped/generated/wrappedlibctypes.h b/src/wrapped/generated/wrappedlibctypes.h index a43993ecb..a91687b31 100644 --- a/src/wrapped/generated/wrappedlibctypes.h +++ b/src/wrapped/generated/wrappedlibctypes.h @@ -140,6 +140,7 @@ typedef int32_t (*iFppipppp_t)(void*, void*, int32_t, void*, void*, void*, void* GO(_ZGTtdlPv, vFp_t) \ GO(__cxa_finalize, vFp_t) \ GO(fork, iFv_t) \ + GO(sched_getcpu, iFv_t) \ GO(vfork, iFv_t) \ GO(iopl, iFi_t) \ GO(__libc_dlclose, iFp_t) \ @@ -245,6 +246,8 @@ typedef int32_t (*iFppipppp_t)(void*, void*, int32_t, void*, void*, void*, void* GO(fcntl64, iFiiN_t) \ GO(fsmount, iFiuu_t) \ GO(ioctl, iFiLp_t) \ + GO(sched_getaffinity, iFiLp_t) \ + GO(sched_setaffinity, iFiLp_t) \ GO(fspick, iFipu_t) \ GO(__lxstat, iFipp_t) \ GO(__lxstat64, iFipp_t) \ diff --git a/src/wrapped/generated/wrappedlibpthreadtypes.h b/src/wrapped/generated/wrappedlibpthreadtypes.h index 5627efbea..a93439a83 100644 --- a/src/wrapped/generated/wrappedlibpthreadtypes.h +++ b/src/wrapped/generated/wrappedlibpthreadtypes.h @@ -104,6 +104,7 @@ typedef int32_t (*iFpppp_t)(void*, void*, void*, void*); GO(pthread_setaffinity_np@GLIBC_2.3.3, iFpp_t) \ GO(_pthread_cleanup_push, vFppp_t) \ GO(_pthread_cleanup_push_defer, vFppp_t) \ + GO(pthread_attr_getaffinity_np, iFpLp_t) \ GO(pthread_attr_setaffinity_np, iFpLp_t) \ GO(pthread_getaffinity_np, iFpLp_t) \ GO(pthread_setaffinity_np, iFpLp_t) \ diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c index e3475e6ba..549ea4105 100644 --- a/src/wrapped/generated/wrapper.c +++ b/src/wrapped/generated/wrapper.c @@ -1204,6 +1204,7 @@ typedef int8_t (*cFpipp_t)(void*, int32_t, void*, void*); typedef int32_t (*iFEiiu_t)(x64emu_t*, int32_t, int32_t, uint32_t); typedef int32_t (*iFEiip_t)(x64emu_t*, int32_t, int32_t, void*); typedef int32_t (*iFEiiN_t)(x64emu_t*, int32_t, int32_t, ...); +typedef int32_t (*iFEiLp_t)(x64emu_t*, int32_t, uintptr_t, void*); typedef int32_t (*iFEipp_t)(x64emu_t*, int32_t, void*, void*); typedef int32_t (*iFEipV_t)(x64emu_t*, int32_t, void*, void*); typedef int32_t (*iFEipA_t)(x64emu_t*, int32_t, void*, void*); @@ -4300,10 +4301,6 @@ typedef int32_t (*iFiiULippp_t)(int32_t, int32_t, uint64_t, uintptr_t, int32_t, typedef intptr_t (*lFpLpdddddd_t)(void*, uintptr_t, void*, double, double, double, double, double, double); #endif -#if defined(PPC64LE) -typedef int32_t (*iFEiLp_t)(x64emu_t*, int32_t, uintptr_t, void*); -#endif - #if !defined(PPC64LE) typedef int32_t (*iFiLN_t)(int32_t, uintptr_t, ...); #endif @@ -5463,6 +5460,7 @@ void cFpipp(x64emu_t *emu, uintptr_t fcn) { cFpipp_t fn = (cFpipp_t)fcn; R_RAX=( void iFEiiu(x64emu_t *emu, uintptr_t fcn) { iFEiiu_t fn = (iFEiiu_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX); } void iFEiip(x64emu_t *emu, uintptr_t fcn) { iFEiip_t fn = (iFEiip_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX); } void iFEiiN(x64emu_t *emu, uintptr_t fcn) { iFEiiN_t fn = (iFEiiN_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX); } +void iFEiLp(x64emu_t *emu, uintptr_t fcn) { iFEiLp_t fn = (iFEiLp_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX); } void iFEipp(x64emu_t *emu, uintptr_t fcn) { iFEipp_t fn = (iFEipp_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX); } void iFEipV(x64emu_t *emu, uintptr_t fcn) { iFEipV_t fn = (iFEipV_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (void*)R_RSI, (void*)(R_RSP + 8)); } void iFEipA(x64emu_t *emu, uintptr_t fcn) { iFEipA_t fn = (iFEipA_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX); } @@ -8584,10 +8582,6 @@ void iFiiULippp(x64emu_t *emu, uintptr_t fcn) { iFiiULippp_t fn = (iFiiULippp_t) void lFpLpdddddd(x64emu_t *emu, uintptr_t fcn) { lFpLpdddddd_t fn = (lFpLpdddddd_t)fcn; R_RAX=(intptr_t)fn((void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, emu->xmm[0].d[0], emu->xmm[1].d[0], emu->xmm[2].d[0], emu->xmm[3].d[0], emu->xmm[4].d[0], emu->xmm[5].d[0]); } #endif -#if defined(PPC64LE) -void iFEiLp(x64emu_t *emu, uintptr_t fcn) { iFEiLp_t fn = (iFEiLp_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX); } -#endif - #if !defined(PPC64LE) void iFiLN(x64emu_t *emu, uintptr_t fcn) { iFiLN_t fn = (iFiLN_t)fcn; R_RAX=(int)fn((int32_t)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX); } #endif diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h index aeb06c37e..0f5d55b7e 100644 --- a/src/wrapped/generated/wrapper.h +++ b/src/wrapped/generated/wrapper.h @@ -1210,6 +1210,7 @@ void cFpipp(x64emu_t *emu, uintptr_t fnc); void iFEiiu(x64emu_t *emu, uintptr_t fnc); void iFEiip(x64emu_t *emu, uintptr_t fnc); void iFEiiN(x64emu_t *emu, uintptr_t fnc); +void iFEiLp(x64emu_t *emu, uintptr_t fnc); void iFEipp(x64emu_t *emu, uintptr_t fnc); void iFEipV(x64emu_t *emu, uintptr_t fnc); void iFEipA(x64emu_t *emu, uintptr_t fnc); @@ -4258,10 +4259,6 @@ void iFiiULippp(x64emu_t *emu, uintptr_t fnc); void lFpLpdddddd(x64emu_t *emu, uintptr_t fnc); #endif -#if defined(PPC64LE) -void iFEiLp(x64emu_t *emu, uintptr_t fnc); -#endif - #if !defined(PPC64LE) void iFiLN(x64emu_t *emu, uintptr_t fnc); #endif diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index fcf398bb4..a24db198a 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -63,6 +63,7 @@ extern int _nl_msg_cat_cntr __attribute__((weak)); #include #include #include +#include #undef LOG_INFO #undef LOG_DEBUG @@ -93,6 +94,7 @@ extern int _nl_msg_cat_cntr __attribute__((weak)); #include "pe_tools.h" #include "cleanup.h" #include "random.h" +#include "cpumask.h" #ifndef LOG_INFO #define LOG_INFO 1 #endif @@ -4835,6 +4837,39 @@ EXPORT long my_sysconf(x64emu_t* emu, int what) { } EXPORT long my___sysconf(x64emu_t* emu, int what) __attribute__((alias("my_sysconf"))); +EXPORT int my_sched_getaffinity(x64emu_t* emu, pid_t pid, size_t sz, cpu_set_t* mask) +{ + if(!BOX64ENV(skipcpu)) + return sched_getaffinity(pid, sz, mask); + uint8_t mask_[sz]; + int ret = sched_getaffinity(pid, sz, (cpu_set_t*)mask_); + if(ret>=0) { + cpumask_shiftright(mask_, sz, BOX64ENV(skipcpu)); + cpumask_maxcpu(mask, sz, BOX64ENV(maxcpu)); + memcpy(mask, mask_, sz); + } + return ret; +} +EXPORT int my_sched_getcpu(x64emu_t* emu) +{ + int ret = sched_getcpu(); + if(ret>=0 && BOX64ENV(skipcpu)) { + ret -= BOX64ENV(skipcpu); + if(ret<0) ret = 0; + } + return ret; +} +EXPORT int my_sched_setaffinity(x64emu_t* emu, pid_t pid, size_t sz, cpu_set_t* mask) +{ + if(!BOX64ENV(skipcpu)) + return sched_setaffinity(pid, sz, mask); + uint8_t mask_[sz]; + memcpy(mask_, mask, sz); + cpumask_maxcpu(mask, sz, BOX64ENV(maxcpu)); + cpumask_shiftleft(mask_, sz, BOX64ENV(skipcpu)); + return sched_setaffinity(pid, sz, (cpu_set_t*)mask_); +} + EXPORT char* my___progname = NULL; EXPORT char* my___progname_full = NULL; EXPORT char* my_program_invocation_name = NULL; diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h index 633e2219b..18014df82 100644 --- a/src/wrapped/wrappedlibc_private.h +++ b/src/wrapped/wrappedlibc_private.h @@ -1749,8 +1749,8 @@ GOM(scanf, iFpV) GO(__sched_cpualloc, pFL) GO(__sched_cpucount, iFLp) GO(__sched_cpufree, vFp) -GO(sched_getaffinity, iFiLp) -GO(sched_getcpu, iFv) +GOM(sched_getaffinity, iFEiLp) +GOM(sched_getcpu, iFEv) GO(__sched_getparam, iFip) GOW(sched_getparam, iFip) GO(__sched_get_priority_max, iFi) @@ -1760,7 +1760,7 @@ GOW(sched_get_priority_min, iFi) //GO(__sched_getscheduler, iFi) GOW(sched_getscheduler, iFi) GOW(sched_rr_get_interval, iFip) -GO(sched_setaffinity, iFiLp) +GOM(sched_setaffinity, iFEiLp) GOW(sched_setparam, iFip) //GO(__sched_setscheduler, iFiip) GOW(sched_setscheduler, iFiip) diff --git a/src/wrapped/wrappedlibpthread_private.h b/src/wrapped/wrappedlibpthread_private.h index 8f211cd7d..699db58cf 100644 --- a/src/wrapped/wrappedlibpthread_private.h +++ b/src/wrapped/wrappedlibpthread_private.h @@ -23,8 +23,8 @@ GO(__libc_current_sigrtmin, iFv) GOM(pthread_atfork, iFEppp) GOM(__pthread_atfork, iFEppp) GOM(pthread_attr_destroy, iFEp) -GO(pthread_attr_getaffinity_np, iFpLp) #ifdef NOALIGN +GO(pthread_attr_getaffinity_np, iFpLp) GO(pthread_attr_getdetachstate, iFpp) GO(pthread_attr_getguardsize, iFpp) GO(pthread_attr_getinheritsched, iFpp) @@ -32,6 +32,7 @@ GO(pthread_attr_getschedparam, iFpp) GO(pthread_attr_getschedpolicy, iFpp) GO(pthread_attr_getscope, iFpp) #else +GOM(pthread_attr_getaffinity_np, iFEpLp) GOM(pthread_attr_getdetachstate, iFEpp) GOM(pthread_attr_getguardsize, iFEpp) GOM(pthread_attr_getinheritsched, iFEpp) diff --git a/src/wrapped32/generated/functions_list.txt b/src/wrapped32/generated/functions_list.txt index 52f51cbc0..e69c3aaa8 100644 --- a/src/wrapped32/generated/functions_list.txt +++ b/src/wrapped32/generated/functions_list.txt @@ -587,7 +587,6 @@ #() iEiuu -> iEiuu #() iFiuu -> iFiuu #() iFiuL -> iFiuL -#() iEiup -> iEiup #() iFiup -> iFiup #() iFiUU -> iFiUU #() iFiUp -> iFiUp @@ -2473,6 +2472,7 @@ wrappedlibc: - vFp: - _ZGTtdlPv - iEv: + - sched_getcpu - iEi: - __close_nocancel - iEL: @@ -2612,6 +2612,8 @@ wrappedlibc: - iEiLp: - __ioctl_time64 - ioctl + - sched_getaffinity + - sched_setaffinity - iEipp: - iEipV: - iEpii: @@ -3159,6 +3161,7 @@ wrappedlibpthread: - iEpiu: - sem_init - iEpup: + - pthread_attr_getaffinity_np - pthread_attr_setaffinity_np - iEppL: - pthread_attr_setstack diff --git a/src/wrapped32/generated/wrappedlibctypes32.h b/src/wrapped32/generated/wrappedlibctypes32.h index 59c0ba81a..f78a7f988 100644 --- a/src/wrapped32/generated/wrappedlibctypes32.h +++ b/src/wrapped32/generated/wrappedlibctypes32.h @@ -165,6 +165,7 @@ typedef int32_t (*iFpuippupp_t)(void*, uint32_t, int32_t, void*, void*, uint32_t GO(freeaddrinfo, vEp_t) \ GO(regfree, vEp_t) \ GO(_ZGTtdlPv, vFp_t) \ + GO(sched_getcpu, iEv_t) \ GO(__close_nocancel, iEi_t) \ GO(shmdt, iEp_t) \ GO(sysinfo, iEp_t) \ @@ -245,6 +246,8 @@ typedef int32_t (*iFpuippupp_t)(void*, uint32_t, int32_t, void*, void*, uint32_t GO(__fcntl_time64, iEiiN_t) \ GO(__ioctl_time64, iEiLp_t) \ GO(ioctl, iEiLp_t) \ + GO(sched_getaffinity, iEiLp_t) \ + GO(sched_setaffinity, iEiLp_t) \ GO(regcomp, iEppi_t) \ GO(__isoc23_vsscanf, iEppp_t) \ GO(vswscanf, iEppp_t) \ diff --git a/src/wrapped32/generated/wrappedlibpthreadtypes32.h b/src/wrapped32/generated/wrappedlibpthreadtypes32.h index 39fcf667c..eefd235fc 100644 --- a/src/wrapped32/generated/wrappedlibpthreadtypes32.h +++ b/src/wrapped32/generated/wrappedlibpthreadtypes32.h @@ -106,6 +106,7 @@ typedef int32_t (*iEBh_ppp_t)(struct_h_t*, void*, void*, void*); GO(_pthread_cleanup_push, vEppp_t) \ GO(_pthread_cleanup_push_defer, vEppp_t) \ GO(sem_init, iEpiu_t) \ + GO(pthread_attr_getaffinity_np, iEpup_t) \ GO(pthread_attr_setaffinity_np, iEpup_t) \ GO(pthread_attr_setstack, iEppL_t) \ GO(__pthread_atfork, iEppp_t) \ diff --git a/src/wrapped32/generated/wrapper32.c b/src/wrapped32/generated/wrapper32.c index 65008d8df..48eb32abe 100644 --- a/src/wrapped32/generated/wrapper32.c +++ b/src/wrapped32/generated/wrapper32.c @@ -681,7 +681,6 @@ typedef int32_t (*iFiui_t)(int32_t, uint32_t, int32_t); typedef int32_t (*iEiuu_t)(int32_t, uint32_t, uint32_t); typedef int32_t (*iFiuu_t)(int32_t, uint32_t, uint32_t); typedef int32_t (*iFiuL_t)(int32_t, uint32_t, uintptr_t); -typedef int32_t (*iEiup_t)(int32_t, uint32_t, void*); typedef int32_t (*iFiup_t)(int32_t, uint32_t, void*); typedef int32_t (*iFiUU_t)(int32_t, uint64_t, uint64_t); typedef int32_t (*iFiUp_t)(int32_t, uint64_t, void*); @@ -2944,7 +2943,6 @@ void iFiui_32(x64emu_t *emu, uintptr_t fcn) { iFiui_t fn = (iFiui_t)fcn; R_EAX = void iEiuu_32(x64emu_t *emu, uintptr_t fcn) { iEiuu_t fn = (iEiuu_t)fcn; errno = emu->libc_err; R_EAX = fn(from_ptri(int32_t, R_ESP + 4), from_ptri(uint32_t, R_ESP + 8), from_ptri(uint32_t, R_ESP + 12)); emu->libc_err = errno; } void iFiuu_32(x64emu_t *emu, uintptr_t fcn) { iFiuu_t fn = (iFiuu_t)fcn; R_EAX = fn(from_ptri(int32_t, R_ESP + 4), from_ptri(uint32_t, R_ESP + 8), from_ptri(uint32_t, R_ESP + 12)); } void iFiuL_32(x64emu_t *emu, uintptr_t fcn) { iFiuL_t fn = (iFiuL_t)fcn; R_EAX = fn(from_ptri(int32_t, R_ESP + 4), from_ptri(uint32_t, R_ESP + 8), from_ulong(from_ptri(ulong_t, R_ESP + 12))); } -void iEiup_32(x64emu_t *emu, uintptr_t fcn) { iEiup_t fn = (iEiup_t)fcn; errno = emu->libc_err; R_EAX = fn(from_ptri(int32_t, R_ESP + 4), from_ptri(uint32_t, R_ESP + 8), from_ptriv(R_ESP + 12)); emu->libc_err = errno; } void iFiup_32(x64emu_t *emu, uintptr_t fcn) { iFiup_t fn = (iFiup_t)fcn; R_EAX = fn(from_ptri(int32_t, R_ESP + 4), from_ptri(uint32_t, R_ESP + 8), from_ptriv(R_ESP + 12)); } void iFiUU_32(x64emu_t *emu, uintptr_t fcn) { iFiUU_t fn = (iFiUU_t)fcn; R_EAX = fn(from_ptri(int32_t, R_ESP + 4), from_ptri(uint64_t, R_ESP + 8), from_ptri(uint64_t, R_ESP + 16)); } void iFiUp_32(x64emu_t *emu, uintptr_t fcn) { iFiUp_t fn = (iFiUp_t)fcn; R_EAX = fn(from_ptri(int32_t, R_ESP + 4), from_ptri(uint64_t, R_ESP + 8), from_ptriv(R_ESP + 16)); } diff --git a/src/wrapped32/generated/wrapper32.h b/src/wrapped32/generated/wrapper32.h index 949274b47..dcd00e9c0 100644 --- a/src/wrapped32/generated/wrapper32.h +++ b/src/wrapped32/generated/wrapper32.h @@ -628,7 +628,6 @@ void iFiui_32(x64emu_t *emu, uintptr_t fnc); void iEiuu_32(x64emu_t *emu, uintptr_t fnc); void iFiuu_32(x64emu_t *emu, uintptr_t fnc); void iFiuL_32(x64emu_t *emu, uintptr_t fnc); -void iEiup_32(x64emu_t *emu, uintptr_t fnc); void iFiup_32(x64emu_t *emu, uintptr_t fnc); void iFiUU_32(x64emu_t *emu, uintptr_t fnc); void iFiUp_32(x64emu_t *emu, uintptr_t fnc); diff --git a/src/wrapped32/wrappedlibc.c b/src/wrapped32/wrappedlibc.c index 9209a8e44..f401bb9b8 100755 --- a/src/wrapped32/wrappedlibc.c +++ b/src/wrapped32/wrappedlibc.c @@ -47,6 +47,7 @@ #include #endif #include +#include #include "wrappedlibs.h" @@ -73,6 +74,7 @@ #include "cleanup.h" #include "box32_inputevent.h" #include "syscall_user_dispatch.h" +#include "cpumask.h" // need to undef all read / read64 stuffs! #undef pread @@ -3485,6 +3487,40 @@ EXPORT int my32_shmdt(x64emu_t* emu, void* addr) } #endif +EXPORT int my32_sched_getaffinity(x64emu_t* emu, pid_t pid, size_t sz, cpu_set_t* mask) +{ + if(!BOX64ENV(skipcpu)) + return sched_getaffinity(pid, sz, mask); + uint8_t mask_[sz]; + int ret = sched_getaffinity(pid, sz, (cpu_set_t*)mask_); + if(ret>=0) { + cpumask_shiftright(mask_, sz, BOX64ENV(skipcpu)); + cpumask_maxcpu(mask, sz, BOX64ENV(maxcpu)); + memcpy(mask, mask_, sz); + } + return ret; +} +EXPORT int my32_sched_getcpu(x64emu_t* emu) +{ + int ret = sched_getcpu(); + if(ret>=0 && BOX64ENV(skipcpu)) { + ret -= BOX64ENV(skipcpu); + if(ret<0) ret = 0; + } + return ret; +} +EXPORT int my32_sched_setaffinity(x64emu_t* emu, pid_t pid, size_t sz, cpu_set_t* mask) +{ + if(!BOX64ENV(skipcpu)) + return sched_setaffinity(pid, sz, mask); + uint8_t mask_[sz]; + memcpy(mask_, mask, sz); + cpumask_maxcpu(mask, sz, BOX64ENV(maxcpu)); + cpumask_shiftleft(mask_, sz, BOX64ENV(skipcpu)); + return sched_setaffinity(pid, sz, (cpu_set_t*)mask_); +} + + #if 0 #ifndef __NR_memfd_create #define MFD_CLOEXEC 0x0001U diff --git a/src/wrapped32/wrappedlibc_private.h b/src/wrapped32/wrappedlibc_private.h index a5a7d6458..202208e0a 100755 --- a/src/wrapped32/wrappedlibc_private.h +++ b/src/wrapped32/wrappedlibc_private.h @@ -1477,8 +1477,8 @@ GOM(scandir64, iEEpppp) //%% //GO(__sched_cpualloc, pEu) //TODO: check, return cpu_set_t* : should this be aligned/changed? GO(__sched_cpucount, iEup) //GO(__sched_cpufree, vEp) -GO(sched_getaffinity, iEiup) -GO(sched_getcpu, iEv) +GOM(sched_getaffinity, iEEiLp) +GOM(sched_getcpu, iEEv) GO(__sched_getparam, iEip) GOW(sched_getparam, iEip) GO(__sched_get_priority_max, iEi) @@ -1488,7 +1488,7 @@ GOW(sched_get_priority_min, iEi) GO(__sched_getscheduler, iEi) GOW(sched_getscheduler, iEi) //GOW(sched_rr_get_interval, iEip) -GO(sched_setaffinity, iEiup) +GOM(sched_setaffinity, iEEiLp) //GOW(sched_setparam, iEip) GO(__sched_setscheduler, iEiip) GOW(sched_setscheduler, iEiip) diff --git a/src/wrapped32/wrappedlibpthread_private.h b/src/wrapped32/wrappedlibpthread_private.h index 040b749b3..a36c13543 100755 --- a/src/wrapped32/wrappedlibpthread_private.h +++ b/src/wrapped32/wrappedlibpthread_private.h @@ -18,7 +18,7 @@ GOM(pthread_atfork, iEEppp) GOM(__pthread_atfork, iEEppp) GOM(pthread_attr_destroy, iEEp) -// pthread_attr_getaffinity_np +GOM(pthread_attr_getaffinity_np, iEEpup) GOM(pthread_attr_getdetachstate, iEEpp) GOM(pthread_attr_getguardsize, iEEpp) GOM(pthread_attr_getinheritsched, iEEpp) diff --git a/wine/wow64/CMakeLists.txt b/wine/wow64/CMakeLists.txt index fe145955e..a8a8365d7 100644 --- a/wine/wow64/CMakeLists.txt +++ b/wine/wow64/CMakeLists.txt @@ -102,6 +102,7 @@ set(WOW64_BOX64CPU_SRC "${BOX64_ROOT}/src/tools/env.c" "${BOX64_ROOT}/src/tools/dynacache.c" "${BOX64_ROOT}/src/tools/rbtree.c" + "${BOX64_ROOT}/src/tools/cpumask.c" ) add_library(wowbox64 SHARED ${WOW64_MAIN_SRC} ${MUSL_SRC} ${WOW64_BOX64CPU_SRC} ${INTERPRETER} ${DYNAREC_ASM}