mutex.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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 flybreak the first version.
  9. */
  10. #include <arm-tpl.h>
  11. #include <cstdint>
  12. #include <stdatomic.h>
  13. #include "tpl.h"
  14. static int check_create(volatile __ARM_TPL_mutex_t *__vm, bool recursive = false)
  15. {
  16. if (__vm->data == 0)
  17. {
  18. uintptr_t mut_null = 0;
  19. arm_tpl_mutex_struct *mutex_p = (arm_tpl_mutex_struct *)rt_malloc(sizeof(arm_tpl_mutex_struct));
  20. if (mutex_p == nullptr) return -1;
  21. if (recursive)
  22. mutex_p->mutex = rt_mutex_create("mutexx", RT_IPC_FLAG_PRIO);
  23. else
  24. mutex_p->mutex = rt_mutex_create("mutexx", RT_IPC_FLAG_PRIO);
  25. if (mutex_p->mutex == nullptr)
  26. {
  27. rt_free(mutex_p);
  28. return -1;
  29. }
  30. mutex_p->type = recursive ? RECURSIVE : NORMAL;
  31. uintptr_t mut_new = reinterpret_cast<uintptr_t>(mutex_p);
  32. if (!atomic_compare_exchange_strong(&__vm->data, &mut_null, mut_new))
  33. {
  34. rt_mutex_delete(mutex_p->mutex);
  35. rt_free(mutex_p);
  36. }
  37. }
  38. return 0;
  39. }
  40. static int mutexLock(arm_tpl_mutex_struct *mutex_p, rt_tick_t timeOut)
  41. {
  42. if (mutex_p->type == RECURSIVE)
  43. {
  44. if (rt_mutex_take(mutex_p->mutex, timeOut) == 0)
  45. return 0;
  46. }
  47. else
  48. {
  49. if (rt_mutex_take(mutex_p->mutex, timeOut) == 0)
  50. return 0;
  51. }
  52. return -1;
  53. }
  54. static int mutexUnlock(arm_tpl_mutex_struct *mutex_p)
  55. {
  56. if (mutex_p->type == RECURSIVE)
  57. rt_mutex_release(mutex_p->mutex);
  58. else
  59. rt_mutex_release(mutex_p->mutex);
  60. return 0;
  61. }
  62. extern "C" int __ARM_TPL_recursive_mutex_init(__ARM_TPL_mutex_t *__m)
  63. {
  64. volatile __ARM_TPL_mutex_t *__vm = __m;
  65. return check_create(__vm, true);
  66. }
  67. extern "C" int __ARM_TPL_mutex_lock(__ARM_TPL_mutex_t *__m)
  68. {
  69. volatile __ARM_TPL_mutex_t *__vm = __m;
  70. if (check_create(__vm))
  71. return -1;
  72. while (mutexLock((arm_tpl_mutex_struct *)(__vm->data), ARM_TPL_MAX_DELAY) != 0);
  73. return 0;
  74. }
  75. extern "C" int __ARM_TPL_mutex_trylock(__ARM_TPL_mutex_t *__m)
  76. {
  77. volatile __ARM_TPL_mutex_t *__vm = __m;
  78. if (check_create(__vm))
  79. return -1;
  80. return mutexLock((arm_tpl_mutex_struct *)(__vm->data), 0);
  81. }
  82. extern "C" int __ARM_TPL_mutex_unlock(__ARM_TPL_mutex_t *__m)
  83. {
  84. volatile __ARM_TPL_mutex_t *__vm = __m;
  85. return mutexUnlock((arm_tpl_mutex_struct *)(__vm->data));
  86. }
  87. extern "C" int __ARM_TPL_mutex_destroy(__ARM_TPL_mutex_t *__m)
  88. {
  89. volatile __ARM_TPL_mutex_t *__vm = __m;
  90. if (__vm->data != 0)
  91. {
  92. rt_mutex_delete(((arm_tpl_mutex_struct *)(__vm->data))->mutex);
  93. rt_free((void *)(__vm->data));
  94. __vm->data = 0;
  95. }
  96. return 0;
  97. }