| #![allow(unused)] | |
| use std::ffi::c_void; | |
| use libc::{self, pthread_attr_t, pthread_t}; | |
| /// Spawn a thread using `pthread_create`, abort the process on any errors. | |
| pub unsafe fn spawn_pthread( | |
| f: extern "C" fn(*mut c_void) -> *mut c_void, | |
| value: *mut c_void, | |
| ) -> pthread_t { | |
| let mut thread_id: pthread_t = 0; | |
| let attr: *const pthread_attr_t = std::ptr::null(); | |
| if unsafe { libc::pthread_create(&raw mut thread_id, attr, f, value) } != 0 { | |
| std::process::abort(); | |
| } | |
| thread_id | |
| } | |
| /// Unsafe because we do *not* check that `F` is `Send + 'static`. | |
| /// That makes it much easier to write tests... | |
| pub unsafe fn spawn_pthread_closure<F: FnOnce()>(f: F) -> pthread_t { | |
| let mut thread_id: pthread_t = 0; | |
| let attr: *const pthread_attr_t = std::ptr::null(); | |
| let f = Box::new(f); | |
| extern "C" fn thread_func<F: FnOnce()>(f: *mut c_void) -> *mut c_void { | |
| let f = unsafe { Box::from_raw(f as *mut F) }; | |
| f(); | |
| std::ptr::null_mut() | |
| } | |
| if unsafe { | |
| libc::pthread_create( | |
| &raw mut thread_id, | |
| attr, | |
| thread_func::<F>, | |
| Box::into_raw(f) as *mut c_void, | |
| ) | |
| } != 0 | |
| { | |
| std::process::abort(); | |
| } | |
| thread_id | |
| } | |
| // Join the given pthread, abort the process on any errors. | |
| pub unsafe fn join_pthread(thread_id: pthread_t) { | |
| if unsafe { libc::pthread_join(thread_id, std::ptr::null_mut()) } != 0 { | |
| std::process::abort(); | |
| } | |
| } | |
| /// Spawn `N` threads using `pthread_create` without any arguments, abort the process on any errors. | |
| pub unsafe fn spawn_pthreads_no_params<const N: usize>( | |
| functions: [extern "C" fn(*mut c_void) -> *mut c_void; N], | |
| ) -> [pthread_t; N] { | |
| functions.map(|func| spawn_pthread(func, std::ptr::null_mut())) | |
| } | |
| // Join the `N` given pthreads, abort the process on any errors. | |
| pub unsafe fn join_pthreads<const N: usize>(thread_ids: [pthread_t; N]) { | |
| let _ = thread_ids.map(|id| join_pthread(id)); | |
| } |