Ticket #224: spinlock_debug.diff

File spinlock_debug.diff, 2.2 kB (added by growler, 1 year ago)

Spinlock debugging

  • eaccelerator-0.9.5.1/x86_spinlocks.h

    old new  
    3232 
    3333#define spinlock_init(rw)  do { (rw)->lock = 0x00000001; (rw)->pid=-1; (rw)->locked=0;} while(0) 
    3434 
    35 #define spinlock_try_lock(rw)  asm volatile("lock ; decl %0" :"=m" ((rw)->lock) : : "memory") 
    36 #define _spinlock_unlock(rw)   asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory") 
     35#define _spinlock_atomic_decrement(rw)  asm volatile("lock ; decl %0" :"=m" ((rw)->lock) : : "memory") 
     36#define _spinlock_atomic_increment(rw)   asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory") 
     37 
     38#define MAXSPINS 1000 
     39#define MAXYIELDS 10000 
    3740 
    3841static inline void yield() 
    3942{ 
    40   struct timeval t; 
    41  
    42   t.tv_sec = 0; 
    43   t.tv_usec = 100; 
    44   select(0, NULL, NULL, NULL, &t); 
     43#ifdef ZEND_WIN32 
     44  // Windows yields on a sleep(0) 
     45  sleep(0); 
     46#else 
     47  // POSIX flavoured yielding 
     48  sched_yield(); 
     49#endif 
    4550} 
    4651 
    4752static inline void spinlock_unlock(spinlock_t* rw) { 
    4853  if (rw->locked && (rw->pid == getpid())) { 
    4954    rw->pid = 0; 
    5055    rw->locked = 0; 
    51     _spinlock_unlock(rw); 
     56    _spinlock_atomic_increment(rw); 
    5257  } 
    5358} 
    5459 
    5560static inline void spinlock_lock(spinlock_t* rw) 
    5661{ 
     62  int spins = MAXSPINS; 
     63  int yields = MAXYIELDS; 
     64 
     65  if (rw->locked && (rw->pid == getpid())) { 
     66    fprintf(stderr, "eA: ERROR I'm attempting to take a lock I already have. My pid %d\r\n", getpid()); 
     67    return; 
     68  } 
     69 
    5770  while (1) { 
    58     spinlock_try_lock(rw); 
     71    _spinlock_atomic_decrement(rw); 
    5972    if (rw->lock == 0) { 
     73      if (rw->locked == 1) 
     74        fprintf(stderr, "eA: ERROR lock in inconsistant state. I've just taken it, but it's already marked as locked. I am %d, lock was held by %d\r\n", getpid(), rw->pid); 
    6075      rw->pid = getpid(); 
    6176      rw->locked = 1; 
    6277      return; 
    6378    } 
    64     _spinlock_unlock(rw); 
    65     yield(); 
     79    _spinlock_atomic_increment(rw); 
     80 
     81    --spins; 
     82    if (spins == 0) { 
     83      spins = MAXSPINS; 
     84      yields--; 
     85      if (yields == 0) { 
     86        yields = MAXYIELDS; 
     87        fprintf(stderr, "eA: WARNING I've been spinning for a while trying to get a lock. My pid %d, lock held by %d\r\n", getpid(), rw->pid); 
     88        fflush(stderr); 
     89      } 
     90      yield(); 
     91    } 
    6692  } 
    6793} 
    6894