@@ -274,15 +274,52 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
274274 interp_ok ( Scalar :: from_u32 ( this. get_pid ( ) ) )
275275 }
276276
277- fn linux_gettid ( & mut self ) -> InterpResult < ' tcx , Scalar > {
277+ /// The `gettid`-like function for Unix platforms that take no parameters and return a 32-bit
278+ /// integer. It is not always named "gettid".
279+ fn unix_gettid ( & mut self , link_name : & str ) -> InterpResult < ' tcx , Scalar > {
278280 let this = self . eval_context_ref ( ) ;
279- this. assert_target_os ( "linux" , "gettid" ) ;
281+ this. assert_target_os_is_unix ( link_name ) ;
280282
281- let index = this. machine . threads . active_thread ( ) . to_u32 ( ) ;
283+ // For most platforms the return type is an `i32`, but some are unsigned. The TID
284+ // will always be positive so we don't need to differentiate.
285+ interp_ok ( Scalar :: from_u32 ( this. get_current_tid ( ) ) )
286+ }
287+
288+ /// The Apple-specific `int pthread_threadid_np(pthread_t thread, uint64_t *thread_id)`, which
289+ /// allows querying the ID for arbitrary threads, identified by their pthread_t.
290+ ///
291+ /// API documentation: <https://www.manpagez.com/man/3/pthread_threadid_np/>.
292+ fn apple_pthread_threadip_np (
293+ & mut self ,
294+ thread_op : & OpTy < ' tcx > ,
295+ tid_op : & OpTy < ' tcx > ,
296+ ) -> InterpResult < ' tcx , Scalar > {
297+ let this = self . eval_context_mut ( ) ;
298+ this. assert_target_os ( "macos" , "pthread_threadip_np" ) ;
299+
300+ let tid_dest = this. read_pointer ( tid_op) ?;
301+ if this. ptr_is_null ( tid_dest) ? {
302+ // If NULL is passed, an error is immediately returned
303+ return interp_ok ( this. eval_libc ( "EINVAL" ) ) ;
304+ }
305+
306+ let thread = this. read_scalar ( thread_op) ?. to_int ( this. libc_ty_layout ( "pthread_t" ) . size ) ?;
307+ let thread = if thread == 0 {
308+ // Null thread ID indicates that we are querying the active thread.
309+ this. machine . threads . active_thread ( )
310+ } else {
311+ // Our pthread_t is just the raw ThreadId.
312+ let Ok ( thread) = this. thread_id_try_from ( thread) else {
313+ return interp_ok ( this. eval_libc ( "ESRCH" ) ) ;
314+ } ;
315+ thread
316+ } ;
282317
283- // Compute a TID for this thread, ensuring that the main thread has PID == TID.
284- let tid = this. get_pid ( ) . strict_add ( index) ;
318+ let tid = this. get_tid ( thread) ;
319+ let tid_dest = this. deref_pointer_as ( tid_op, this. machine . layouts . u64 ) ?;
320+ this. write_int ( tid, & tid_dest) ?;
285321
286- interp_ok ( Scalar :: from_u32 ( tid) )
322+ // Possible errors have been handled, return success.
323+ interp_ok ( Scalar :: from_u32 ( 0 ) )
287324 }
288325}
0 commit comments