Z3 Context Thread Safety Question #7762
Replies: 1 comment 1 reply
-
|
It isn't thread safe because z3_translate and related increment and decrement reference counts on ast nodes from the source context. I think you want to weigh the overhead of the broker against overhead of solving. Solving should be several orders of magnitude higher time and space overhead than replicating the ast nodes from the input. If ast node overhead is higher, then I am not sure it is useful to use threads in the first place. I use a broker in the local search solver to allow two threads to communicate information without being blocked on each other. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This is sort of a follow-up to #4762. I've been working on the Rust z3 bindings and have been playing with a structured way to allow usages of the Rust API in multi-threaded scenarios (see prove-rs/z3.rs#404). From this investigation, I have a question about the thread-safety of the z3 context.
Background (feel free to skip)
My multi-threading strategy is this:
Contexts can never be moved to other threads or referenced by other threadsAsts,Solvers,Models, etc, may also never be moved or referenced across threads (I'm going to sayAstfor the rest of this, but I mean any of these types that isn't aContext).Asts may be wrapped in a specialSendableHandlestructure:translates theAstfor a newContext, owned by theSendableHandle. No other code is able to see thisContext.translateis done, thisContextis kept around for the lifetime of theSendableHandle, and no further declarations are made inside it.SendableHandlecan be moved to another thread and then have its contents unwrapped and translated into anAstassociated with aContextowned by the receiving thread through a call torecover(&ctx).This paradigm introduces some overhead, as
Asts must be translated twice, and there's an extraContextconstruction/destruction every time something needs to move across threads, but it ensures that noAstis ever accessed from a different thread than theContextit is associated with, without relying on rust-side atomics or mutexes.So, my question comes because when I originally thought of this, I was thinking that the soundness of this approach required that
SendableHandlecould be moved to a thread but never referenced across threads. As an experiment I tried loosening these requirements and allowing references across threads. Much to my surprise, this worked.TLDR
So, my question is about the safety of the following pattern of interactions with the Z3 context. If I:
ContextAst/Solver/etc in itContextagain outside of using it as the source ofZ3_translate/Z3_solver_translate/etc calls.Is it then safe to access the
Contextfrom other threads without synchronization?Beta Was this translation helpful? Give feedback.
All reactions