]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/pass-dep/shims/pthreads.rs
Rollup merge of #102055 - c410-f3r:moar-errors, r=petrochenkov
[rust.git] / src / tools / miri / tests / pass-dep / shims / pthreads.rs
1 //@ignore-target-windows: No libc on Windows
2
3 fn main() {
4     test_mutex_libc_init_recursive();
5     test_mutex_libc_init_normal();
6     test_mutex_libc_init_errorcheck();
7     test_rwlock_libc_static_initializer();
8
9     #[cfg(any(target_os = "linux"))]
10     test_mutex_libc_static_initializer_recursive();
11 }
12
13 fn test_mutex_libc_init_recursive() {
14     unsafe {
15         let mut attr: libc::pthread_mutexattr_t = std::mem::zeroed();
16         assert_eq!(libc::pthread_mutexattr_init(&mut attr as *mut _), 0);
17         assert_eq!(
18             libc::pthread_mutexattr_settype(&mut attr as *mut _, libc::PTHREAD_MUTEX_RECURSIVE),
19             0,
20         );
21         let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
22         assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mut attr as *mut _), 0);
23         assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
24         assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0);
25         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
26         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
27         assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0);
28         assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
29         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
30         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
31         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), libc::EPERM);
32         assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0);
33         assert_eq!(libc::pthread_mutexattr_destroy(&mut attr as *mut _), 0);
34     }
35 }
36
37 fn test_mutex_libc_init_normal() {
38     unsafe {
39         let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
40         assert_eq!(
41             libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, 0x12345678),
42             libc::EINVAL,
43         );
44         assert_eq!(
45             libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL),
46             0,
47         );
48         let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
49         assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0);
50         assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
51         assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), libc::EBUSY);
52         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
53         assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0);
54         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
55         assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0);
56     }
57 }
58
59 fn test_mutex_libc_init_errorcheck() {
60     unsafe {
61         let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
62         assert_eq!(
63             libc::pthread_mutexattr_settype(
64                 &mut mutexattr as *mut _,
65                 libc::PTHREAD_MUTEX_ERRORCHECK,
66             ),
67             0,
68         );
69         let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
70         assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0);
71         assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
72         assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), libc::EBUSY);
73         assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), libc::EDEADLK);
74         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
75         assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0);
76         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
77         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), libc::EPERM);
78         assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0);
79     }
80 }
81
82 // Only linux provides PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
83 // libc for macOS just has the default PTHREAD_MUTEX_INITIALIZER.
84 #[cfg(target_os = "linux")]
85 fn test_mutex_libc_static_initializer_recursive() {
86     let mutex = std::cell::UnsafeCell::new(libc::PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
87     unsafe {
88         assert_eq!(libc::pthread_mutex_lock(mutex.get()), 0);
89         assert_eq!(libc::pthread_mutex_trylock(mutex.get()), 0);
90         assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0);
91         assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0);
92         assert_eq!(libc::pthread_mutex_trylock(mutex.get()), 0);
93         assert_eq!(libc::pthread_mutex_lock(mutex.get()), 0);
94         assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0);
95         assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0);
96         assert_eq!(libc::pthread_mutex_unlock(mutex.get()), libc::EPERM);
97         assert_eq!(libc::pthread_mutex_destroy(mutex.get()), 0);
98     }
99 }
100
101 // Testing the behavior of std::sync::RwLock does not fully exercise the pthread rwlock shims, we
102 // need to go a layer deeper and test the behavior of the libc functions, because
103 // std::sys::unix::rwlock::RWLock itself keeps track of write_locked and num_readers.
104 fn test_rwlock_libc_static_initializer() {
105     let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
106     unsafe {
107         assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0);
108         assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0);
109         assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0);
110         assert_eq!(libc::pthread_rwlock_tryrdlock(rw.get()), 0);
111         assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0);
112         assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), libc::EBUSY);
113         assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0);
114
115         assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0);
116         assert_eq!(libc::pthread_rwlock_tryrdlock(rw.get()), libc::EBUSY);
117         assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), libc::EBUSY);
118         assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0);
119
120         assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), 0);
121         assert_eq!(libc::pthread_rwlock_tryrdlock(rw.get()), libc::EBUSY);
122         assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), libc::EBUSY);
123         assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0);
124
125         assert_eq!(libc::pthread_rwlock_destroy(rw.get()), 0);
126     }
127 }