1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use crateTranslate;
use crate::;
use ;
use Mutex;
/// A [`Send`] and [`Sync`] wrapper for Z3 structures associated with a [`Context`].
///
/// This wrapper
/// takes in a Z3 type (or a user-defined type that uses Z3 types) and translates its contents
/// into a private "singleton" [`Context`]. Since this [`Context`] is unused elsewhere, it is safe
/// to [`Send`] it and its contents to other threads AND to have [`Sync`] accesses across threads.
/// The safety of the [`Send`] impl is upheld by construction, as all data associated with the inner
/// [`Context`] is guaranteed to be moved with it.
/// The safety of the [`Sync`] impl is upheld through an inner [`Mutex`].
///
/// Inner data can only be accessed through [`Synchronized::recover`], which translates the contents
/// for the given [`Context`].
///
/// # Performance
///
/// Initializing this type (usually done through
/// [`PrepareSynchronized::synchronized`](crate::PrepareSynchronized::synchronized))
/// will allocate
/// a new [`Context`] and [`Translate`] the provided `T` into it. This involves a non-zero amount of
/// overhead; if you are creating thousands of [`Synchronized`], you will see a performance impact.
///
/// If you need to move/reference a collection of data between threads, consider putting it in
/// a [`Vec`], which also implements [`PrepareSynchronized`](crate::PrepareSynchronized), and will
/// only create one [`Context`]. You can also implement [`Translate`] on your own types, which
/// will then inherit from a blanket impl of [`PrepareSynchronized`](crate::PrepareSynchronized)
/// for [`Translate`].
///
/// Note that this will only alleviate the overhead of
/// allocating many [`Context`]s. There is still some unavoidable overhead:
/// * A [`Context`] must be allocated.
/// * Your `T` must be [`Translate`]'d into the [`Context`].
/// * The data inside [`Synchronized`] must be [`Translate`]'d out to be used.
///
/// Z3 translation scales in proportion to the complexity of the statement; if you use this with
/// some very complex set of formulas, expect it to take longer.
///
/// # See also:
///
/// - [`PrepareSendable`](crate::PrepareSynchronized)
/// - [`Translate`]
);
/// Cloning a [`Synchronized`] will create a new [`Context`] and translate the data into it.
/// This allows a handle to be easily sent to multiple threads without violating context
/// memory safety, at the expense of some extra cloning.
/// The [`Context`] inside is only used with the [`Translate`] inside, so
/// it is sound to [`Send`]
unsafe
/// The only method access to the [`Ast`](crate::ast::Ast) or [`Context`] is guarded
/// by a [`Mutex`], so it is sound to [`Sync`]
unsafe