Skip to content

Commit daac517

Browse files
Christopher Friedtcfriedt
authored andcommitted
tests: posix: mutex: test pthread_mutex_timedlock() ETIMEDOUT
Add a test to ensure that `pthread_mutex_timedlock()` returns `ETIMEDOUT` when it fails. Signed-off-by: Christopher Friedt <[email protected]>
1 parent f9ecc9a commit daac517

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

tests/posix/common/src/mutex.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,65 @@ ZTEST(posix_apis, test_mutex_resource_leak)
192192
zassert_ok(pthread_mutex_destroy(&m), "failed to destroy mutex %zu", i);
193193
}
194194
}
195+
196+
#define TIMEDLOCK_TIMEOUT_MS 200
197+
#define TIMEDLOCK_TIMEOUT_DELAY_MS 100
198+
199+
BUILD_ASSERT(TIMEDLOCK_TIMEOUT_DELAY_MS >= 100, "TIMEDLOCK_TIMEOUT_DELAY_MS too small");
200+
BUILD_ASSERT(TIMEDLOCK_TIMEOUT_MS >= 2 * TIMEDLOCK_TIMEOUT_DELAY_MS,
201+
"TIMEDLOCK_TIMEOUT_MS too small");
202+
203+
static void timespec_add_ms(struct timespec *ts, uint32_t ms)
204+
{
205+
bool oflow;
206+
207+
ts->tv_nsec += ms * NSEC_PER_MSEC;
208+
oflow = ts->tv_nsec >= NSEC_PER_SEC;
209+
ts->tv_sec += oflow;
210+
ts->tv_nsec -= oflow * NSEC_PER_SEC;
211+
}
212+
213+
static void *test_mutex_timedlock_fn(void *arg)
214+
{
215+
struct timespec time_point;
216+
pthread_mutex_t *mutex = (pthread_mutex_t *)arg;
217+
218+
zassume_ok(clock_gettime(CLOCK_MONOTONIC, &time_point));
219+
timespec_add_ms(&time_point, TIMEDLOCK_TIMEOUT_MS);
220+
221+
return INT_TO_POINTER(pthread_mutex_timedlock(mutex, &time_point));
222+
}
223+
224+
/** @brief Test to verify @ref pthread_mutex_timedlock returns ETIMEDOUT */
225+
ZTEST(posix_apis, test_mutex_timedlock)
226+
{
227+
void *ret;
228+
pthread_t th;
229+
pthread_t mutex;
230+
pthread_attr_t attr;
231+
232+
zassert_ok(pthread_attr_init(&attr));
233+
zassert_ok(pthread_attr_setstack(&attr, &stack, STACK_SIZE));
234+
235+
zassert_ok(pthread_mutex_init(&mutex, NULL));
236+
237+
printk("Expecting timedlock with timeout of %d ms to fail\n", TIMEDLOCK_TIMEOUT_MS);
238+
zassert_ok(pthread_mutex_lock(&mutex));
239+
zassert_ok(pthread_create(&th, &attr, test_mutex_timedlock_fn, &mutex));
240+
zassert_ok(pthread_join(th, &ret));
241+
/* ensure timeout occurs */
242+
zassert_equal(ETIMEDOUT, POINTER_TO_INT(ret));
243+
244+
printk("Expecting timedlock with timeout of %d ms to succeed after 100ms\n",
245+
TIMEDLOCK_TIMEOUT_MS);
246+
zassert_ok(pthread_create(&th, &attr, test_mutex_timedlock_fn, &mutex));
247+
/* unlock before timeout expires */
248+
k_msleep(TIMEDLOCK_TIMEOUT_DELAY_MS);
249+
zassert_ok(pthread_mutex_unlock(&mutex));
250+
zassert_ok(pthread_join(th, &ret));
251+
/* ensure lock is successful, in spite of delay */
252+
zassert_ok(POINTER_TO_INT(ret));
253+
254+
zassert_ok(pthread_mutex_destroy(&mutex));
255+
zassert_ok(pthread_attr_destroy(&attr));
256+
}

0 commit comments

Comments
 (0)