From cd3ef98ee1786d57283f8ea286015462ca37389d Mon Sep 17 00:00:00 2001 From: Youvedeep Singh Date: Wed, 28 Feb 2018 17:39:40 +0530 Subject: [PATCH] tests: kernel: posix: pthread_rwlock: POSIX rw lock test. Added test for POSIX read-write lock APIs. Signed-off-by: Youvedeep Singh --- .../posix/pthread_rwlock/CMakeLists.txt | 6 + tests/kernel/posix/pthread_rwlock/prj.conf | 2 + .../posix/pthread_rwlock/src/posix_rwlock.c | 132 ++++++++++++++++++ .../kernel/posix/pthread_rwlock/testcase.yaml | 3 + 4 files changed, 143 insertions(+) create mode 100644 tests/kernel/posix/pthread_rwlock/CMakeLists.txt create mode 100644 tests/kernel/posix/pthread_rwlock/prj.conf create mode 100644 tests/kernel/posix/pthread_rwlock/src/posix_rwlock.c create mode 100644 tests/kernel/posix/pthread_rwlock/testcase.yaml diff --git a/tests/kernel/posix/pthread_rwlock/CMakeLists.txt b/tests/kernel/posix/pthread_rwlock/CMakeLists.txt new file mode 100644 index 00000000000..1f0f8897775 --- /dev/null +++ b/tests/kernel/posix/pthread_rwlock/CMakeLists.txt @@ -0,0 +1,6 @@ +include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) +project(NONE) + +target_include_directories(app PRIVATE $ENV{ZEPHYR_BASE}/include/posix) +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kernel/posix/pthread_rwlock/prj.conf b/tests/kernel/posix/pthread_rwlock/prj.conf new file mode 100644 index 00000000000..8b969e576f2 --- /dev/null +++ b/tests/kernel/posix/pthread_rwlock/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_PTHREAD_IPC=y diff --git a/tests/kernel/posix/pthread_rwlock/src/posix_rwlock.c b/tests/kernel/posix/pthread_rwlock/src/posix_rwlock.c new file mode 100644 index 00000000000..297eb13e24c --- /dev/null +++ b/tests/kernel/posix/pthread_rwlock/src/posix_rwlock.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "ztest.h" + +#define N_THR 3 +#define STACKSZ 1024 + +K_THREAD_STACK_ARRAY_DEFINE(stacks, N_THR, STACKSZ); +pthread_rwlock_t rwlock; + +static void *thread_top(void *p1) +{ + pthread_t pthread; + u32_t policy, ret = 0; + struct sched_param param; + + pthread = (pthread_t) pthread_self(); + pthread_getschedparam(pthread, &policy, ¶m); + printk("Thread %d scheduling policy = %d & priority %d started\n", + (s32_t) p1, policy, param.priority); + + ret = pthread_rwlock_tryrdlock(&rwlock); + if (ret) { + printk("Not able to get RD lock on trying, try again\n"); + zassert_false(pthread_rwlock_rdlock(&rwlock), + "Failed to acquire write lock"); + } + + printk("Thread %d got RD lock\n", (s32_t) p1); + usleep(USEC_PER_MSEC); + printk("Thread %d releasing RD lock\n", (s32_t) p1); + zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock"); + + printk("Thread %d acquiring WR lock\n", (s32_t) p1); + zassert_false(pthread_rwlock_wrlock(&rwlock), + "Failed to acquire WR lock"); + printk("Thread %d acquired WR lock\n", (s32_t) p1); + usleep(USEC_PER_MSEC); + printk("Thread %d releasing WR lock\n", (s32_t) p1); + zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock"); + + pthread_exit(NULL); + return NULL; +} + +static void test_rw_lock(void) +{ + s32_t i, ret; + pthread_attr_t attr[N_THR]; + struct sched_param schedparam; + pthread_t newthread[N_THR]; + struct timespec time; + void *status; + + time.tv_sec = 1; + time.tv_nsec = 0; + + zassert_false(pthread_rwlock_init(&rwlock, NULL), + "Failed to create rwlock"); + + printk("\nmain acquire WR lock and 3 threads acquire RD lock\n"); + ret = pthread_rwlock_trywrlock(&rwlock); + + if (ret != 0) { + printk("Parent thread acquiring WR lock\n"); + zassert_false(pthread_rwlock_timedwrlock(&rwlock, &time), + "Failed to acquire write lock"); + } + + /* Creating N premptive threads in increasing order of priority */ + for (i = 0; i < N_THR; i++) { + pthread_attr_destroy(&attr[i]); + pthread_attr_init(&attr[i]); + + /* Setting scheduling priority */ + schedparam.priority = i + 1; + pthread_attr_setschedparam(&attr[i], &schedparam); + + /* Setting stack */ + pthread_attr_setstack(&attr[i], &stacks[i][0], STACKSZ); + + ret = pthread_create(&newthread[i], &attr[i], thread_top, + (void *)i); + zassert_false(ret, "Low memory to thread new thread\n"); + + } + + /* Delay to give change to child threads to run */ + usleep(USEC_PER_MSEC); + printk("Parent thread releasing WR lock\n"); + zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock"); + + /* Let child threads acquire RD Lock */ + usleep(USEC_PER_MSEC); + printk("Parent thread acquiring WR lock again\n"); + + zassert_false(pthread_rwlock_wrlock(&rwlock), + "Failed to acquire write lock"); + printk("Parent thread acquired WR lock again\n"); + usleep(USEC_PER_MSEC); + printk("Parent thread releasing WR lock again\n"); + zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock"); + + printk("\n3 threads acquire WR lock\n"); + printk("Main thread acquiring RD lock\n"); + + zassert_false(pthread_rwlock_rdlock(&rwlock), "Failed to lock"); + printk("Main thread acquired RD lock\n"); + usleep(USEC_PER_MSEC); + printk("Main thread releasing RD lock\n"); + zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock"); + + for (i = 0; i < N_THR; i++) { + zassert_false(pthread_join(newthread[i], &status), + "Failed to join\n"); + } + + zassert_false(pthread_rwlock_destroy(&rwlock), + "Failed to destroy rwlock"); +} + +void test_main(void) +{ + ztest_test_suite(test_posix_rwlock_api, + ztest_unit_test(test_rw_lock)); + ztest_run_test_suite(test_posix_rwlock_api); +} diff --git a/tests/kernel/posix/pthread_rwlock/testcase.yaml b/tests/kernel/posix/pthread_rwlock/testcase.yaml new file mode 100644 index 00000000000..cfe553a44f1 --- /dev/null +++ b/tests/kernel/posix/pthread_rwlock/testcase.yaml @@ -0,0 +1,3 @@ +tests: + kernel.posix.pthread_rwlock: + tags: core