creusot_std/std/
thread.rs1use crate::{ghost::invariant::Tokens, prelude::*};
2use ::std::thread::{self, JoinHandle, ScopedJoinHandle};
3
4pub trait JoinHandleExt<T> {
6 #[logic]
8 fn valid_result(self, x: T) -> bool;
9
10 #[ensures(self.valid_result(result))]
17 fn join_unwrap(self) -> T;
18}
19
20impl<T> JoinHandleExt<T> for JoinHandle<T> {
21 #[logic(opaque)]
22 fn valid_result(self, _x: T) -> bool {
23 dead
24 }
25
26 #[ensures(self.valid_result(result))]
27 #[trusted]
28 fn join_unwrap(self) -> T {
29 self.join().unwrap()
30 }
31}
32
33impl<T> JoinHandleExt<T> for ScopedJoinHandle<'_, T> {
34 #[logic(opaque)]
35 fn valid_result(self, _x: T) -> bool {
36 dead
37 }
38
39 #[ensures(self.valid_result(result))]
40 #[trusted]
41 fn join_unwrap(self) -> T {
42 self.join().unwrap()
43 }
44}
45
46extern_spec! {
47 impl<T> JoinHandle<T> {
48 #[ensures(true)] fn is_finished(&self) -> bool;
50 }
51
52 impl<T> ScopedJoinHandle<'_, T> {
53 #[ensures(true)] fn is_finished(&self) -> bool;
55 }
56}
57
58#[requires(forall<t: Ghost<Tokens>> (forall<ns> t.contains(ns)) ==> f.precondition((t,)))]
62#[ensures(exists<t: Ghost<Tokens>> (forall<ns> t.contains(ns)) && forall<r> result.valid_result(r) ==> f.postcondition_once((t,), r))]
63#[trusted]
64pub fn spawn<F, T>(f: F) -> JoinHandle<T>
65where
66 F: FnOnce(Ghost<Tokens>) -> T + Send + 'static,
67 T: Send + 'static,
68{
69 ::std::thread::spawn(|| f(Tokens::new()))
70}
71
72pub struct Scope<'scope, 'env: 'scope> {
74 inner: &'scope thread::Scope<'scope, 'env>,
75}
76
77impl<'scope, 'env: 'scope> Scope<'scope, 'env> {
78 #[requires(forall<t: Ghost<Tokens>> (forall<ns> t.contains(ns)) ==> f.precondition((t,)))]
79 #[ensures(exists<t: Ghost<Tokens>> (forall<ns> t.contains(ns)) && forall<r> result.valid_result(r) ==> f.postcondition_once((t,), r))]
80 #[trusted]
81 pub fn spawn<F, T>(&mut self, f: F) -> ScopedJoinHandle<'scope, T>
82 where
83 F: FnOnce(Ghost<Tokens>) -> T + Send + 'scope,
84 T: Send + 'scope,
85 {
86 self.inner.spawn(|| f(Tokens::new()))
87 }
88}
89
90#[requires(forall<s> inv(s) ==> f.precondition((s,)))]
92#[ensures(exists<s> inv(s) && f.postcondition_once((s,),result))]
93#[trusted]
94pub fn scope<'env, F, T>(f: F) -> T
95where
96 F: for<'scope> FnOnce(&mut Scope<'scope, 'env>) -> T,
97{
98 ::std::thread::scope(|s| f(&mut Scope { inner: s }))
99}