1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <ztest.h>
8 #include <errno.h>
9 #include <pthread.h>
10
11 #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACKSIZE)
12
13 static K_THREAD_STACK_DEFINE(stack, STACK_SIZE);
14
15 #define SLEEP_MS 100
16
17 pthread_mutex_t mutex1;
18 pthread_mutex_t mutex2;
19
normal_mutex_entry(void * p1)20 void *normal_mutex_entry(void *p1)
21 {
22 int i, rc;
23
24 /* Sleep for maximum 300 ms as main thread is sleeping for 100 ms */
25
26 for (i = 0; i < 3; i++) {
27 rc = pthread_mutex_trylock(&mutex1);
28 if (rc == 0) {
29 break;
30 }
31 k_msleep(SLEEP_MS);
32 }
33
34 zassert_false(rc, "try lock failed");
35 TC_PRINT("mutex lock is taken\n");
36 zassert_false(pthread_mutex_unlock(&mutex1),
37 "mutex unlock is falied");
38 return NULL;
39 }
40
recursive_mutex_entry(void * p1)41 void *recursive_mutex_entry(void *p1)
42 {
43 zassert_false(pthread_mutex_lock(&mutex2), "mutex is not taken");
44 zassert_false(pthread_mutex_lock(&mutex2),
45 "mutex is not taken 2nd time");
46 TC_PRINT("recrusive mutex lock is taken\n");
47 zassert_false(pthread_mutex_unlock(&mutex2),
48 "mutex is not unlocked");
49 zassert_false(pthread_mutex_unlock(&mutex2),
50 "mutex is not unlocked");
51 return NULL;
52 }
53
54 /**
55 * @brief Test to demonstrate PTHREAD_MUTEX_NORMAL
56 *
57 * @details Mutex type is setup as normal. pthread_mutex_trylock
58 * and pthread_mutex_lock are tested with mutex type being
59 * normal.
60 */
test_posix_normal_mutex(void)61 void test_posix_normal_mutex(void)
62 {
63 pthread_t thread_1;
64 pthread_attr_t attr;
65 pthread_mutexattr_t mut_attr;
66 struct sched_param schedparam;
67 int schedpolicy = SCHED_FIFO;
68 int ret, type, protocol, temp;
69
70 schedparam.sched_priority = 2;
71 ret = pthread_attr_init(&attr);
72 if (ret != 0) {
73 zassert_false(pthread_attr_destroy(&attr),
74 "Unable to destroy pthread object attrib");
75 zassert_false(pthread_attr_init(&attr),
76 "Unable to create pthread object attrib");
77 }
78
79 pthread_attr_setstack(&attr, &stack, STACK_SIZE);
80 pthread_attr_setschedpolicy(&attr, schedpolicy);
81 pthread_attr_setschedparam(&attr, &schedparam);
82
83 temp = pthread_mutexattr_settype(&mut_attr, PTHREAD_MUTEX_NORMAL);
84 zassert_false(temp, "setting mutex type is failed");
85 temp = pthread_mutex_init(&mutex1, &mut_attr);
86 zassert_false(temp, "mutex initialization is failed");
87
88 temp = pthread_mutexattr_gettype(&mut_attr, &type);
89 zassert_false(temp, "reading mutex type is failed");
90 temp = pthread_mutexattr_getprotocol(&mut_attr, &protocol);
91 zassert_false(temp, "reading mutex protocol is failed");
92
93 pthread_mutex_lock(&mutex1);
94
95 zassert_equal(type, PTHREAD_MUTEX_NORMAL,
96 "mutex type is not normal");
97
98 zassert_equal(protocol, PTHREAD_PRIO_NONE,
99 "mutex protocol is not prio_none");
100 ret = pthread_create(&thread_1, &attr, &normal_mutex_entry, NULL);
101
102 if (ret) {
103 TC_PRINT("Thread1 creation failed %d", ret);
104 }
105 k_msleep(SLEEP_MS);
106 pthread_mutex_unlock(&mutex1);
107
108 pthread_join(thread_1, NULL);
109 temp = pthread_mutex_destroy(&mutex1);
110 zassert_false(temp, "Destroying mutex is failed");
111 }
112
113 /**
114 * @brief Test to demonstrate PTHREAD_MUTEX_RECURSIVE
115 *
116 * @details Mutex type is setup as recursive. mutex will be locked
117 * twice and unlocked for the same number of time.
118 *
119 */
test_posix_recursive_mutex(void)120 void test_posix_recursive_mutex(void)
121 {
122 pthread_t thread_2;
123 pthread_attr_t attr2;
124 pthread_mutexattr_t mut_attr2;
125 struct sched_param schedparam2;
126 int schedpolicy = SCHED_FIFO;
127 int ret, type, protocol, temp;
128
129 schedparam2.sched_priority = 2;
130 ret = pthread_attr_init(&attr2);
131 if (ret != 0) {
132 zassert_false(pthread_attr_destroy(&attr2),
133 "Unable to destroy pthread object attrib");
134 zassert_false(pthread_attr_init(&attr2),
135 "Unable to create pthread object attrib");
136 }
137
138 pthread_attr_setstack(&attr2, &stack, STACK_SIZE);
139 pthread_attr_setschedpolicy(&attr2, schedpolicy);
140 pthread_attr_setschedparam(&attr2, &schedparam2);
141
142 temp = pthread_mutexattr_settype(&mut_attr2, PTHREAD_MUTEX_RECURSIVE);
143 zassert_false(temp, "setting mutex2 type is failed");
144 temp = pthread_mutex_init(&mutex2, &mut_attr2);
145 zassert_false(temp, "mutex2 initialization is failed");
146
147 temp = pthread_mutexattr_gettype(&mut_attr2, &type);
148 zassert_false(temp, "reading mutex2 type is failed");
149 temp = pthread_mutexattr_getprotocol(&mut_attr2, &protocol);
150 zassert_false(temp, "reading mutex2 protocol is failed");
151
152 zassert_equal(type, PTHREAD_MUTEX_RECURSIVE,
153 "mutex2 type is not recursive");
154
155 zassert_equal(protocol, PTHREAD_PRIO_NONE,
156 "mutex2 protocol is not prio_none");
157 ret = pthread_create(&thread_2, &attr2, &recursive_mutex_entry, NULL);
158
159 zassert_false(ret, "Thread2 creation failed");
160
161 pthread_join(thread_2, NULL);
162 temp = pthread_mutex_destroy(&mutex2);
163 zassert_false(temp, "Destroying mutex2 is failed");
164 }
165