]> git.lizzy.rs Git - rust.git/commitdiff
Move pthread_create and related shims to a separate file.
authorVytautas Astrauskas <astrauv@amazon.com>
Mon, 6 Apr 2020 20:44:47 +0000 (13:44 -0700)
committerVytautas Astrauskas <astrauv@amazon.com>
Mon, 27 Apr 2020 21:23:32 +0000 (14:23 -0700)
src/lib.rs
src/shims/foreign_items/posix.rs
src/shims/mod.rs
src/shims/threads.rs [new file with mode: 0644]
src/threads.rs

index c042526be64c1723f17a07168b6e6f314eb9e412..d8b3397c8e9ba46993776f7e2a8497de1c46798a 100644 (file)
@@ -42,6 +42,7 @@
 pub use crate::shims::os_str::EvalContextExt as OsStrEvalContextExt;
 pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as PanicEvalContextExt};
 pub use crate::shims::sync::{EvalContextExt as SyncEvalContextExt};
+pub use crate::shims::threads::EvalContextExt as ThreadShimsEvalContextExt;
 pub use crate::shims::time::EvalContextExt as TimeEvalContextExt;
 pub use crate::shims::tls::{EvalContextExt as TlsEvalContextExt, TlsData};
 pub use crate::shims::EvalContextExt as ShimsEvalContextExt;
index 878ab8896ddace2af73df68a40dd18798ed4f101..7d2cb16afee4241fff63a2b53b586e117d21c4f2 100644 (file)
@@ -6,7 +6,6 @@
 use log::trace;
 
 use crate::*;
-use rustc_index::vec::Idx;
 use rustc_middle::mir;
 use rustc_target::abi::{Align, LayoutOf, Size};
 
@@ -316,66 +315,19 @@ fn emulate_foreign_item_by_name(
 
             // Threading
             "pthread_create" => {
-                println!("WARNING: The thread support is experimental. \
-                          For example, Miri does not detect data races yet.");
                 assert_eq!(args.len(), 4);
-                let func = args[2];
-                let fn_ptr = this.read_scalar(func)?.not_undef()?;
-                let fn_val = this.memory.get_fn(fn_ptr)?;
-                let instance = match fn_val {
-                    rustc_mir::interpret::FnVal::Instance(instance) => instance,
-                    _ => unreachable!(),
-                };
-                let thread_info_place = this.deref_operand(args[0])?;
-                let thread_info_type = args[0].layout.ty
-                    .builtin_deref(true)
-                    .ok_or_else(|| err_ub_format!(
-                        "wrong signature used for `pthread_create`: first argument must be a raw pointer."
-                    ))?
-                    .ty;
-                let thread_info_layout = this.layout_of(thread_info_type)?;
-                let func_arg = match *args[3] {
-                    rustc_mir::interpret::Operand::Immediate(immediate) => immediate,
-                    _ => unreachable!(),
-                };
-                let func_args = [func_arg];
-                let ret_place =
-                    this.allocate(this.layout_of(this.tcx.types.usize)?, MiriMemoryKind::Machine.into());
-                let new_thread_id = this.create_thread()?;
-                let old_thread_id = this.set_active_thread(new_thread_id)?;
-                this.call_function(
-                    instance,
-                    &func_args[..],
-                    Some(ret_place.into()),
-                    StackPopCleanup::None { cleanup: true },
-                )?;
-                this.set_active_thread(old_thread_id)?;
-                this.write_scalar(
-                    Scalar::from_uint(new_thread_id.index() as u128, thread_info_layout.size),
-                    thread_info_place.into(),
-                )?;
-
-                // Return success (`0`).
-                this.write_null(dest)?;
+                let result = this.pthread_create(args[0], args[1], args[2], args[3])?;
+                this.write_scalar(Scalar::from_i32(result), dest)?;
             }
             "pthread_join" => {
                 assert_eq!(args.len(), 2);
-                assert!(
-                    this.is_null(this.read_scalar(args[1])?.not_undef()?)?,
-                    "Miri supports pthread_join only with retval==NULL"
-                );
-                let thread = this.read_scalar(args[0])?.not_undef()?.to_machine_usize(this)?;
-                this.join_thread(thread.into())?;
-
-                // Return success (`0`).
-                this.write_null(dest)?;
+                let result = this.pthread_join(args[0], args[1])?;
+                this.write_scalar(Scalar::from_i32(result), dest)?;
             }
             "pthread_detach" => {
-                let thread = this.read_scalar(args[0])?.not_undef()?.to_machine_usize(this)?;
-                this.detach_thread(thread.into())?;
-
-                // Return success (`0`).
-                this.write_null(dest)?;
+                assert_eq!(args.len(), 1);
+                let result = this.pthread_detach(args[0])?;
+                this.write_scalar(Scalar::from_i32(result), dest)?;
             }
 
             "pthread_attr_getguardsize" => {
index 71ff6024ec6fe5e1dc057450f1a45448f1ae77e1..118058dd32e743f695dd6f1ee9295cf51fb72b12 100644 (file)
@@ -6,6 +6,7 @@
 pub mod os_str;
 pub mod panic;
 pub mod sync;
+pub mod threads;
 pub mod time;
 pub mod tls;
 
diff --git a/src/shims/threads.rs b/src/shims/threads.rs
new file mode 100644 (file)
index 0000000..6e1087d
--- /dev/null
@@ -0,0 +1,84 @@
+use crate::*;
+use rustc_index::vec::Idx;
+use rustc_target::abi::LayoutOf;
+
+impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
+    fn pthread_create(
+        &mut self,
+        thread: OpTy<'tcx, Tag>,
+        _attr: OpTy<'tcx, Tag>,
+        start_routine: OpTy<'tcx, Tag>,
+        arg: OpTy<'tcx, Tag>,
+    ) -> InterpResult<'tcx, i32> {
+        println!(
+            "WARNING: The thread support is experimental. \
+                  For example, Miri does not detect data races yet."
+        );
+
+        let this = self.eval_context_mut();
+
+        let new_thread_id = this.create_thread()?;
+        let old_thread_id = this.set_active_thread(new_thread_id)?;
+
+        let thread_info_place = this.deref_operand(thread)?;
+        let thread_info_type = thread.layout.ty
+            .builtin_deref(true)
+            .ok_or_else(|| err_ub_format!(
+                "wrong signature used for `pthread_create`: first argument must be a raw pointer."
+            ))?
+            .ty;
+        let thread_info_layout = this.layout_of(thread_info_type)?;
+        this.write_scalar(
+            Scalar::from_uint(new_thread_id.index() as u128, thread_info_layout.size),
+            thread_info_place.into(),
+        )?;
+
+        let fn_ptr = this.read_scalar(start_routine)?.not_undef()?;
+        let instance = this.memory.get_fn(fn_ptr)?.as_instance()?;
+
+        let func_arg = match *arg {
+            rustc_mir::interpret::Operand::Immediate(immediate) => immediate,
+            _ => unreachable!(),
+        };
+        let func_args = [func_arg];
+
+        let ret_place =
+            this.allocate(this.layout_of(this.tcx.types.usize)?, MiriMemoryKind::Machine.into());
+
+        this.call_function(
+            instance,
+            &func_args[..],
+            Some(ret_place.into()),
+            StackPopCleanup::None { cleanup: true },
+        )?;
+
+        this.set_active_thread(old_thread_id)?;
+
+        Ok(0)
+    }
+    fn pthread_join(
+        &mut self,
+        thread: OpTy<'tcx, Tag>,
+        retval: OpTy<'tcx, Tag>,
+    ) -> InterpResult<'tcx, i32> {
+        let this = self.eval_context_mut();
+
+        if !this.is_null(this.read_scalar(retval)?.not_undef()?)? {
+            throw_unsup_format!("Miri supports pthread_join only with retval==NULL");
+        }
+
+        let thread_id = this.read_scalar(thread)?.not_undef()?.to_machine_usize(this)?;
+        this.join_thread(thread_id.into())?;
+
+        Ok(0)
+    }
+    fn pthread_detach(&mut self, thread: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
+        let this = self.eval_context_mut();
+
+        let thread_id = this.read_scalar(thread)?.not_undef()?.to_machine_usize(this)?;
+        this.detach_thread(thread_id.into())?;
+
+        Ok(0)
+    }
+}
index 618713e3c3deaf5c2671167efa2276abeb7ac456..9d982359bfbb1cced3ae40ec80c19711b7c485d7 100644 (file)
@@ -91,9 +91,6 @@ pub struct ThreadSet<'mir, 'tcx> {
     ///
     /// Note that this vector also contains terminated threads.
     threads: IndexVec<ThreadId, Thread<'mir, 'tcx>>,
-
-    /// List of threads that just terminated. TODO: Cleanup.
-    terminated_threads: Vec<ThreadId>,
 }
 
 impl<'mir, 'tcx> Default for ThreadSet<'mir, 'tcx> {
@@ -103,7 +100,6 @@ fn default() -> Self {
         Self {
             active_thread: ThreadId::new(0),
             threads: threads,
-            terminated_threads: Default::default(),
         }
     }
 }