qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]