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