Revision 15a51156

b/exec-all.h
297 297
extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
298 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 324
#if defined(__powerpc__)
301 325
static inline int testandset (int *p)
302 326
{
......
396 420
                         : "cc","memory");
397 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 450
#elif defined(__ia64)
400 451

  
401 452
#include <ia64intrin.h>
......
428 479
#error unimplemented CPU support
429 480
#endif
430 481

  
431
typedef int spinlock_t;
432

  
433
#define SPIN_LOCK_UNLOCKED 0
434

  
435 482
#if defined(CONFIG_USER_ONLY)
436 483
static inline void spin_lock(spinlock_t *lock)
437 484
{
......
440 487

  
441 488
static inline void spin_unlock(spinlock_t *lock)
442 489
{
443
    *lock = 0;
490
    resetlock(lock);
444 491
}
445 492

  
446 493
static inline int spin_trylock(spinlock_t *lock)
b/exec.c
1215 1215
void cpu_interrupt(CPUState *env, int mask)
1216 1216
{
1217 1217
    TranslationBlock *tb;
1218
    static int interrupt_lock;
1218
    static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
1219 1219

  
1220 1220
    env->interrupt_request |= mask;
1221 1221
    /* if the cpu is currently executing code, we must unlink it and
......
1224 1224
    if (tb && !testandset(&interrupt_lock)) {
1225 1225
        env->current_tb = NULL;
1226 1226
        tb_reset_jump_recursive(tb);
1227
        interrupt_lock = 0;
1227
        resetlock(&interrupt_lock);
1228 1228
    }
1229 1229
}
1230 1230

  

Also available in: Unified diff