test_locks.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include <stdio.h>
  7. #include <stdbool.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <sys/lock.h>
  11. #include "unity.h"
  12. #include "test_utils.h"
  13. #include "sdkconfig.h"
  14. #include "freertos/FreeRTOS.h"
  15. #include "freertos/semphr.h"
  16. #if defined(_RETARGETABLE_LOCKING)
  17. static void locking_task(void* arg)
  18. {
  19. _LOCK_T lock = (_LOCK_T) arg;
  20. __lock_acquire(lock);
  21. __lock_release(lock);
  22. vTaskSuspend(NULL);
  23. }
  24. static void recursive_locking_task(void* arg)
  25. {
  26. _LOCK_T lock = (_LOCK_T) arg;
  27. __lock_acquire_recursive(lock);
  28. __lock_release_recursive(lock);
  29. vTaskSuspend(NULL);
  30. }
  31. static void test_inner_normal(_LOCK_T lock)
  32. {
  33. /* Acquire the lock */
  34. __lock_acquire(lock);
  35. /* Create another task to try acquire same lock */
  36. TaskHandle_t task_hdl;
  37. TEST_ASSERT(xTaskCreate(&locking_task, "locking_task", 2048, lock, UNITY_FREERTOS_PRIORITY, &task_hdl));
  38. vTaskDelay(2);
  39. /* It should get blocked */
  40. TEST_ASSERT_EQUAL(eBlocked, eTaskGetState(task_hdl));
  41. /* Once we release the lock, the task should succeed and suspend itself */
  42. __lock_release(lock);
  43. vTaskDelay(2);
  44. TEST_ASSERT_EQUAL(eSuspended, eTaskGetState(task_hdl));
  45. vTaskDelete(task_hdl);
  46. /* Can not recursively acquire the lock from same task */
  47. TEST_ASSERT_EQUAL(0, __lock_try_acquire(lock));
  48. TEST_ASSERT_EQUAL(-1, __lock_try_acquire(lock));
  49. __lock_release(lock);
  50. }
  51. static void test_inner_recursive(_LOCK_T lock)
  52. {
  53. /* Acquire the lock */
  54. __lock_acquire_recursive(lock);
  55. /* Create another task to try acquire same lock */
  56. TaskHandle_t task_hdl;
  57. TEST_ASSERT(xTaskCreate(&recursive_locking_task, "locking_task", 2048, lock, UNITY_FREERTOS_PRIORITY, &task_hdl));
  58. vTaskDelay(2);
  59. /* It should get blocked */
  60. TEST_ASSERT_EQUAL(eBlocked, eTaskGetState(task_hdl));
  61. /* Once we release the lock, the task should succeed and suspend itself */
  62. __lock_release_recursive(lock);
  63. vTaskDelay(2);
  64. TEST_ASSERT_EQUAL(eSuspended, eTaskGetState(task_hdl));
  65. vTaskDelete(task_hdl);
  66. /* Try recursively acquiring the lock */
  67. TEST_ASSERT_EQUAL(0, __lock_try_acquire_recursive(lock));
  68. TEST_ASSERT_EQUAL(0, __lock_try_acquire_recursive(lock));
  69. __lock_release_recursive(lock);
  70. __lock_release_recursive(lock);
  71. }
  72. TEST_CASE("Retargetable static locks", "[newlib_locks]")
  73. {
  74. StaticSemaphore_t semaphore;
  75. _LOCK_T lock = (_LOCK_T) xSemaphoreCreateMutexStatic(&semaphore);
  76. test_inner_normal(lock);
  77. }
  78. TEST_CASE("Retargetable static recursive locks", "[newlib_locks]")
  79. {
  80. StaticSemaphore_t semaphore;
  81. _LOCK_T lock = (_LOCK_T) xSemaphoreCreateRecursiveMutexStatic(&semaphore);
  82. test_inner_recursive(lock);
  83. }
  84. TEST_CASE("Retargetable dynamic locks", "[newlib_locks]")
  85. {
  86. _LOCK_T lock;
  87. __lock_init(lock);
  88. test_inner_normal(lock);
  89. __lock_close(lock);
  90. }
  91. TEST_CASE("Retargetable dynamic recursive locks", "[newlib_locks]")
  92. {
  93. _LOCK_T lock;
  94. __lock_init_recursive(lock);
  95. test_inner_recursive(lock);
  96. __lock_close_recursive(lock);
  97. }
  98. #endif // _RETARGETABLE_LOCKING