mirror of
https://github.com/Z3Prover/z3
synced 2025-06-18 11:58:31 +00:00
optimizations to api ctx ref counting
This commit is contained in:
parent
eb2ee34dfe
commit
6e5ced0080
3 changed files with 24 additions and 12 deletions
|
@ -51,11 +51,14 @@ namespace api {
|
||||||
}
|
}
|
||||||
|
|
||||||
void context::del_object(api::object* o) {
|
void context::del_object(api::object* o) {
|
||||||
|
#ifndef SINGLE_THREAD
|
||||||
if (m_concurrent_dec_ref) {
|
if (m_concurrent_dec_ref) {
|
||||||
lock_guard lock(m_mux);
|
lock_guard lock(m_mux);
|
||||||
m_objects_to_flush.push_back(o);
|
m_objects_to_flush.push_back(o);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
m_free_object_ids.push_back(o->id());
|
m_free_object_ids.push_back(o->id());
|
||||||
m_allocated_objects.remove(o->id());
|
m_allocated_objects.remove(o->id());
|
||||||
dealloc(o);
|
dealloc(o);
|
||||||
|
@ -63,25 +66,26 @@ namespace api {
|
||||||
}
|
}
|
||||||
|
|
||||||
void context::dec_ref(ast* a) {
|
void context::dec_ref(ast* a) {
|
||||||
|
#ifndef SINGLE_THREAD
|
||||||
if (m_concurrent_dec_ref) {
|
if (m_concurrent_dec_ref) {
|
||||||
lock_guard lock(m_mux);
|
lock_guard lock(m_mux);
|
||||||
m_asts_to_flush.push_back(a);
|
m_asts_to_flush.push_back(a);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
m().dec_ref(a);
|
m().dec_ref(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void context::flush_objects() {
|
void context::flush_objects() {
|
||||||
|
#ifndef SINGLE_THREAD
|
||||||
if (!m_concurrent_dec_ref)
|
if (!m_concurrent_dec_ref)
|
||||||
return;
|
return;
|
||||||
{
|
{
|
||||||
lock_guard lock(m_mux);
|
lock_guard lock(m_mux);
|
||||||
if (m_asts_to_flush.empty() && m_objects_to_flush.empty())
|
if (m_asts_to_flush.empty() && m_objects_to_flush.empty())
|
||||||
return;
|
return;
|
||||||
m_asts_to_flush2.append(m_asts_to_flush);
|
m_asts_to_flush2.swap(m_asts_to_flush);
|
||||||
m_asts_to_flush.reset();
|
m_objects_to_flush2.swap(m_objects_to_flush);
|
||||||
m_objects_to_flush2.append(m_objects_to_flush);
|
|
||||||
m_objects_to_flush.reset();
|
|
||||||
}
|
}
|
||||||
for (ast* a : m_asts_to_flush2)
|
for (ast* a : m_asts_to_flush2)
|
||||||
m().dec_ref(a);
|
m().dec_ref(a);
|
||||||
|
@ -92,7 +96,7 @@ namespace api {
|
||||||
}
|
}
|
||||||
m_objects_to_flush2.reset();
|
m_objects_to_flush2.reset();
|
||||||
m_asts_to_flush2.reset();
|
m_asts_to_flush2.reset();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void default_error_handler(Z3_context ctx, Z3_error_code c) {
|
static void default_error_handler(Z3_context ctx, Z3_error_code c) {
|
||||||
|
|
|
@ -75,6 +75,9 @@ namespace api {
|
||||||
struct add_plugins { add_plugins(ast_manager & m); };
|
struct add_plugins { add_plugins(ast_manager & m); };
|
||||||
ast_context_params m_params;
|
ast_context_params m_params;
|
||||||
bool m_user_ref_count; //!< if true, the user is responsible for managing reference counters.
|
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<ast_manager> m_manager;
|
scoped_ptr<ast_manager> m_manager;
|
||||||
scoped_ptr<cmd_context> m_cmd;
|
scoped_ptr<cmd_context> m_cmd;
|
||||||
add_plugins m_plugins;
|
add_plugins m_plugins;
|
||||||
|
@ -91,9 +94,10 @@ namespace api {
|
||||||
smt_params m_fparams;
|
smt_params m_fparams;
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
|
||||||
bool m_concurrent_dec_ref = false;
|
#ifndef SINGLE_THREAD
|
||||||
ptr_vector<ast> m_asts_to_flush, m_asts_to_flush2;
|
ptr_vector<ast> m_asts_to_flush, m_asts_to_flush2;
|
||||||
ptr_vector<api::object> m_objects_to_flush, m_objects_to_flush2;
|
ptr_vector<api::object> m_objects_to_flush, m_objects_to_flush2;
|
||||||
|
#endif
|
||||||
|
|
||||||
ast_ref_vector m_ast_trail;
|
ast_ref_vector m_ast_trail;
|
||||||
ref<api::object> m_last_obj; //!< reference to the last API object returned by the APIs
|
ref<api::object> 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_code(Z3_error_code err, std::string &&opt_msg);
|
||||||
void set_error_handler(Z3_error_handler h) { m_error_handler = h; }
|
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);
|
unsigned add_object(api::object* o);
|
||||||
void del_object(api::object* o);
|
void del_object(api::object* o);
|
||||||
void dec_ref(ast* a);
|
void dec_ref(ast* a);
|
||||||
|
|
|
@ -19,8 +19,8 @@ Revision History:
|
||||||
|
|
||||||
#include "util/params.h"
|
#include "util/params.h"
|
||||||
#include "util/lbool.h"
|
#include "util/lbool.h"
|
||||||
|
#include "util/mutex.h"
|
||||||
#include "ast/ast.h"
|
#include "ast/ast.h"
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
#define Z3_TRY try {
|
#define Z3_TRY try {
|
||||||
#define Z3_CATCH_CORE(CODE) } catch (z3_exception & ex) { mk_c(c)->handle_exception(ex); CODE }
|
#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<lbool>(b); }
|
||||||
struct Z3_params_ref : public api::object {
|
struct Z3_params_ref : public api::object {
|
||||||
params_ref m_params;
|
params_ref m_params;
|
||||||
Z3_params_ref(api::context& c): api::object(c) {}
|
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<Z3_params_ref *>(p); }
|
inline Z3_params_ref * to_params(Z3_params p) { return reinterpret_cast<Z3_params_ref *>(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 {
|
struct Z3_param_descrs_ref : public api::object {
|
||||||
param_descrs m_descrs;
|
param_descrs m_descrs;
|
||||||
Z3_param_descrs_ref(api::context& c): api::object(c) {}
|
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<Z3_param_descrs_ref *>(p); }
|
inline Z3_param_descrs_ref * to_param_descrs(Z3_param_descrs p) { return reinterpret_cast<Z3_param_descrs_ref *>(p); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue