11use std:: time:: { Duration , Instant } ;
22
3+ use rustc_middle:: ty:: layout:: LayoutOf ;
4+ use rustc_target:: spec:: abi:: Abi ;
5+
36use crate :: thread:: Time ;
47use crate :: * ;
58use shims:: windows:: handle:: Handle ;
@@ -8,6 +11,40 @@ impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mi
811
912#[ allow( non_snake_case) ]
1013pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
14+ fn CreateThread (
15+ & mut self ,
16+ security_op : & OpTy < ' tcx , Tag > ,
17+ stacksize_op : & OpTy < ' tcx , Tag > ,
18+ start_op : & OpTy < ' tcx , Tag > ,
19+ arg_op : & OpTy < ' tcx , Tag > ,
20+ flags_op : & OpTy < ' tcx , Tag > ,
21+ thread_op : & OpTy < ' tcx , Tag > ,
22+ ) -> InterpResult < ' tcx , ThreadId > {
23+ let this = self . eval_context_mut ( ) ;
24+
25+ if !this. ptr_is_null ( this. read_pointer ( security_op) ?) ? {
26+ throw_unsup_format ! ( "non-null `lpThreadAttributes` in `CreateThread`" )
27+ }
28+
29+ // stacksize is ignored, but still needs to be a valid usize
30+ let _ = this. read_scalar ( stacksize_op) ?. to_machine_usize ( this) ?;
31+
32+ if this. read_scalar ( flags_op) ?. to_u32 ( ) ? != 0 {
33+ throw_unsup_format ! ( "non-zero `dwCreationFlags` in `CreateThread`" )
34+ }
35+
36+ let thread =
37+ if this. ptr_is_null ( this. read_pointer ( thread_op) ?) ? { None } else { Some ( thread_op) } ;
38+
39+ this. start_thread (
40+ thread,
41+ start_op,
42+ Abi :: System { unwind : false } ,
43+ arg_op,
44+ this. layout_of ( this. tcx . types . u32 ) ?,
45+ )
46+ }
47+
1148 fn WaitForSingleObject (
1249 & mut self ,
1350 handle : & OpTy < ' tcx , Tag > ,
0 commit comments