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 #include <semaphore.h>
11
12 #define STACK_SIZE 1024
13
14 sem_t sema;
15 void *dummy_sem;
16
17 struct sched_param schedparam;
18 int schedpolicy = SCHED_FIFO;
19
20 static K_THREAD_STACK_DEFINE(stack, STACK_SIZE);
21
child_func(void * p1)22 static void *child_func(void *p1)
23 {
24 zassert_equal(sem_post(&sema), 0, "sem_post failed");
25 return NULL;
26 }
27
initialize_thread_attr(pthread_attr_t * attr)28 void initialize_thread_attr(pthread_attr_t *attr)
29 {
30 int ret;
31
32 schedparam.sched_priority = 1;
33
34 ret = pthread_attr_init(attr);
35 if (ret != 0) {
36 zassert_equal(pthread_attr_destroy(attr), 0,
37 "Unable to destroy pthread object attrib");
38 zassert_equal(pthread_attr_init(attr), 0,
39 "Unable to create pthread object attrib");
40 }
41
42 pthread_attr_setstack(attr, &stack, STACK_SIZE);
43 pthread_attr_setschedpolicy(attr, schedpolicy);
44 pthread_attr_setschedparam(attr, &schedparam);
45 }
46
test_posix_semaphore(void)47 void test_posix_semaphore(void)
48 {
49 pthread_t thread1, thread2;
50 pthread_attr_t attr1, attr2;
51 int val, ret;
52 struct timespec abstime;
53
54 initialize_thread_attr(&attr1);
55
56 /* TESTPOINT: Check if sema value is less than
57 * CONFIG_SEM_VALUE_MAX
58 */
59 zassert_equal(sem_init(&sema, 0, (CONFIG_SEM_VALUE_MAX + 1)), -1,
60 "value larger than %d\n", CONFIG_SEM_VALUE_MAX);
61 zassert_equal(errno, EINVAL, NULL);
62
63 zassert_equal(sem_init(&sema, 0, 0), 0, "sem_init failed");
64
65 /* TESTPOINT: Call sem_post with invalid kobject */
66 zassert_equal(sem_post(dummy_sem), -1, "sem_post of"
67 " invalid semaphore object didn't fail");
68 zassert_equal(errno, EINVAL, NULL);
69
70 /* TESTPOINT: Check if semaphore value is as set */
71 zassert_equal(sem_getvalue(&sema, &val), 0, NULL);
72 zassert_equal(val, 0, NULL);
73
74 /* TESTPOINT: Check if sema is acquired when it
75 * is not available
76 */
77 zassert_equal(sem_trywait(&sema), -1, NULL);
78 zassert_equal(errno, EAGAIN, NULL);
79
80 ret = pthread_create(&thread1, &attr1, child_func, NULL);
81 zassert_equal(ret, 0, "Thread creation failed");
82
83 zassert_equal(clock_gettime(CLOCK_REALTIME, &abstime), 0,
84 "clock_gettime failed");
85
86 abstime.tv_sec += 5;
87
88 /* TESPOINT: Wait for 5 seconds and acquire sema given
89 * by thread1
90 */
91 zassert_equal(sem_timedwait(&sema, &abstime), 0, NULL);
92
93 /* TESTPOINT: Semaphore is already acquired, check if
94 * no semaphore is available
95 */
96 zassert_equal(sem_timedwait(&sema, &abstime), -1, NULL);
97 zassert_equal(errno, ETIMEDOUT, NULL);
98
99 /* TESTPOINT: sem_destroy with invalid kobject */
100 zassert_equal(sem_destroy(dummy_sem), -1, "invalid"
101 " semaphore is destroyed");
102 zassert_equal(errno, EINVAL, NULL);
103
104 zassert_equal(sem_destroy(&sema), 0, "semaphore is not destroyed");
105
106 zassert_equal(pthread_attr_destroy(&attr1), 0,
107 "Unable to destroy pthread object attrib");
108
109 /* TESTPOINT: Initialize sema with 1 */
110 zassert_equal(sem_init(&sema, 0, 1), 0, "sem_init failed");
111 zassert_equal(sem_getvalue(&sema, &val), 0, NULL);
112 zassert_equal(val, 1, NULL);
113
114 zassert_equal(sem_destroy(&sema), -1, "acquired semaphore"
115 " is destroyed");
116 zassert_equal(errno, EBUSY, NULL);
117
118 /* TESTPOINT: take semaphore which is initialized with 1 */
119 zassert_equal(sem_trywait(&sema), 0, NULL);
120
121 initialize_thread_attr(&attr2);
122
123 zassert_equal(pthread_create(&thread2, &attr2, child_func, NULL), 0,
124 "Thread creation failed");
125
126 /* TESTPOINT: Wait and acquire semaphore till thread2 gives */
127 zassert_equal(sem_wait(&sema), 0, "sem_wait failed");
128 }
129