spinlock.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  include/asm-s390/spinlock.h
  3.  *
  4.  *  S390 version
  5.  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6.  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
  7.  *
  8.  *  Derived from "include/asm-i386/spinlock.h"
  9.  */
  10. #ifndef __ASM_SPINLOCK_H
  11. #define __ASM_SPINLOCK_H
  12. /*
  13.  * Simple spin lock operations.  There are two variants, one clears IRQ's
  14.  * on the local processor, one does not.
  15.  *
  16.  * We make no fairness assumptions. They have a cost.
  17.  */
  18. typedef struct {
  19. volatile unsigned int lock;
  20. } __attribute__ ((aligned (4))) spinlock_t;
  21. #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
  22. #define spin_lock_init(lp) do { (lp)->lock = 0; } while(0)
  23. #define spin_unlock_wait(lp) do { barrier(); } while(((volatile spinlock_t *)(lp))->lock)
  24. #define spin_is_locked(x) ((x)->lock != 0)
  25. extern inline void spin_lock(spinlock_t *lp)
  26. {
  27.         __asm__ __volatile("    bras  1,1fn"
  28.                            "0:  # diag  0,0,68n"
  29.                            "1:  slr   0,0n"
  30.                            "    cs    0,1,0(%0)n"
  31.                            "    jl    0bn"
  32.                            : : "a" (&lp->lock) : "0", "1", "cc", "memory" );
  33. }
  34. extern inline int spin_trylock(spinlock_t *lp)
  35. {
  36. unsigned int result;
  37. __asm__ __volatile("    slr   %0,%0n"
  38.    "    basr  1,0n"
  39.    "0:  cs    %0,1,0(%1)"
  40.    : "=&d" (result)
  41.    : "a" (&lp->lock) : "1", "cc", "memory" );
  42. return !result;
  43. }
  44. extern inline void spin_unlock(spinlock_t *lp)
  45. {
  46. __asm__ __volatile("    xc 0(4,%0),0(%0)n"
  47.                            "    bcr 15,0"
  48.    : : "a" (&lp->lock) : "memory", "cc" );
  49. }
  50. /*
  51.  * Read-write spinlocks, allowing multiple readers
  52.  * but only one writer.
  53.  *
  54.  * NOTE! it is quite common to have readers in interrupts
  55.  * but no interrupt writers. For those circumstances we
  56.  * can "mix" irq-safe locks - any writer needs to get a
  57.  * irq-safe write-lock, but readers can get non-irqsafe
  58.  * read-locks.
  59.  */
  60. typedef struct {
  61. volatile unsigned long lock;
  62. volatile unsigned long owner_pc;
  63. } rwlock_t;
  64. #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
  65. #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
  66. #define read_lock(rw)   
  67.         asm volatile("   lg    2,0(%0)n"   
  68.                      "   j     1fn"     
  69.                      "0: # diag  0,0,68n" 
  70.                      "1: nihh  2,0x7fffn" /* clear high (=write) bit */ 
  71.                      "   la    3,1(2)n"   /* one more reader */  
  72.                      "   csg   2,3,0(%0)n" /* try to write new value */ 
  73.                      "   jl    0b"       
  74.                      : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
  75. #define read_unlock(rw) 
  76.         asm volatile("   lg    2,0(%0)n"   
  77.                      "   j     1fn"     
  78.                      "0: # diag  0,0,68n" 
  79.                      "1: lgr   3,2n"    
  80.                      "   bctgr 3,0n"    /* one less reader */ 
  81.                      "   csg   2,3,0(%0)n" 
  82.                      "   jl    0b"       
  83.                      : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
  84. #define write_lock(rw) 
  85.         asm volatile("   llihh 3,0x8000n" /* new lock value = 0x80...0 */ 
  86.                      "   j     1fn"       
  87.                      "0: # diag  0,0,68n"   
  88.                      "1: slgr  2,2n"      /* old lock value must be 0 */ 
  89.                      "   csg   2,3,0(%0)n" 
  90.                      "   jl    0b"         
  91.                      : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
  92. #define write_unlock(rw) 
  93.         asm volatile("   slgr  3,3n"      /* new lock value = 0 */ 
  94.                      "   j     1fn"       
  95.                      "0: # diag  0,0,68n"   
  96.                      "1: llihh 2,0x8000n" /* old lock value must be 0x8..0 */
  97.                      "   csg   2,3,0(%0)n"   
  98.                      "   jl    0b"         
  99.                      : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
  100. #endif /* __ASM_SPINLOCK_H */