@@ -274,15 +274,52 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
274
274
interp_ok ( Scalar :: from_u32 ( this. get_pid ( ) ) )
275
275
}
276
276
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 > {
278
280
let this = self . eval_context_ref ( ) ;
279
- this. assert_target_os ( "linux" , "gettid" ) ;
281
+ this. assert_target_os_is_unix ( link_name ) ;
280
282
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
+ } ;
282
317
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) ?;
285
321
286
- interp_ok ( Scalar :: from_u32 ( tid) )
322
+ // Possible errors have been handled, return success.
323
+ interp_ok ( Scalar :: from_u32 ( 0 ) )
287
324
}
288
325
}
0 commit comments