atomic.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. #ifndef _SHIM_ATOMIC_H_
  4. #define _SHIM_ATOMIC_H_
  5. #define LOCK_PREFIX "\n\tlock; "
  6. #define ATOMIC_INIT(i) { (i) }
  7. static inline volatile int atomic_read (const struct atomic_int * v)
  8. {
  9. return v->counter;
  10. }
  11. static inline void atomic_set (struct atomic_int * v, int i)
  12. {
  13. v->counter = i;
  14. }
  15. static inline void atomic_add (int i, struct atomic_int * v)
  16. {
  17. asm volatile(LOCK_PREFIX "addl %1,%0"
  18. : "+m" (v->counter)
  19. : "ir" (i));
  20. }
  21. static inline void atomic_sub (int i, struct atomic_int * v)
  22. {
  23. asm volatile(LOCK_PREFIX "subl %1,%0"
  24. : "+m" (v->counter)
  25. : "ir" (i));
  26. }
  27. static inline int atomic_sub_and_test (int i, struct atomic_int * v)
  28. {
  29. unsigned char c;
  30. asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
  31. : "+m" (v->counter), "=qm" (c)
  32. : "ir" (i) : "memory");
  33. return c;
  34. }
  35. /* Return 0 if the value drops below zero, 1 if >= 0 */
  36. static inline int atomic_sub_and_test_nonnegative (int i, struct atomic_int * v)
  37. {
  38. unsigned char c;
  39. asm volatile(LOCK_PREFIX "subl %2,%0; setns %1"
  40. : "+m" (v->counter), "=qm" (c)
  41. : "ir" (i) : "memory");
  42. return c;
  43. }
  44. static inline void atomic_inc (struct atomic_int * v)
  45. {
  46. asm volatile(LOCK_PREFIX "incl %0"
  47. : "+m" (v->counter));
  48. }
  49. static inline int atomic_inc_and_test (struct atomic_int * v)
  50. {
  51. unsigned char c;
  52. asm volatile(LOCK_PREFIX "incl %0; sete %1"
  53. : "+m" (v->counter), "=qm" (c)
  54. : : "memory");
  55. return c != 0;
  56. }
  57. static inline void atomic_dec (struct atomic_int * v)
  58. {
  59. asm volatile(LOCK_PREFIX "decl %0"
  60. : "+m" (v->counter));
  61. }
  62. static inline int atomic_dec_and_test (struct atomic_int * v)
  63. {
  64. unsigned char c;
  65. asm volatile(LOCK_PREFIX "decl %0; sete %1"
  66. : "+m" (v->counter), "=qm" (c)
  67. : : "memory");
  68. return c != 0;
  69. }
  70. /* Return 0 if the value drops below zero, 1 if >= 0 */
  71. static inline int atomic_dec_and_test_nonnegative (struct atomic_int * v)
  72. {
  73. unsigned char c;
  74. asm volatile(LOCK_PREFIX "decl %0; setns %1"
  75. : "+m" (v->counter), "=qm" (c)
  76. : : "memory");
  77. return c;
  78. }
  79. #ifndef __i386__
  80. # include "cmpxchg_64.h"
  81. #else
  82. # include "cmpxchg_32.h"
  83. #endif
  84. static inline int atomic_cmpxchg (struct atomic_int * v, int old, int new)
  85. {
  86. return cmpxchg((&v->counter), old, new);
  87. }
  88. static inline int atomic_xchg (struct atomic_int * v, int new)
  89. {
  90. return xchg((&v->counter), new);
  91. }
  92. #endif /* _ATOMIC_INT_H_ */