Commit 15a5115690558ad65de02d9b9bb4ec89bc4cf8ac

Authored by aurel32
1 parent f9e7bcfe

Use spinlock_t for interrupt_lock, lock support for HPPA (Stuart Brady)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4118 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 54 additions and 7 deletions
exec-all.h
@@ -297,6 +297,30 @@ extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; @@ -297,6 +297,30 @@ extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
297 extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; 297 extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
298 extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; 298 extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
299 299
  300 +#if defined(__hppa__)
  301 +
  302 +typedef int spinlock_t[4];
  303 +
  304 +#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 }
  305 +
  306 +static inline void resetlock (spinlock_t *p)
  307 +{
  308 + (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1;
  309 +}
  310 +
  311 +#else
  312 +
  313 +typedef int spinlock_t;
  314 +
  315 +#define SPIN_LOCK_UNLOCKED 0
  316 +
  317 +static inline void resetlock (spinlock_t *p)
  318 +{
  319 + *p = SPIN_LOCK_UNLOCKED;
  320 +}
  321 +
  322 +#endif
  323 +
300 #if defined(__powerpc__) 324 #if defined(__powerpc__)
301 static inline int testandset (int *p) 325 static inline int testandset (int *p)
302 { 326 {
@@ -396,6 +420,33 @@ static inline int testandset (int *p) @@ -396,6 +420,33 @@ static inline int testandset (int *p)
396 : "cc","memory"); 420 : "cc","memory");
397 return ret; 421 return ret;
398 } 422 }
  423 +#elif defined(__hppa__)
  424 +
  425 +/* Because malloc only guarantees 8-byte alignment for malloc'd data,
  426 + and GCC only guarantees 8-byte alignment for stack locals, we can't
  427 + be assured of 16-byte alignment for atomic lock data even if we
  428 + specify "__attribute ((aligned(16)))" in the type declaration. So,
  429 + we use a struct containing an array of four ints for the atomic lock
  430 + type and dynamically select the 16-byte aligned int from the array
  431 + for the semaphore. */
  432 +#define __PA_LDCW_ALIGNMENT 16
  433 +static inline void *ldcw_align (void *p) {
  434 + unsigned long a = (unsigned long)p;
  435 + a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1);
  436 + return (void *)a;
  437 +}
  438 +
  439 +static inline int testandset (spinlock_t *p)
  440 +{
  441 + unsigned int ret;
  442 + p = ldcw_align(p);
  443 + __asm__ __volatile__("ldcw 0(%1),%0"
  444 + : "=r" (ret)
  445 + : "r" (p)
  446 + : "memory" );
  447 + return !ret;
  448 +}
  449 +
399 #elif defined(__ia64) 450 #elif defined(__ia64)
400 451
401 #include <ia64intrin.h> 452 #include <ia64intrin.h>
@@ -428,10 +479,6 @@ static inline int testandset (int *p) @@ -428,10 +479,6 @@ static inline int testandset (int *p)
428 #error unimplemented CPU support 479 #error unimplemented CPU support
429 #endif 480 #endif
430 481
431 -typedef int spinlock_t;  
432 -  
433 -#define SPIN_LOCK_UNLOCKED 0  
434 -  
435 #if defined(CONFIG_USER_ONLY) 482 #if defined(CONFIG_USER_ONLY)
436 static inline void spin_lock(spinlock_t *lock) 483 static inline void spin_lock(spinlock_t *lock)
437 { 484 {
@@ -440,7 +487,7 @@ static inline void spin_lock(spinlock_t *lock) @@ -440,7 +487,7 @@ static inline void spin_lock(spinlock_t *lock)
440 487
441 static inline void spin_unlock(spinlock_t *lock) 488 static inline void spin_unlock(spinlock_t *lock)
442 { 489 {
443 - *lock = 0; 490 + resetlock(lock);
444 } 491 }
445 492
446 static inline int spin_trylock(spinlock_t *lock) 493 static inline int spin_trylock(spinlock_t *lock)
@@ -1215,7 +1215,7 @@ void cpu_set_log_filename(const char *filename) @@ -1215,7 +1215,7 @@ void cpu_set_log_filename(const char *filename)
1215 void cpu_interrupt(CPUState *env, int mask) 1215 void cpu_interrupt(CPUState *env, int mask)
1216 { 1216 {
1217 TranslationBlock *tb; 1217 TranslationBlock *tb;
1218 - static int interrupt_lock; 1218 + static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
1219 1219
1220 env->interrupt_request |= mask; 1220 env->interrupt_request |= mask;
1221 /* if the cpu is currently executing code, we must unlink it and 1221 /* if the cpu is currently executing code, we must unlink it and
@@ -1224,7 +1224,7 @@ void cpu_interrupt(CPUState *env, int mask) @@ -1224,7 +1224,7 @@ void cpu_interrupt(CPUState *env, int mask)
1224 if (tb && !testandset(&interrupt_lock)) { 1224 if (tb && !testandset(&interrupt_lock)) {
1225 env->current_tb = NULL; 1225 env->current_tb = NULL;
1226 tb_reset_jump_recursive(tb); 1226 tb_reset_jump_recursive(tb);
1227 - interrupt_lock = 0; 1227 + resetlock(&interrupt_lock);
1228 } 1228 }
1229 } 1229 }
1230 1230