[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Qemu threading support?
From: |
doremi |
Subject: |
[Qemu-devel] Qemu threading support? |
Date: |
Thu, 2 Apr 2009 15:43:31 +0800 |
Hello,
These days I have to add multi-threading support for Qemu (Performace
is not important for me). But it's very complicated, could anybody do
me a favor? Thanks~
(host machine is x86_64, target is x86)
The following steps are how I try to do:
1. Adding a structure LOOKUP_TABLE in vl.c
+#define num_thread 2
+
+struct LOOKUP_TABLE {
+ pthread_t tid;
+ CPUState* env_ptr;
+} lookup_tbl[num_thread];
+
+static CPUState* lookup(pthread_t tid)
+{
+ int i = 0;
+ // while(lookup_tbl[0].tid == 0);
+ /* we examined in host_alarm_handler */
+ for (i = 0; i < num_thread; ++i) {
+ if (lookup_tbl[i].tid == tid)
+ return lookup_tbl[i].env_ptr;
+ }
+ printf("Error FILE: %s, LINE: %d\n", __FILE__, __LINE__);
+ return NULL;
+}
+
2. modify host_alarm_handler() in vl.c
+#if 0
if (env) {
/* stop the currently executing cpu because a timer occured */
cpu_interrupt(env, CPU_INTERRUPT_EXIT);
}
+#endif
+ int j;
+ for (j = 0; j < num_thread; ++j) {
+ if (lookup_tbl[j].tid != 0)
+ pthread_kill(lookup_tbl[j].tid, SIGUSR1);
+ }
3. adding 2 thread function in vl.c
+static void *cpu_exec2(void *ptr)
+{
+ lookup_tbl[1].env_ptr = ptr;
+ for (;;) {
+ lookup_tbl[1].env_ptr = ptr;
+ cpu_exec(ptr);
+ lookup_tbl[1].env_ptr = NULL;
+ main_loop_wait(0);
+ }
+ return NULL;
+}
+
+static void *cpu_exec1(void *ptr)
+{
+ lookup_tbl[0].env_ptr = ptr;
+
+ pthread_create(&lookup_tbl[1].tid, NULL, cpu_exec2, first_cpu->next_cpu);
+
+ for (;;) {
+ lookup_tbl[0].env_ptr = ptr;
+ cpu_exec(ptr);
+ lookup_tbl[0].env_ptr = NULL;
+ main_loop_wait(0);
+ }
+ return NULL;
+}
4. adding some functions for thread signal
+static void thread_signal_handler(int sig)
+{
+ struct CPUState *env1;
+ env1 = lookup(pthread_self());
+ //env1 = first_cpu;
+ if (env1) { /* ???? if (env) ... */
+ cpu_interrupt(env1, CPU_INTERRUPT_EXIT);
+ }
+}
+
+static void init_signal(void)
+{
+ struct sigaction act;
+ sigfillset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = thread_signal_handler;
+ sigaction(SIGUSR1, &act, NULL);
+}
5. main_loop() in vl.c
+ int rets[num_thread], *status[num_thread];
cur_cpu = first_cpu;
next_cpu = cur_cpu->next_cpu ?: first_cpu;
+
+ memset(lookup_tbl, 0, sizeof(lookup_tbl));
+ pthread_create(&lookup_tbl[0].tid, NULL, cpu_exec1, first_cpu);
6. in cpu-all.h
register CPUState *cpu_single_env asm("r12");
First, I try create 2 thread, each thread's cpu_single_env is replaced
to asm("r12"),
because cpu_single_env is a global variable,
If I put it into a register, it implied local variable.
Second, each thread execute the same thing:
cpu_exec() and then force main_loop_wait(0)
Third, I modified host_alarm_handler(), if a timer interrupt occurred,
the original method is check whether env is NULL or not, then call
cpu_interrupt(). The new way is call pthread_kill() to every thread
by SIGUSR1,
when every thread get the signal, it will check
lookup_tbl's env is valid or not, then call cpu_interrupt
My objective is to build a multi-thread qemu,
and run linux kernel,
and the performace and atomic operation is not important, but these
code doesn't work, it may segmentation fault when disas_insn(pc_start
= 0).
What can I do for next step? Which or where step I was wrong?
Or can anybody give me a multi-thread qemu (even if it doesn't work
prefect), thanks~
all my code is in
http://140.123.102.106/qemu.tgz
compile argument:
./configure --target-list=i386-softmmu --disable-kqemu
- [Qemu-devel] Qemu threading support?,
doremi <=