bitop.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* Copyright (C) 2014 OSCAR lab, Stony Brook University
  2. This file is part of Graphene Library OS.
  3. Graphene Library OS is free software: you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. Graphene Library OS is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. /*
  14. * bitop.h
  15. */
  16. #ifndef _BITOP_H
  17. #define _BITOP_H
  18. #define ADDR (*(volatile long *) addr)
  19. #define LOCK_PREFIX ""
  20. /**
  21. * set_bit - Atomically set a bit in memory
  22. * @nr: the bit to set
  23. * @addr: the address to start counting from
  24. *
  25. * This function is atomic and may not be reordered. See __set_bit()
  26. * if you do not require the atomic guarantees.
  27. * Note that @nr may be almost arbitrarily large; this function is not
  28. * restricted to acting on a single-word quantity.
  29. */
  30. static __inline__ void set_bit(int nr, volatile void * addr)
  31. {
  32. __asm__ __volatile__( LOCK_PREFIX
  33. "btsl %1,%0"
  34. :"=m" (ADDR)
  35. :"dIr" (nr) : "memory");
  36. }
  37. /**
  38. * __set_bit - Set a bit in memory
  39. * @nr: the bit to set
  40. * @addr: the address to start counting from
  41. *
  42. * Unlike set_bit(), this function is non-atomic and may be reordered.
  43. * If it's called on the same region of memory simultaneously, the effect
  44. * may be that only one operation succeeds.
  45. */
  46. static __inline__ void __set_bit(int nr, volatile void * addr)
  47. {
  48. __asm__ volatile(
  49. "btsl %1,%0"
  50. :"=m" (ADDR)
  51. :"dIr" (nr) : "memory");
  52. }
  53. /**
  54. * clear_bit - Clears a bit in memory
  55. * @nr: Bit to clear
  56. * @addr: Address to start counting from
  57. *
  58. * clear_bit() is atomic and may not be reordered. However, it does
  59. * not contain a memory barrier, so if it is used for locking purposes,
  60. * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  61. * in order to ensure changes are visible on other processors.
  62. */
  63. static __inline__ void clear_bit(int nr, volatile void * addr)
  64. {
  65. __asm__ __volatile__( LOCK_PREFIX
  66. "btrl %1,%0"
  67. :"=m" (ADDR)
  68. :"dIr" (nr));
  69. }
  70. static __inline__ void __clear_bit(int nr, volatile void * addr)
  71. {
  72. __asm__ __volatile__(
  73. "btrl %1,%0"
  74. :"=m" (ADDR)
  75. :"dIr" (nr));
  76. }
  77. static __inline__ int constant_test_bit(int nr, const volatile void * addr)
  78. {
  79. return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
  80. }
  81. static __inline__ int variable_test_bit(int nr, volatile const void * addr)
  82. {
  83. int oldbit;
  84. __asm__ __volatile__(
  85. "btl %2,%1\n\tsbbl %0,%0"
  86. :"=r" (oldbit)
  87. :"m" (ADDR),"dIr" (nr));
  88. return oldbit;
  89. }
  90. #define test_bit(nr,addr) \
  91. (__builtin_constant_p(nr) ? \
  92. constant_test_bit((nr),(addr)) : \
  93. variable_test_bit((nr),(addr)))
  94. #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
  95. #endif