1 /*
2  * Copyright (c) 2024, Meta
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <pthread.h>
8 
9 #include <zephyr/sys/util.h>
10 #include <zephyr/ztest.h>
11 
12 #define BIOS_FOOD           0xB105F00D
13 #define SCHED_INVALID       4242
14 #define INVALID_DETACHSTATE 7373
15 
16 static bool attr_valid;
17 static pthread_attr_t attr;
18 static const pthread_attr_t uninit_attr;
19 
ZTEST(posix_threads_ext,test_pthread_attr_getguardsize)20 ZTEST(posix_threads_ext, test_pthread_attr_getguardsize)
21 {
22 	size_t guardsize;
23 
24 	/* degenerate cases */
25 	{
26 		if (false) {
27 			/* undefined behaviour */
28 			zassert_equal(pthread_attr_getguardsize(NULL, NULL), EINVAL);
29 			zassert_equal(pthread_attr_getguardsize(NULL, &guardsize), EINVAL);
30 			zassert_equal(pthread_attr_getguardsize(&uninit_attr, &guardsize), EINVAL);
31 		}
32 		zassert_equal(pthread_attr_getguardsize(&attr, NULL), EINVAL);
33 	}
34 
35 	guardsize = BIOS_FOOD;
36 	zassert_ok(pthread_attr_getguardsize(&attr, &guardsize));
37 	zassert_not_equal(guardsize, BIOS_FOOD);
38 }
39 
ZTEST(posix_threads_ext,test_pthread_attr_setguardsize)40 ZTEST(posix_threads_ext, test_pthread_attr_setguardsize)
41 {
42 	size_t guardsize = CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_DEFAULT;
43 	size_t sizes[] = {0, BIT_MASK(CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_BITS / 2),
44 			  BIT_MASK(CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_BITS)};
45 
46 	/* valid value */
47 	zassert_ok(pthread_attr_getguardsize(&attr, &guardsize));
48 
49 	/* degenerate cases */
50 	{
51 		if (false) {
52 			/* undefined behaviour */
53 			zassert_equal(pthread_attr_setguardsize(NULL, SIZE_MAX), EINVAL);
54 			zassert_equal(pthread_attr_setguardsize(NULL, guardsize), EINVAL);
55 			zassert_equal(pthread_attr_setguardsize((pthread_attr_t *)&uninit_attr,
56 								guardsize),
57 				      EINVAL);
58 		}
59 		zassert_equal(pthread_attr_setguardsize(&attr, SIZE_MAX), EINVAL);
60 	}
61 
62 	ARRAY_FOR_EACH(sizes, i) {
63 		zassert_ok(pthread_attr_setguardsize(&attr, sizes[i]));
64 		guardsize = ~sizes[i];
65 		zassert_ok(pthread_attr_getguardsize(&attr, &guardsize));
66 		zassert_equal(guardsize, sizes[i]);
67 	}
68 }
69 
ZTEST(posix_threads_ext,test_pthread_mutexattr_gettype)70 ZTEST(posix_threads_ext, test_pthread_mutexattr_gettype)
71 {
72 	int type;
73 	pthread_mutexattr_t attr;
74 
75 	/* degenerate cases */
76 	{
77 		if (false) {
78 			/* undefined behaviour */
79 			zassert_equal(EINVAL, pthread_mutexattr_gettype(&attr, &type));
80 		}
81 		zassert_equal(EINVAL, pthread_mutexattr_gettype(NULL, NULL));
82 		zassert_equal(EINVAL, pthread_mutexattr_gettype(NULL, &type));
83 		zassert_equal(EINVAL, pthread_mutexattr_gettype(&attr, NULL));
84 	}
85 
86 	zassert_ok(pthread_mutexattr_init(&attr));
87 	zassert_ok(pthread_mutexattr_gettype(&attr, &type));
88 	zassert_equal(type, PTHREAD_MUTEX_DEFAULT);
89 	zassert_ok(pthread_mutexattr_destroy(&attr));
90 }
91 
ZTEST(posix_threads_ext,test_pthread_mutexattr_settype)92 ZTEST(posix_threads_ext, test_pthread_mutexattr_settype)
93 {
94 	int type;
95 	pthread_mutexattr_t attr;
96 
97 	/* degenerate cases */
98 	{
99 		if (false) {
100 			/* undefined behaviour */
101 			zassert_equal(EINVAL,
102 				      pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT));
103 		}
104 		zassert_equal(EINVAL, pthread_mutexattr_settype(NULL, 42));
105 		zassert_equal(EINVAL, pthread_mutexattr_settype(NULL, PTHREAD_MUTEX_NORMAL));
106 		zassert_equal(EINVAL, pthread_mutexattr_settype(&attr, 42));
107 	}
108 
109 	zassert_ok(pthread_mutexattr_init(&attr));
110 
111 	zassert_ok(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT));
112 	zassert_ok(pthread_mutexattr_gettype(&attr, &type));
113 	zassert_equal(type, PTHREAD_MUTEX_DEFAULT);
114 
115 	zassert_ok(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL));
116 	zassert_ok(pthread_mutexattr_gettype(&attr, &type));
117 	zassert_equal(type, PTHREAD_MUTEX_NORMAL);
118 
119 	zassert_ok(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE));
120 	zassert_ok(pthread_mutexattr_gettype(&attr, &type));
121 	zassert_equal(type, PTHREAD_MUTEX_RECURSIVE);
122 
123 	zassert_ok(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK));
124 	zassert_ok(pthread_mutexattr_gettype(&attr, &type));
125 	zassert_equal(type, PTHREAD_MUTEX_ERRORCHECK);
126 
127 	zassert_ok(pthread_mutexattr_destroy(&attr));
128 }
129 
before(void * arg)130 static void before(void *arg)
131 {
132 	ARG_UNUSED(arg);
133 
134 	zassert_ok(pthread_attr_init(&attr));
135 	attr_valid = true;
136 }
137 
after(void * arg)138 static void after(void *arg)
139 {
140 	ARG_UNUSED(arg);
141 
142 	if (attr_valid) {
143 		(void)pthread_attr_destroy(&attr);
144 		attr_valid = false;
145 	}
146 }
147 
148 ZTEST_SUITE(posix_threads_ext, NULL, NULL, before, after, NULL);
149