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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * SMP locks primitives for building ix86 locks
  3.  * (not yet used).
  4.  *
  5.  * Alan Cox, alan@cymru.net, 1995
  6.  */
  7.  
  8. /*
  9.  * This would be much easier but far less clear and easy
  10.  * to borrow for other processors if it was just assembler.
  11.  */
  12. extern __inline__ void prim_spin_lock(struct spinlock *sp)
  13. {
  14. int processor=smp_processor_id();
  15. /*
  16.  * Grab the lock bit
  17.  */
  18.  
  19. while(lock_set_bit(0,&sp->lock))
  20. {
  21. /*
  22.  * Failed, but that's cos we own it!
  23.  */
  24.  
  25. if(sp->cpu==processor)
  26. {
  27. sp->users++;
  28. return 0;
  29. }
  30. /*
  31.  * Spin in the cache S state if possible
  32.  */
  33. while(sp->lock)
  34. {
  35. /*
  36.  * Wait for any invalidates to go off
  37.  */
  38.  
  39. if(smp_invalidate_needed&(1<<processor))
  40. while(lock_clear_bit(processor,&smp_invalidate_needed))
  41. local_flush_tlb();
  42. sp->spins++;
  43. }
  44. /*
  45.  * Someone wrote the line, we go 'I' and get
  46.  * the cache entry. Now try to regrab
  47.  */
  48. }
  49. sp->users++;sp->cpu=processor;
  50. return 1;
  51. }
  52. /*
  53.  * Release a spin lock
  54.  */
  55.  
  56. extern __inline__ int prim_spin_unlock(struct spinlock *sp)
  57. {
  58. /* This is safe. The decrement is still guarded by the lock. A multilock would
  59.    not be safe this way */
  60. if(!--sp->users)
  61. {
  62. lock_clear_bit(0,&sp->lock);sp->cpu= NO_PROC_ID;
  63. return 1;
  64. }
  65. return 0;
  66. }
  67. /*
  68.  * Non blocking lock grab
  69.  */
  70.  
  71. extern __inline__ int prim_spin_lock_nb(struct spinlock *sp)
  72. {
  73. if(lock_set_bit(0,&sp->lock))
  74. return 0; /* Locked already */
  75. sp->users++;
  76. return 1; /* We got the lock */
  77. }
  78. /*
  79.  * These wrap the locking primitives up for usage
  80.  */
  81.  
  82. extern __inline__ void spinlock(struct spinlock *sp)
  83. {
  84. if(sp->priority<current->lock_order)
  85. panic("lock order violation: %s (%d)n", sp->name, current->lock_order);
  86. if(prim_spin_lock(sp))
  87. {
  88. /*
  89.  * We got a new lock. Update the priority chain
  90.  */
  91. sp->oldpri=current->lock_order;
  92. current->lock_order=sp->priority;
  93. }
  94. }
  95. extern __inline__ void spinunlock(struct spinlock *sp)
  96. {
  97. if(current->lock_order!=sp->priority)
  98. panic("lock release order violation %s (%d)n", sp->name, current->lock_order);
  99. if(prim_spin_unlock(sp))
  100. {
  101. /*
  102.  * Update the debugging lock priority chain. We dumped
  103.  * our last right to the lock.
  104.  */
  105. current->lock_order=sp->oldpri;
  106. }
  107. }
  108. extern __inline__ void spintestlock(struct spinlock *sp)
  109. {
  110. /*
  111.  * We do no sanity checks, it's legal to optimistically
  112.  * get a lower lock.
  113.  */
  114. prim_spin_lock_nb(sp);
  115. }
  116. extern __inline__ void spintestunlock(struct spinlock *sp)
  117. {
  118. /*
  119.  * A testlock doesn't update the lock chain so we
  120.  * must not update it on free
  121.  */
  122. prim_spin_unlock(sp);
  123. }