| /* |
| * Copyright (c) 2018 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <ztest.h> |
| #include <errno.h> |
| #include <pthread.h> |
| |
| #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) |
| |
| static K_THREAD_STACK_DEFINE(stack, STACK_SIZE); |
| |
| #define SLEEP_MS 100 |
| |
| pthread_mutex_t mutex1; |
| pthread_mutex_t mutex2; |
| |
| void *normal_mutex_entry(void *p1) |
| { |
| int i, rc; |
| |
| /* Sleep for maximum 300 ms as main thread is sleeping for 100 ms */ |
| |
| for (i = 0; i < 3; i++) { |
| rc = pthread_mutex_trylock(&mutex1); |
| if (rc == 0) { |
| break; |
| } |
| k_msleep(SLEEP_MS); |
| } |
| |
| zassert_false(rc, "try lock failed"); |
| TC_PRINT("mutex lock is taken\n"); |
| zassert_false(pthread_mutex_unlock(&mutex1), |
| "mutex unlock is failed"); |
| return NULL; |
| } |
| |
| void *recursive_mutex_entry(void *p1) |
| { |
| zassert_false(pthread_mutex_lock(&mutex2), "mutex is not taken"); |
| zassert_false(pthread_mutex_lock(&mutex2), |
| "mutex is not taken 2nd time"); |
| TC_PRINT("recursive mutex lock is taken\n"); |
| zassert_false(pthread_mutex_unlock(&mutex2), |
| "mutex is not unlocked"); |
| zassert_false(pthread_mutex_unlock(&mutex2), |
| "mutex is not unlocked"); |
| return NULL; |
| } |
| |
| /** |
| * @brief Test to demonstrate PTHREAD_MUTEX_NORMAL |
| * |
| * @details Mutex type is setup as normal. pthread_mutex_trylock |
| * and pthread_mutex_lock are tested with mutex type being |
| * normal. |
| */ |
| void test_posix_normal_mutex(void) |
| { |
| pthread_t thread_1; |
| pthread_attr_t attr; |
| pthread_mutexattr_t mut_attr; |
| struct sched_param schedparam; |
| int schedpolicy = SCHED_FIFO; |
| int ret, type, protocol, temp; |
| |
| schedparam.sched_priority = 2; |
| ret = pthread_attr_init(&attr); |
| if (ret != 0) { |
| zassert_false(pthread_attr_destroy(&attr), |
| "Unable to destroy pthread object attrib"); |
| zassert_false(pthread_attr_init(&attr), |
| "Unable to create pthread object attrib"); |
| } |
| |
| pthread_attr_setstack(&attr, &stack, STACK_SIZE); |
| pthread_attr_setschedpolicy(&attr, schedpolicy); |
| pthread_attr_setschedparam(&attr, &schedparam); |
| |
| temp = pthread_mutexattr_settype(&mut_attr, PTHREAD_MUTEX_NORMAL); |
| zassert_false(temp, "setting mutex type is failed"); |
| temp = pthread_mutex_init(&mutex1, &mut_attr); |
| zassert_false(temp, "mutex initialization is failed"); |
| |
| temp = pthread_mutexattr_gettype(&mut_attr, &type); |
| zassert_false(temp, "reading mutex type is failed"); |
| temp = pthread_mutexattr_getprotocol(&mut_attr, &protocol); |
| zassert_false(temp, "reading mutex protocol is failed"); |
| |
| pthread_mutex_lock(&mutex1); |
| |
| zassert_equal(type, PTHREAD_MUTEX_NORMAL, |
| "mutex type is not normal"); |
| |
| zassert_equal(protocol, PTHREAD_PRIO_NONE, |
| "mutex protocol is not prio_none"); |
| ret = pthread_create(&thread_1, &attr, &normal_mutex_entry, NULL); |
| |
| if (ret) { |
| TC_PRINT("Thread1 creation failed %d", ret); |
| } |
| k_msleep(SLEEP_MS); |
| pthread_mutex_unlock(&mutex1); |
| |
| pthread_join(thread_1, NULL); |
| temp = pthread_mutex_destroy(&mutex1); |
| zassert_false(temp, "Destroying mutex is failed"); |
| } |
| |
| /** |
| * @brief Test to demonstrate PTHREAD_MUTEX_RECURSIVE |
| * |
| * @details Mutex type is setup as recursive. mutex will be locked |
| * twice and unlocked for the same number of time. |
| * |
| */ |
| void test_posix_recursive_mutex(void) |
| { |
| pthread_t thread_2; |
| pthread_attr_t attr2; |
| pthread_mutexattr_t mut_attr2; |
| struct sched_param schedparam2; |
| int schedpolicy = SCHED_FIFO; |
| int ret, type, protocol, temp; |
| |
| schedparam2.sched_priority = 2; |
| ret = pthread_attr_init(&attr2); |
| if (ret != 0) { |
| zassert_false(pthread_attr_destroy(&attr2), |
| "Unable to destroy pthread object attrib"); |
| zassert_false(pthread_attr_init(&attr2), |
| "Unable to create pthread object attrib"); |
| } |
| |
| pthread_attr_setstack(&attr2, &stack, STACK_SIZE); |
| pthread_attr_setschedpolicy(&attr2, schedpolicy); |
| pthread_attr_setschedparam(&attr2, &schedparam2); |
| |
| temp = pthread_mutexattr_settype(&mut_attr2, PTHREAD_MUTEX_RECURSIVE); |
| zassert_false(temp, "setting mutex2 type is failed"); |
| temp = pthread_mutex_init(&mutex2, &mut_attr2); |
| zassert_false(temp, "mutex2 initialization is failed"); |
| |
| temp = pthread_mutexattr_gettype(&mut_attr2, &type); |
| zassert_false(temp, "reading mutex2 type is failed"); |
| temp = pthread_mutexattr_getprotocol(&mut_attr2, &protocol); |
| zassert_false(temp, "reading mutex2 protocol is failed"); |
| |
| zassert_equal(type, PTHREAD_MUTEX_RECURSIVE, |
| "mutex2 type is not recursive"); |
| |
| zassert_equal(protocol, PTHREAD_PRIO_NONE, |
| "mutex2 protocol is not prio_none"); |
| ret = pthread_create(&thread_2, &attr2, &recursive_mutex_entry, NULL); |
| |
| zassert_false(ret, "Thread2 creation failed"); |
| |
| pthread_join(thread_2, NULL); |
| temp = pthread_mutex_destroy(&mutex2); |
| zassert_false(temp, "Destroying mutex2 is failed"); |
| } |