《操作系统》的实验代码。

80 rivejä
2.5 KiB

12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
  1. #ifndef __LIBS_ATOMIC_H__
  2. #define __LIBS_ATOMIC_H__
  3. /* Atomic operations that C can't guarantee us. Useful for resource counting etc.. */
  4. static inline void set_bit(int nr, volatile void *addr) __attribute__((always_inline));
  5. static inline void clear_bit(int nr, volatile void *addr) __attribute__((always_inline));
  6. static inline void change_bit(int nr, volatile void *addr) __attribute__((always_inline));
  7. static inline bool test_bit(int nr, volatile void *addr) __attribute__((always_inline));
  8. /* *
  9. * set_bit - Atomically set a bit in memory
  10. * @nr: the bit to set
  11. * @addr: the address to start counting from
  12. *
  13. * Note that @nr may be almost arbitrarily large; this function is not
  14. * restricted to acting on a single-word quantity.
  15. * */
  16. static inline void
  17. set_bit(int nr, volatile void *addr) {
  18. asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
  19. }
  20. /* *
  21. * clear_bit - Atomically clears a bit in memory
  22. * @nr: the bit to clear
  23. * @addr: the address to start counting from
  24. * */
  25. static inline void
  26. clear_bit(int nr, volatile void *addr) {
  27. asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
  28. }
  29. /* *
  30. * change_bit - Atomically toggle a bit in memory
  31. * @nr: the bit to change
  32. * @addr: the address to start counting from
  33. * */
  34. static inline void
  35. change_bit(int nr, volatile void *addr) {
  36. asm volatile ("btcl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
  37. }
  38. /* *
  39. * test_bit - Determine whether a bit is set
  40. * @nr: the bit to test
  41. * @addr: the address to count from
  42. * */
  43. static inline bool
  44. test_bit(int nr, volatile void *addr) {
  45. int oldbit;
  46. asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
  47. return oldbit != 0;
  48. }
  49. /* *
  50. * test_and_set_bit - Atomically set a bit and return its old value
  51. * @nr: the bit to set
  52. * @addr: the address to count from
  53. * */
  54. static inline bool
  55. test_and_set_bit(int nr, volatile void *addr) {
  56. int oldbit;
  57. asm volatile ("btsl %2, %1; sbbl %0, %0" : "=r" (oldbit), "=m" (*(volatile long *)addr) : "Ir" (nr) : "memory");
  58. return oldbit != 0;
  59. }
  60. /* *
  61. * test_and_clear_bit - Atomically clear a bit and return its old value
  62. * @nr: the bit to clear
  63. * @addr: the address to count from
  64. * */
  65. static inline bool
  66. test_and_clear_bit(int nr, volatile void *addr) {
  67. int oldbit;
  68. asm volatile ("btrl %2, %1; sbbl %0, %0" : "=r" (oldbit), "=m" (*(volatile long *)addr) : "Ir" (nr) : "memory");
  69. return oldbit != 0;
  70. }
  71. #endif /* !__LIBS_ATOMIC_H__ */