spinlock.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

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 long lock;
  20. } 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. unsigned int reg1, reg2;
  28.         __asm__ __volatile("    bras  %0,1fn"
  29.                            "0:  diag  0,0,68n"
  30.                            "1:  slr   %1,%1n"
  31.                            "    cs    %1,%0,0(%2)n"
  32.                            "    jl    0bn"
  33.                            : "=&d" (reg1), "=&d" (reg2)
  34.    : "a" (&lp->lock) : "cc", "memory" );
  35. }
  36. extern inline int spin_trylock(spinlock_t *lp)
  37. {
  38. unsigned long result, reg;
  39. __asm__ __volatile("    slr   %0,%0n"
  40.    "    basr  %1,0n"
  41.    "0:  cs    %0,%1,0(%2)"
  42.    : "=&d" (result), "=&d" (reg)
  43.    : "a" (&lp->lock) : "cc", "memory" );
  44. return !result;
  45. }
  46. extern inline void spin_unlock(spinlock_t *lp)
  47. {
  48. __asm__ __volatile("    xc 0(4,%0),0(%0)n"
  49.                            "    bcr 15,0"
  50.    : : "a" (&lp->lock) : "memory", "cc" );
  51. }
  52. /*
  53.  * Read-write spinlocks, allowing multiple readers
  54.  * but only one writer.
  55.  *
  56.  * NOTE! it is quite common to have readers in interrupts
  57.  * but no interrupt writers. For those circumstances we
  58.  * can "mix" irq-safe locks - any writer needs to get a
  59.  * irq-safe write-lock, but readers can get non-irqsafe
  60.  * read-locks.
  61.  */
  62. typedef struct {
  63. volatile unsigned long lock;
  64. volatile unsigned long owner_pc;
  65. } rwlock_t;
  66. #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
  67. #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
  68. #define read_lock(rw)   
  69.         asm volatile("   l     2,0(%0)n"   
  70.                      "   j     1fn"     
  71.                      "0: diag  0,0,68n" 
  72.                      "1: la    2,0(2)n"     /* clear high (=write) bit */ 
  73.                      "   la    3,1(2)n"     /* one more reader */ 
  74.                      "   cs    2,3,0(%0)n"  /* try to write new value */ 
  75.                      "   jl    0b"       
  76.                      : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
  77. #define read_unlock(rw) 
  78.         asm volatile("   l     2,0(%0)n"   
  79.                      "   j     1fn"     
  80.                      "0: diag  0,0,68n" 
  81.                      "1: lr    3,2n"    
  82.                      "   ahi   3,-1n"    /* one less reader */ 
  83.                      "   cs    2,3,0(%0)n" 
  84.                      "   jl    0b"       
  85.                      : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
  86. #define write_lock(rw) 
  87.         asm volatile("   lhi   3,1n"    
  88.                      "   sll   3,31n"    /* new lock value = 0x80000000 */ 
  89.                      "   j     1fn"     
  90.                      "0: diag  0,0,68n" 
  91.                      "1: slr   2,2n"     /* old lock value must be 0 */ 
  92.                      "   cs    2,3,0(%0)n" 
  93.                      "   jl    0b"       
  94.                      : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
  95. #define write_unlock(rw) 
  96.         asm volatile("   slr   3,3n"     /* new lock value = 0 */ 
  97.                      "   j     1fn"     
  98.                      "0: diag  0,0,68n" 
  99.                      "1: lhi   2,1n"    
  100.                      "   sll   2,31n"    /* old lock value must be 0x80000000 */ 
  101.                      "   cs    2,3,0(%0)n" 
  102.                      "   jl    0b"       
  103.                      : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
  104. #endif /* __ASM_SPINLOCK_H */