Mwait cleanup
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 2 Jan 2015 19:36:01 +0000 (14:36 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 5 Jan 2015 21:24:09 +0000 (16:24 -0500)
"rax" isn't the input specifier; it is "a".  That loads void* eax into rax, and
we don't need the movq to rax.

Also, we were leaving the monitor value in rax instead of using an appropriate
hint.  I don't know what passing gibberish does to mwait.  Incidentally,
nothing I pass here matters in qemu - the VM still hogs CPU time.

Finally, any real use of monitor/mwait needs to deal with the race on the
monitored address.  After we monitor, we should check and see if the address
has been changed, similar to how futexes and CAS work.  We'll probably need a
couple helpers and a nice top-level function for this.

kern/arch/x86/arch.h

index 6ad68d9..d2f6d55 100644 (file)
@@ -80,8 +80,14 @@ static inline uint64_t read_tscp(void)
 
 static inline void mwait(void *eax)
 {
-  asm volatile("movq %0, %%rax; xorq %%rcx, %%rcx; xorq %%rdx, %%rdx; monitor; mwait\n":
-              : "rax"(eax));
+       asm volatile("xorq %%rcx, %%rcx;"
+                    "xorq %%rdx, %%rdx;"
+                    "monitor;"
+                                /* this is racy, generically.  we never check if the write to
+                                 * the monitored address happened already. */
+                    "movq $0, %%rax;"  /* c-state hint.  this is C1 */
+                    "mwait;"
+                    : : "a"(eax));
 }
 /* Check out k/a/x86/rdtsc_test.c for more info */
 static inline uint64_t read_tsc_serialized(void)