mutex.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Copyright (c) 2018 Intel Corporation
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <kernel.h>
  7. #include <string.h>
  8. #include "wrapper.h"
  9. K_MEM_SLAB_DEFINE(cv2_mutex_slab, sizeof(struct cv2_mutex),
  10. CONFIG_CMSIS_V2_MUTEX_MAX_COUNT, 4);
  11. static const osMutexAttr_t init_mutex_attrs = {
  12. .name = "ZephyrMutex",
  13. .attr_bits = osMutexPrioInherit,
  14. .cb_mem = NULL,
  15. .cb_size = 0,
  16. };
  17. /**
  18. * @brief Create and Initialize a Mutex object.
  19. */
  20. osMutexId_t osMutexNew(const osMutexAttr_t *attr)
  21. {
  22. struct cv2_mutex *mutex;
  23. if (k_is_in_isr()) {
  24. return NULL;
  25. }
  26. if (attr == NULL) {
  27. attr = &init_mutex_attrs;
  28. }
  29. __ASSERT(attr->attr_bits & osMutexPrioInherit,
  30. "Zephyr supports osMutexPrioInherit by default. Do not unselect it\n");
  31. __ASSERT(!(attr->attr_bits & osMutexRobust),
  32. "Zephyr does not support osMutexRobust.\n");
  33. if (k_mem_slab_alloc(&cv2_mutex_slab, (void **)&mutex, K_MSEC(100)) == 0) {
  34. memset(mutex, 0, sizeof(struct cv2_mutex));
  35. } else {
  36. return NULL;
  37. }
  38. k_mutex_init(&mutex->z_mutex);
  39. mutex->state = attr->attr_bits;
  40. if (attr->name == NULL) {
  41. strncpy(mutex->name, init_mutex_attrs.name,
  42. sizeof(mutex->name) - 1);
  43. } else {
  44. strncpy(mutex->name, attr->name, sizeof(mutex->name) - 1);
  45. }
  46. return (osMutexId_t)mutex;
  47. }
  48. /**
  49. * @brief Wait until a Mutex becomes available.
  50. */
  51. osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
  52. {
  53. struct cv2_mutex *mutex = (struct cv2_mutex *) mutex_id;
  54. int status;
  55. if (mutex_id == NULL) {
  56. return osErrorParameter;
  57. }
  58. if (k_is_in_isr()) {
  59. return osErrorISR;
  60. }
  61. if (mutex->z_mutex.lock_count == 0U ||
  62. mutex->z_mutex.owner == _current) {
  63. }
  64. /* Throw an error if the mutex is not configured to be recursive and
  65. * the current thread is trying to acquire the mutex again.
  66. */
  67. if ((mutex->state & osMutexRecursive) == 0U) {
  68. if ((mutex->z_mutex.owner == _current) &&
  69. (mutex->z_mutex.lock_count != 0U)) {
  70. return osErrorResource;
  71. }
  72. }
  73. if (timeout == osWaitForever) {
  74. status = k_mutex_lock(&mutex->z_mutex, K_FOREVER);
  75. } else if (timeout == 0U) {
  76. status = k_mutex_lock(&mutex->z_mutex, K_NO_WAIT);
  77. } else {
  78. status = k_mutex_lock(&mutex->z_mutex,
  79. K_TICKS(timeout));
  80. }
  81. if (status == -EBUSY) {
  82. return osErrorResource;
  83. } else if (status == -EAGAIN) {
  84. return osErrorTimeout;
  85. } else {
  86. return osOK;
  87. }
  88. }
  89. /**
  90. * @brief Release a Mutex that was obtained by osMutexWait.
  91. */
  92. osStatus_t osMutexRelease(osMutexId_t mutex_id)
  93. {
  94. struct cv2_mutex *mutex = (struct cv2_mutex *) mutex_id;
  95. if (mutex_id == NULL) {
  96. return osErrorParameter;
  97. }
  98. if (k_is_in_isr()) {
  99. return osErrorISR;
  100. }
  101. /* Mutex was not obtained before or was not owned by current thread */
  102. if ((mutex->z_mutex.lock_count == 0U) ||
  103. (mutex->z_mutex.owner != _current)) {
  104. return osErrorResource;
  105. }
  106. k_mutex_unlock(&mutex->z_mutex);
  107. return osOK;
  108. }
  109. /**
  110. * @brief Delete a Mutex that was created by osMutexCreate.
  111. */
  112. osStatus_t osMutexDelete(osMutexId_t mutex_id)
  113. {
  114. struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;
  115. if (mutex_id == NULL) {
  116. return osErrorParameter;
  117. }
  118. if (k_is_in_isr()) {
  119. return osErrorISR;
  120. }
  121. /* The status code "osErrorResource" (mutex specified by parameter
  122. * mutex_id is in an invalid mutex state) is not supported in Zephyr.
  123. */
  124. k_mem_slab_free(&cv2_mutex_slab, (void *) &mutex);
  125. return osOK;
  126. }
  127. osThreadId_t osMutexGetOwner(osMutexId_t mutex_id)
  128. {
  129. struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;
  130. if (k_is_in_isr() || (mutex == NULL)) {
  131. return NULL;
  132. }
  133. /* Mutex was not obtained before */
  134. if (mutex->z_mutex.lock_count == 0U) {
  135. return NULL;
  136. }
  137. return get_cmsis_thread_id(mutex->z_mutex.owner);
  138. }
  139. const char *osMutexGetName(osMutexId_t mutex_id)
  140. {
  141. struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;
  142. if (k_is_in_isr() || (mutex == NULL)) {
  143. return NULL;
  144. }
  145. return mutex->name;
  146. }