mirror of
https://github.com/xemu-project/xemu.git
synced 2024-06-02 20:18:25 -04:00
t
This commit is contained in:
parent
e5dd3cc1ce
commit
c32cb4f6a3
|
@ -24,6 +24,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/thread.h"
|
||||||
#include "sysemu/tcg.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "sysemu/replay.h"
|
#include "sysemu/replay.h"
|
||||||
#include "sysemu/cpu-timers.h"
|
#include "sysemu/cpu-timers.h"
|
||||||
|
@ -62,11 +63,61 @@ static void mttcg_force_rcu(Notifier *notify, void *data)
|
||||||
* current CPUState for a given thread.
|
* current CPUState for a given thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void qemu_thread_set_affinity_simple(int core_id) {
|
||||||
|
int nbits =
|
||||||
|
#ifdef _WIN32
|
||||||
|
64
|
||||||
|
#else
|
||||||
|
sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
|
#endif
|
||||||
|
unsigned long *bitmap = bitmap_new(nbits);
|
||||||
|
|
||||||
|
core_id = core_id % nbits;
|
||||||
|
set_bit(core_id, bitmap);
|
||||||
|
|
||||||
|
QemuThread thread;
|
||||||
|
qemu_thread_get_self(&thread);
|
||||||
|
|
||||||
|
int ret = qemu_thread_set_affinity(&thread, bitmap, nbits);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "Setting CPU affinity failed\n");
|
||||||
|
}
|
||||||
|
g_free(bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qemu_thread_clear_affinity(void) {
|
||||||
|
int nbits =
|
||||||
|
#ifdef _WIN32
|
||||||
|
64
|
||||||
|
#else
|
||||||
|
sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
|
#endif
|
||||||
|
unsigned long *bitmap = bitmap_new(nbits);
|
||||||
|
|
||||||
|
for (int i = 0; i < nbits; i++) {
|
||||||
|
set_bit(i, bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
QemuThread thread;
|
||||||
|
qemu_thread_get_self(&thread);
|
||||||
|
|
||||||
|
int ret = qemu_thread_set_affinity(&thread, bitmap, nbits);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "Setting CPU affinity failed\n");
|
||||||
|
}
|
||||||
|
g_free(bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "ui/xemu-settings.h"
|
||||||
|
static bool pinned = false;
|
||||||
|
|
||||||
static void *mttcg_cpu_thread_fn(void *arg)
|
static void *mttcg_cpu_thread_fn(void *arg)
|
||||||
{
|
{
|
||||||
MttcgForceRcuNotifier force_rcu;
|
MttcgForceRcuNotifier force_rcu;
|
||||||
CPUState *cpu = arg;
|
CPUState *cpu = arg;
|
||||||
|
|
||||||
|
qemu_thread_set_affinity_simple(0);
|
||||||
|
|
||||||
assert(tcg_enabled());
|
assert(tcg_enabled());
|
||||||
g_assert(!icount_enabled());
|
g_assert(!icount_enabled());
|
||||||
|
|
||||||
|
@ -89,6 +140,15 @@ static void *mttcg_cpu_thread_fn(void *arg)
|
||||||
cpu->exit_request = 1;
|
cpu->exit_request = 1;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (pinned != g_config.perf.pin_cpu_thread) {
|
||||||
|
if (g_config.perf.pin_cpu_thread) {
|
||||||
|
qemu_thread_set_affinity_simple(0);
|
||||||
|
} else {
|
||||||
|
qemu_thread_clear_affinity();
|
||||||
|
}
|
||||||
|
pinned = g_config.perf.pin_cpu_thread;
|
||||||
|
}
|
||||||
|
|
||||||
if (cpu_can_run(cpu)) {
|
if (cpu_can_run(cpu)) {
|
||||||
int r;
|
int r;
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
|
|
|
@ -209,3 +209,6 @@ perf:
|
||||||
cache_shaders:
|
cache_shaders:
|
||||||
type: bool
|
type: bool
|
||||||
default: true
|
default: true
|
||||||
|
pin_cpu_thread:
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
|
|
@ -58,6 +58,8 @@ void MainMenuGeneralView::Draw()
|
||||||
Toggle("Hard FPU emulation", &g_config.perf.hard_fpu,
|
Toggle("Hard FPU emulation", &g_config.perf.hard_fpu,
|
||||||
"Use hardware-accelerated floating point emulation (requires restart)");
|
"Use hardware-accelerated floating point emulation (requires restart)");
|
||||||
#endif
|
#endif
|
||||||
|
Toggle("Set CPU thread affinity", &g_config.perf.pin_cpu_thread,
|
||||||
|
"Set CPU thread affinity to Logical CPU 0");
|
||||||
|
|
||||||
Toggle("Cache shaders to disk", &g_config.perf.cache_shaders,
|
Toggle("Cache shaders to disk", &g_config.perf.cache_shaders,
|
||||||
"Reduce stutter in games by caching previously generated shaders");
|
"Reduce stutter in games by caching previously generated shaders");
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "qemu/thread.h"
|
#include "qemu/thread.h"
|
||||||
#include "qemu/notify.h"
|
#include "qemu/notify.h"
|
||||||
#include "qemu-thread-common.h"
|
#include "qemu-thread-common.h"
|
||||||
|
#include "qemu/bitmap.h"
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
|
||||||
static bool name_threads;
|
static bool name_threads;
|
||||||
|
@ -480,7 +481,24 @@ void qemu_thread_create(QemuThread *thread, const char *name,
|
||||||
int qemu_thread_set_affinity(QemuThread *thread, unsigned long *host_cpus,
|
int qemu_thread_set_affinity(QemuThread *thread, unsigned long *host_cpus,
|
||||||
unsigned long nbits)
|
unsigned long nbits)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
DWORD_PTR affinity = 0;
|
||||||
|
DWORD_PTR affinity_prev;
|
||||||
|
unsigned long value;
|
||||||
|
assert(nbits <= 64);
|
||||||
|
|
||||||
|
value = find_first_bit(host_cpus, nbits);
|
||||||
|
while (value < nbits) {
|
||||||
|
affinity |= 1ULL << value;
|
||||||
|
value = find_next_bit(host_cpus, nbits, value + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
affinity_prev =
|
||||||
|
SetThreadAffinityMask(qemu_thread_get_handle(thread), affinity);
|
||||||
|
if (!affinity_prev) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemu_thread_get_affinity(QemuThread *thread, unsigned long **host_cpus,
|
int qemu_thread_get_affinity(QemuThread *thread, unsigned long **host_cpus,
|
||||||
|
|
Loading…
Reference in a new issue