atomic_8.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-04-27 peterfan Add copyright header.
  9. */
  10. #include <rthw.h>
  11. #include <stdint.h>
  12. #include <stdbool.h>
  13. /*
  14. * override gcc builtin atomic function for std::atomic<int64_t>, std::atomic<uint64_t>
  15. * @see https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
  16. */
  17. uint64_t __atomic_load_8(volatile void *ptr, int memorder)
  18. {
  19. volatile uint64_t *val_ptr = (volatile uint64_t *)ptr;
  20. rt_base_t level;
  21. uint64_t tmp;
  22. level = rt_hw_interrupt_disable();
  23. tmp = *val_ptr;
  24. rt_hw_interrupt_enable(level);
  25. return tmp;
  26. }
  27. void __atomic_store_8(volatile void *ptr, uint64_t val, int memorder)
  28. {
  29. volatile uint64_t *val_ptr = (volatile uint64_t *)ptr;
  30. rt_base_t level;
  31. level = rt_hw_interrupt_disable();
  32. *val_ptr = val;
  33. rt_hw_interrupt_enable(level);
  34. }
  35. uint64_t __atomic_exchange_8(volatile void *ptr, uint64_t val, int memorder)
  36. {
  37. volatile uint64_t *val_ptr = (volatile uint64_t *)ptr;
  38. rt_base_t level;
  39. uint64_t tmp;
  40. level = rt_hw_interrupt_disable();
  41. tmp = *val_ptr;
  42. *val_ptr = val;
  43. rt_hw_interrupt_enable(level);
  44. return tmp;
  45. }
  46. bool __atomic_compare_exchange_8(volatile void *ptr, volatile void *expected, uint64_t desired, bool weak, int success_memorder, int failure_memorder)
  47. {
  48. volatile uint64_t *val_ptr = (volatile uint64_t *)ptr;
  49. volatile uint64_t *expected_ptr = (volatile uint64_t *)expected;
  50. rt_base_t level;
  51. bool exchanged;
  52. level = rt_hw_interrupt_disable();
  53. if (*val_ptr == *expected_ptr)
  54. {
  55. *val_ptr = desired;
  56. exchanged = true;
  57. }
  58. else
  59. {
  60. *expected_ptr = *val_ptr;
  61. exchanged = false;
  62. }
  63. rt_hw_interrupt_enable(level);
  64. return exchanged;
  65. }
  66. #define __atomic_fetch_op_8(OPNAME, OP) \
  67. uint64_t __atomic_fetch_##OPNAME##_8(volatile void *ptr, uint64_t val, int memorder) {\
  68. volatile uint64_t* val_ptr = (volatile uint64_t*)ptr;\
  69. rt_base_t level;\
  70. uint64_t tmp;\
  71. level = rt_hw_interrupt_disable();\
  72. tmp = *val_ptr;\
  73. *val_ptr OP##= val;\
  74. rt_hw_interrupt_enable(level);\
  75. return tmp;\
  76. }
  77. __atomic_fetch_op_8(add, +)
  78. __atomic_fetch_op_8(sub, -)
  79. __atomic_fetch_op_8( and, &)
  80. __atomic_fetch_op_8( or, |)
  81. __atomic_fetch_op_8(xor, ^)