1 /*
2  * Copyright (c) 2023, Meta
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <pthread.h>
8 
9 #include <zephyr/ztest.h>
10 #include <zephyr/sys/util.h>
11 
ZTEST(posix_apis,test_spin_init_destroy)12 ZTEST(posix_apis, test_spin_init_destroy)
13 {
14 	pthread_spinlock_t lock;
15 
16 	zassert_equal(pthread_spin_init(NULL, PTHREAD_PROCESS_PRIVATE), EINVAL,
17 		      "pthread_spin_init() did not return EINVAL with NULL lock pointer");
18 	zassert_equal(pthread_spin_init(&lock, 42), EINVAL,
19 		      "pthread_spin_init() did not return EINVAL with invalid pshared");
20 	zassert_equal(pthread_spin_destroy(NULL), EINVAL,
21 		      "pthread_spin_destroy() did not return EINVAL with NULL lock pointer");
22 
23 	zassert_ok(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE), "pthread_spin_init() failed");
24 	zassert_ok(pthread_spin_destroy(&lock), "pthread_spin_destroy() failed");
25 }
26 
ZTEST(posix_apis,test_spin_descriptor_leak)27 ZTEST(posix_apis, test_spin_descriptor_leak)
28 {
29 	pthread_spinlock_t lock[CONFIG_MAX_PTHREAD_SPINLOCK_COUNT];
30 
31 	for (size_t j = 0; j < 2; ++j) {
32 		for (size_t i = 0; i < ARRAY_SIZE(lock); ++i) {
33 			zassert_ok(pthread_spin_init(&lock[i], PTHREAD_PROCESS_PRIVATE),
34 				   "failed to initialize spinlock %zu (rep %zu)", i, j);
35 		}
36 
37 		zassert_equal(pthread_spin_init(&lock[CONFIG_MAX_PTHREAD_SPINLOCK_COUNT],
38 						PTHREAD_PROCESS_PRIVATE),
39 			      ENOMEM,
40 			      "should not be able to initialize more than "
41 			      "CONFIG_MAX_PTHREAD_SPINLOCK_COUNT spinlocks");
42 
43 		for (size_t i = 0; i < ARRAY_SIZE(lock); ++i) {
44 			zassert_ok(pthread_spin_destroy(&lock[i]),
45 				   "failed to destroy spinlock %zu (rep %zu)", i, j);
46 		}
47 	}
48 }
49 
ZTEST(posix_apis,test_spin_lock_unlock)50 ZTEST(posix_apis, test_spin_lock_unlock)
51 {
52 	pthread_spinlock_t lock;
53 
54 	zassert_equal(pthread_spin_lock(NULL), EINVAL,
55 		      "pthread_spin_lock() did not return EINVAL with NULL lock pointer");
56 	zassert_equal(pthread_spin_trylock(NULL), EINVAL,
57 		      "pthread_spin_lock() did not return EINVAL with NULL lock pointer");
58 	zassert_equal(pthread_spin_unlock(NULL), EINVAL,
59 		      "pthread_spin_lock() did not return EINVAL with NULL lock pointer");
60 
61 	zassert_ok(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE), "pthread_spin_init() failed");
62 
63 	zassert_ok(pthread_spin_lock(&lock), "pthread_spin_lock() failed");
64 	zassert_ok(pthread_spin_unlock(&lock), "pthread_spin_lock() failed");
65 
66 	zassert_ok(pthread_spin_trylock(&lock), "pthread_spin_trylock() failed");
67 	zassert_ok(pthread_spin_unlock(&lock), "pthread_spin_unlock() failed");
68 
69 	zassert_ok(pthread_spin_destroy(&lock), "pthread_spin_init() failed");
70 	zassert_equal(pthread_spin_destroy(&lock), EINVAL, "pthread_spin_unlock() did not fail");
71 }
72