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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: dec_and_lock.S,v 1.5 2001/11/18 00:12:56 davem Exp $
  2.  * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()"
  3.  *                 using cas and ldstub instructions.
  4.  *
  5.  * Copyright (C) 2000 David S. Miller (davem@redhat.com)
  6.  */
  7. #include <linux/config.h>
  8. #ifndef CONFIG_DEBUG_SPINLOCK
  9. .text
  10. .align 64
  11. /* CAS basically works like this:
  12.  *
  13.  * void CAS(MEM, REG1, REG2)
  14.  * {
  15.  *   START_ATOMIC();
  16.  *   if (*(MEM) == REG1) {
  17.  *     TMP = *(MEM);
  18.  *     *(MEM) = REG2;
  19.  *     REG2 = TMP;
  20.  *   } else
  21.  *     REG2 = *(MEM);
  22.  *   END_ATOMIC();
  23.  * }
  24.  */
  25. .globl atomic_dec_and_lock
  26. atomic_dec_and_lock: /* %o0 = counter, %o1 = lock */
  27. loop1: lduw [%o0], %g5
  28. subcc %g5, 1, %g7
  29. be,pn %icc, to_zero
  30.  nop
  31. nzero: cas [%o0], %g5, %g7
  32. cmp %g5, %g7
  33. bne,pn %icc, loop1
  34.  mov 0, %g1
  35. out:
  36. membar #StoreLoad | #StoreStore
  37. retl
  38.  mov %g1, %o0
  39. to_zero:
  40. ldstub [%o1], %g3
  41. brnz,pn %g3, spin_on_lock
  42.  membar #StoreLoad | #StoreStore
  43. loop2: cas [%o0], %g5, %g7 /* ASSERT(g7 == 0) */
  44. cmp %g5, %g7
  45. be,pt %icc, out
  46.  mov 1, %g1
  47. lduw [%o0], %g5
  48. subcc %g5, 1, %g7
  49. be,pn %icc, loop2
  50.  nop
  51. membar #StoreStore | #LoadStore
  52. stb %g0, [%o1]
  53. b,pt %xcc, nzero
  54.  nop
  55. spin_on_lock:
  56. ldub [%o1], %g3
  57. brnz,pt %g3, spin_on_lock
  58.  membar #LoadLoad
  59. ba,pt %xcc, to_zero
  60.  nop
  61. nop
  62. #endif /* !(CONFIG_DEBUG_SPINLOCK) */