3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00

fix race condition, exception handling/throwing

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-11-05 18:24:15 -08:00
parent 9a4fb4ff76
commit 5813e22032

View file

@ -108,11 +108,17 @@ class parallel_tactic : public tactic {
solver_state* get_task() { solver_state* get_task() {
while (!m_shutdown) { while (!m_shutdown) {
solver_state* st = try_get_task();
if (st) return st;
inc_wait(); inc_wait();
std::unique_lock<std::mutex> lock(m_mutex); solver_state* st = try_get_task();
m_cond.wait(lock, [this] { --m_num_waiters; return true; }); if (st) {
dec_wait();
return st;
}
{
std::unique_lock<std::mutex> lock(m_mutex);
m_cond.wait(lock);
}
dec_wait();
} }
return nullptr; return nullptr;
} }
@ -128,6 +134,7 @@ class parallel_tactic : public tactic {
void reset() { void reset() {
for (auto* t : m_tasks) dealloc(t); for (auto* t : m_tasks) dealloc(t);
for (auto* t : m_active) dealloc(t);
m_tasks.reset(); m_tasks.reset();
m_active.reset(); m_active.reset();
} }
@ -322,6 +329,8 @@ private:
bool m_has_undef; bool m_has_undef;
bool m_allsat; bool m_allsat;
unsigned m_num_unsat; unsigned m_num_unsat;
int m_exn_code;
std::string m_exn_msg;
void init() { void init() {
m_num_threads = omp_get_num_procs(); // TBD adjust by possible threads used inside each solver. m_num_threads = omp_get_num_procs(); // TBD adjust by possible threads used inside each solver.
@ -329,6 +338,7 @@ private:
m_has_undef = false; m_has_undef = false;
m_allsat = false; m_allsat = false;
m_num_unsat = 0; m_num_unsat = 0;
m_exn_code = 0;
} }
void close_branch(solver_state& s, lbool status) { void close_branch(solver_state& s, lbool status) {
@ -476,9 +486,17 @@ private:
dealloc(st); dealloc(st);
} }
} }
catch (z3_exception& ex) { catch (z3_exception& ex) {
std::cout << ex.msg() << "\n"; IF_VERBOSE(1, verbose_stream() << ex.msg() << "\n";);
m_queue.shutdown(); m_queue.shutdown();
std::lock_guard<std::mutex> lock(m_mutex);
if (ex.has_error_code()) {
m_exn_code = ex.error_code();
}
else {
m_exn_msg = ex.msg();
m_exn_code = -1;
}
} }
} }
@ -489,20 +507,21 @@ private:
lbool solve(model_ref& mdl) { lbool solve(model_ref& mdl) {
vector<std::thread> threads; vector<std::thread> threads;
for (unsigned i = 0; i < m_num_threads; ++i) { for (unsigned i = 0; i < m_num_threads; ++i)
threads.push_back(std::thread([this]() { run_solver(); })); threads.push_back(std::thread([this]() { run_solver(); }));
} for (std::thread& t : threads)
for (std::thread& t : threads) {
t.join(); t.join();
} m_manager.limit().reset_cancel();
if (m_exn_code == -1)
throw default_exception(m_exn_msg);
if (m_exn_code != 0)
throw z3_error(m_exn_code);
if (!m_models.empty()) { if (!m_models.empty()) {
mdl = m_models.back(); mdl = m_models.back();
m_manager.limit().reset_cancel();
return l_true; return l_true;
} }
if (m_has_undef) if (m_has_undef)
return l_undef; return l_undef;
m_manager.limit().reset_cancel();
return l_false; return l_false;
} }
@ -583,6 +602,9 @@ public:
virtual void collect_statistics(statistics & st) const { virtual void collect_statistics(statistics & st) const {
st.copy(m_stats); st.copy(m_stats);
st.update("par unsat", m_num_unsat);
st.update("par models", m_models.size());
st.update("par progress", m_progress);
} }
virtual void reset_statistics() { virtual void reset_statistics() {
m_stats.reset(); m_stats.reset();