diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index aa96998b3..a16341955 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -51,11 +51,14 @@ namespace api { } void context::del_object(api::object* o) { +#ifndef SINGLE_THREAD if (m_concurrent_dec_ref) { lock_guard lock(m_mux); m_objects_to_flush.push_back(o); } - else { + else +#endif + { m_free_object_ids.push_back(o->id()); m_allocated_objects.remove(o->id()); dealloc(o); @@ -63,25 +66,26 @@ namespace api { } void context::dec_ref(ast* a) { +#ifndef SINGLE_THREAD if (m_concurrent_dec_ref) { lock_guard lock(m_mux); m_asts_to_flush.push_back(a); } - else + else +#endif m().dec_ref(a); } void context::flush_objects() { +#ifndef SINGLE_THREAD if (!m_concurrent_dec_ref) return; { lock_guard lock(m_mux); if (m_asts_to_flush.empty() && m_objects_to_flush.empty()) return; - m_asts_to_flush2.append(m_asts_to_flush); - m_asts_to_flush.reset(); - m_objects_to_flush2.append(m_objects_to_flush); - m_objects_to_flush.reset(); + m_asts_to_flush2.swap(m_asts_to_flush); + m_objects_to_flush2.swap(m_objects_to_flush); } for (ast* a : m_asts_to_flush2) m().dec_ref(a); @@ -92,7 +96,7 @@ namespace api { } m_objects_to_flush2.reset(); m_asts_to_flush2.reset(); - +#endif } static void default_error_handler(Z3_context ctx, Z3_error_code c) { diff --git a/src/api/api_context.h b/src/api/api_context.h index cf8c6ac87..182958b1e 100644 --- a/src/api/api_context.h +++ b/src/api/api_context.h @@ -75,6 +75,9 @@ namespace api { struct add_plugins { add_plugins(ast_manager & m); }; ast_context_params m_params; bool m_user_ref_count; //!< if true, the user is responsible for managing reference counters. +#ifndef SINGLE_THREAD + bool m_concurrent_dec_ref = false; +#endif scoped_ptr m_manager; scoped_ptr m_cmd; add_plugins m_plugins; @@ -91,9 +94,10 @@ namespace api { smt_params m_fparams; // ------------------------------- - bool m_concurrent_dec_ref = false; +#ifndef SINGLE_THREAD ptr_vector m_asts_to_flush, m_asts_to_flush2; ptr_vector m_objects_to_flush, m_objects_to_flush2; +#endif ast_ref_vector m_ast_trail; ref m_last_obj; //!< reference to the last API object returned by the APIs @@ -173,7 +177,13 @@ namespace api { void set_error_code(Z3_error_code err, std::string &&opt_msg); void set_error_handler(Z3_error_handler h) { m_error_handler = h; } - void enable_concurrent_dec_ref() { m_concurrent_dec_ref = true; } + void enable_concurrent_dec_ref() { +#ifdef SINGLE_THREAD + set_error_code(Z3_EXCEPTION, "Can't use concurrent features with a single-thread build"); +#else + m_concurrent_dec_ref = true; +#endif + } unsigned add_object(api::object* o); void del_object(api::object* o); void dec_ref(ast* a); diff --git a/src/api/api_util.h b/src/api/api_util.h index 474d3410e..80f4f5ec7 100644 --- a/src/api/api_util.h +++ b/src/api/api_util.h @@ -19,8 +19,8 @@ Revision History: #include "util/params.h" #include "util/lbool.h" +#include "util/mutex.h" #include "ast/ast.h" -#include #define Z3_TRY try { #define Z3_CATCH_CORE(CODE) } catch (z3_exception & ex) { mk_c(c)->handle_exception(ex); CODE } @@ -88,7 +88,6 @@ inline lbool to_lbool(Z3_lbool b) { return static_cast(b); } struct Z3_params_ref : public api::object { params_ref m_params; Z3_params_ref(api::context& c): api::object(c) {} - ~Z3_params_ref() override {} }; inline Z3_params_ref * to_params(Z3_params p) { return reinterpret_cast(p); } @@ -98,7 +97,6 @@ inline params_ref& to_param_ref(Z3_params p) { return p == nullptr ? const_cast< struct Z3_param_descrs_ref : public api::object { param_descrs m_descrs; Z3_param_descrs_ref(api::context& c): api::object(c) {} - ~Z3_param_descrs_ref() override {} }; inline Z3_param_descrs_ref * to_param_descrs(Z3_param_descrs p) { return reinterpret_cast(p); }