mirror of
https://github.com/Z3Prover/z3
synced 2025-08-29 22:40:08 +00:00
synchronizing with main repository
This commit is contained in:
commit
ec76efedbe
386 changed files with 10027 additions and 8346 deletions
|
@ -56,7 +56,6 @@ z3_add_component(util
|
|||
symbol.cpp
|
||||
timeit.cpp
|
||||
timeout.cpp
|
||||
timer.cpp
|
||||
trace.cpp
|
||||
util.cpp
|
||||
warning.cpp
|
||||
|
|
|
@ -154,7 +154,7 @@ public:
|
|||
return static_cast<unsigned>(reinterpret_cast<size_t *>(m_data)[SIZE_IDX]);
|
||||
}
|
||||
|
||||
bool empty() const { return m_data == 0; }
|
||||
bool empty() const { return m_data == nullptr; }
|
||||
|
||||
T & operator[](unsigned idx) {
|
||||
SASSERT(idx < size());
|
||||
|
|
|
@ -32,6 +32,7 @@ Revision History:
|
|||
#include "util/debug.h"
|
||||
#include "util/trace.h"
|
||||
#include "util/tptr.h"
|
||||
#include "util/util.h"
|
||||
#ifdef Z3DEBUG
|
||||
#include "util/hashtable.h"
|
||||
#endif
|
||||
|
|
|
@ -56,20 +56,20 @@ void finalize_debug() {
|
|||
|
||||
void enable_debug(const char * tag) {
|
||||
init_debug_table();
|
||||
g_enabled_debug_tags->insert(const_cast<char *>(tag));
|
||||
g_enabled_debug_tags->insert(tag);
|
||||
}
|
||||
|
||||
void disable_debug(const char * tag) {
|
||||
init_debug_table();
|
||||
g_enabled_debug_tags->erase(const_cast<char *>(tag));
|
||||
g_enabled_debug_tags->erase(tag);
|
||||
}
|
||||
|
||||
bool is_debug_enabled(const char * tag) {
|
||||
init_debug_table();
|
||||
return g_enabled_debug_tags->contains(const_cast<char *>(tag));
|
||||
return g_enabled_debug_tags->contains(tag);
|
||||
}
|
||||
|
||||
#ifndef _WINDOWS
|
||||
#if !defined(_WINDOWS) && !defined(NO_Z3_DEBUGGER)
|
||||
void invoke_gdb() {
|
||||
char buffer[1024];
|
||||
int * x = nullptr;
|
||||
|
|
|
@ -44,6 +44,17 @@ bool assertions_enabled();
|
|||
#define DEBUG_CODE(CODE) ((void) 0)
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#if !TARGET_OS_OSX
|
||||
#define NO_Z3_DEBUGGER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#define NO_Z3_DEBUGGER
|
||||
#endif
|
||||
|
||||
#ifdef NO_Z3_DEBUGGER
|
||||
#define INVOKE_DEBUGGER() exit(ERR_INTERNAL_FATAL)
|
||||
#else
|
||||
|
|
|
@ -51,6 +51,10 @@ class ema {
|
|||
m_beta *= 0.5;
|
||||
if (m_beta < m_alpha) m_beta = m_alpha;
|
||||
}
|
||||
|
||||
void set(double x) {
|
||||
m_value = x;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,7 +61,7 @@ hwf_manager::hwf_manager() :
|
|||
m_mpz_manager(m_mpq_manager)
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
#if defined(_AMD64_) || defined(_M_IA64)
|
||||
#if defined(_WIN64)
|
||||
// Precision control is not supported on x64.
|
||||
// See: http://msdn.microsoft.com/en-us/library/e9b52ceh(VS.110).aspx
|
||||
// CMW: I think this is okay though, the compiler will chose the right instructions
|
||||
|
@ -303,7 +303,7 @@ void hwf_manager::round_to_integral(mpf_rounding_mode rm, hwf const & x, hwf & o
|
|||
// CMW: modf is not the right function here.
|
||||
// modf(x.value, &o.value);
|
||||
|
||||
// According to the Intel Architecture manual, the x87-instrunction FRNDINT is the
|
||||
// According to the Intel Architecture manual, the x87-instruction FRNDINT is the
|
||||
// same in 32-bit and 64-bit mode. The _mm_round_* intrinsics are SSE4 extensions.
|
||||
#ifdef _WINDOWS
|
||||
#if defined(USE_INTRINSICS) && \
|
||||
|
@ -557,7 +557,7 @@ void hwf_manager::mk_ninf(hwf & o) {
|
|||
}
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#if defined(_AMD64_) || defined(_M_IA64)
|
||||
#if defined(_WIN64)
|
||||
#ifdef USE_INTRINSICS
|
||||
#define SETRM(RM) _MM_SET_ROUNDING_MODE(RM)
|
||||
#else
|
||||
|
|
|
@ -183,7 +183,7 @@ template <typename T, typename X> unsigned core_solver_pretty_printer<T, X>:: ge
|
|||
}
|
||||
if (!m_core_solver.use_tableau()) {
|
||||
w = std::max(w, (unsigned)T_to_string(m_exact_column_norms[column]).size());
|
||||
if (m_core_solver.m_column_norms.size() > 0)
|
||||
if (!m_core_solver.m_column_norms.empty())
|
||||
w = std::max(w, (unsigned)T_to_string(m_core_solver.m_column_norms[column]).size());
|
||||
}
|
||||
return w;
|
||||
|
@ -339,7 +339,7 @@ template <typename T, typename X> void core_solver_pretty_printer<T, X>::print()
|
|||
print_lows();
|
||||
print_upps();
|
||||
print_exact_norms();
|
||||
if (m_core_solver.m_column_norms.size() > 0)
|
||||
if (!m_core_solver.m_column_norms.empty())
|
||||
print_approx_norms();
|
||||
m_out << std::endl;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ void eta_matrix<T, X>::apply_from_right(vector<T> & w) {
|
|||
}
|
||||
template <typename T, typename X>
|
||||
void eta_matrix<T, X>::apply_from_right(indexed_vector<T> & w) {
|
||||
if (w.m_index.size() == 0)
|
||||
if (w.m_index.empty())
|
||||
return;
|
||||
#ifdef Z3DEBUG
|
||||
// vector<T> wcopy(w.m_data);
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
|
||||
unsigned row_count() const { return m_data.size(); }
|
||||
unsigned column_count() const { return m_data.size() > 0? m_data[0].size() : 0; }
|
||||
unsigned column_count() const { return !m_data.empty()? m_data[0].size() : 0; }
|
||||
|
||||
class ref_row {
|
||||
general_matrix& m_matrix;
|
||||
|
|
|
@ -37,7 +37,7 @@ struct lar_term {
|
|||
}
|
||||
|
||||
bool is_empty() const {
|
||||
return m_coeffs.size() == 0; // && is_zero(m_v);
|
||||
return m_coeffs.empty(); // && is_zero(m_v);
|
||||
}
|
||||
|
||||
unsigned size() const { return static_cast<unsigned>(m_coeffs.size()); }
|
||||
|
|
|
@ -665,7 +665,7 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::ratio_test() {
|
|||
m_flipped_boxed.clear();
|
||||
int initial_delta_sign = m_delta >= numeric_traits<T>::zero()? 1: -1;
|
||||
do {
|
||||
if (m_breakpoint_set.size() == 0) {
|
||||
if (m_breakpoint_set.empty()) {
|
||||
set_status_to_tentative_dual_unbounded_or_dual_unbounded();
|
||||
return false;
|
||||
}
|
||||
|
@ -697,7 +697,7 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::update_d_and_x
|
|||
this->m_d[j] -= m_theta_D * this->m_pivot_row[j];
|
||||
}
|
||||
this->m_d[m_p] = - m_theta_D;
|
||||
if (m_flipped_boxed.size() > 0) {
|
||||
if (!m_flipped_boxed.empty()) {
|
||||
process_flipped();
|
||||
update_xb_after_bound_flips();
|
||||
}
|
||||
|
|
|
@ -504,7 +504,7 @@ lp_primal_core_solver<T, X>::get_bound_on_variable_and_update_leaving_precisely(
|
|||
X tt = - (this->m_lower_bounds[j] - this->m_x[j]) / m;
|
||||
if (numeric_traits<X>::is_neg(tt))
|
||||
tt = zero_of_type<X>();
|
||||
if (leavings.size() == 0 || tt < t || (tt == t && m > abs_of_d_of_leaving)) {
|
||||
if (leavings.empty() || tt < t || (tt == t && m > abs_of_d_of_leaving)) {
|
||||
t = tt;
|
||||
abs_of_d_of_leaving = m;
|
||||
leavings.clear();
|
||||
|
@ -524,7 +524,7 @@ lp_primal_core_solver<T, X>::get_bound_on_variable_and_update_leaving_precisely(
|
|||
X tt = (this->m_upper_bounds[j] - this->m_x[j]) / m;
|
||||
if (numeric_traits<X>::is_neg(tt))
|
||||
tt = zero_of_type<X>();
|
||||
if (leavings.size() == 0 || tt < t || (tt == t && - m > abs_of_d_of_leaving)) {
|
||||
if (leavings.empty() || tt < t || (tt == t && - m > abs_of_d_of_leaving)) {
|
||||
t = tt;
|
||||
abs_of_d_of_leaving = - m;
|
||||
leavings.clear();
|
||||
|
|
|
@ -103,7 +103,7 @@ template <typename T, typename X> void lp_solver<T, X>::flip_costs() {
|
|||
|
||||
template <typename T, typename X> bool lp_solver<T, X>::problem_is_empty() {
|
||||
for (auto & c : m_A_values)
|
||||
if (c.second.size())
|
||||
if (!c.second.empty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ template <typename T, typename X> unsigned lp_solver<T, X>::try_to_remove_some_r
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
if (rows_to_delete.size() > 0) {
|
||||
if (!rows_to_delete.empty()) {
|
||||
for (unsigned k : rows_to_delete) {
|
||||
m_A_values.erase(k);
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ void print_matrix_with_widths(vector<vector<std::string>> & A, vector<unsigned>
|
|||
void print_string_matrix(vector<vector<std::string>> & A, std::ostream & out, unsigned blanks_in_front) {
|
||||
vector<unsigned> widths;
|
||||
|
||||
if (A.size() > 0)
|
||||
if (!A.empty())
|
||||
for (unsigned j = 0; j < A[0].size(); j++) {
|
||||
widths.push_back(get_width_of_column(j, A));
|
||||
}
|
||||
|
|
|
@ -220,7 +220,7 @@ class mps_reader {
|
|||
*m_message_stream << "cannot read from file" << std::endl;
|
||||
}
|
||||
m_line_number++;
|
||||
if (m_line.size() != 0 && m_line[0] != '*' && !all_white_space())
|
||||
if (!m_line.empty() && m_line[0] != '*' && !all_white_space())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -514,7 +514,7 @@ class mps_reader {
|
|||
lp_assert(m_line.size() >= 14);
|
||||
vector<std::string> bound_string = split_and_trim(m_line.substr(name_offset, m_line.size()));
|
||||
|
||||
if (bound_string.size() == 0) {
|
||||
if (bound_string.empty()) {
|
||||
set_m_ok_to_false();
|
||||
(*m_message_stream) << "error at line " << m_line_number << std::endl;
|
||||
throw m_line;
|
||||
|
|
|
@ -248,7 +248,7 @@ void square_sparse_matrix<T, X>::put_max_index_to_0(vector<indexed_value<T>> & r
|
|||
|
||||
template <typename T, typename X>
|
||||
void square_sparse_matrix<T, X>::set_max_in_row(vector<indexed_value<T>> & row_vals) {
|
||||
if (row_vals.size() == 0)
|
||||
if (row_vals.empty())
|
||||
return;
|
||||
T max_val = abs(row_vals[0].m_value);
|
||||
unsigned max_index = 0;
|
||||
|
@ -386,7 +386,7 @@ bool square_sparse_matrix<T, X>::set_row_from_work_vector_and_clean_work_vector_
|
|||
}
|
||||
work_vec.m_index.clear();
|
||||
auto & row_vals = m_rows[i0];
|
||||
if (row_vals.size() == 0) {
|
||||
if (row_vals.empty()) {
|
||||
return false;
|
||||
}
|
||||
set_max_in_row(row_vals); // it helps to find larger pivots
|
||||
|
|
|
@ -20,7 +20,7 @@ Revision History:
|
|||
#ifndef MACHINE_H_
|
||||
#define MACHINE_H_
|
||||
|
||||
#ifdef _AMD64_
|
||||
#if defined(__LP64__) || defined(_WIN64)
|
||||
#define PTR_ALIGNMENT 3
|
||||
#else
|
||||
#define PTR_ALIGNMENT 2
|
||||
|
|
|
@ -18,7 +18,7 @@ Copyright (c) 2015 Microsoft Corporation
|
|||
// ADD_INITIALIZER('rational::initialize();')
|
||||
// ADD_FINALIZER('rational::finalize();')
|
||||
// Thus, any executable or shared object (DLL) that depends on rational.h
|
||||
// will have an automalically generated file mem_initializer.cpp containing
|
||||
// will have an automatically generated file mem_initializer.cpp containing
|
||||
// mem_initialize()
|
||||
// mem_finalize()
|
||||
// and these functions will include the statements:
|
||||
|
@ -242,13 +242,13 @@ void * memory::allocate(char const* file, int line, char const* obj, size_t s) {
|
|||
#define SYNCH_THRESHOLD 100000
|
||||
|
||||
#ifdef _WINDOWS
|
||||
// Actually this is VS specific instead of Windows specific.
|
||||
// This is VS2013 specific instead of Windows specific.
|
||||
// It can go away with VS2017 builds
|
||||
__declspec(thread) long long g_memory_thread_alloc_size = 0;
|
||||
__declspec(thread) long long g_memory_thread_alloc_count = 0;
|
||||
#else
|
||||
// GCC style
|
||||
__thread long long g_memory_thread_alloc_size = 0;
|
||||
__thread long long g_memory_thread_alloc_count = 0;
|
||||
thread_local long long g_memory_thread_alloc_size = 0;
|
||||
thread_local long long g_memory_thread_alloc_count = 0;
|
||||
#endif
|
||||
|
||||
static void synchronize_counters(bool allocating) {
|
||||
|
|
|
@ -381,7 +381,7 @@ char * mpn_manager::to_string(mpn_digit const * a, size_t const lng, char * buf,
|
|||
div_1(t_numer, t_denom[0], &temp[0]);
|
||||
div_unnormalize(t_numer, t_denom, d, &rem);
|
||||
buf[j++] = '0' + rem;
|
||||
while (temp.size() > 0 && temp.back() == 0)
|
||||
while (!temp.empty() && temp.back() == 0)
|
||||
temp.pop_back();
|
||||
}
|
||||
buf[j] = 0;
|
||||
|
|
|
@ -37,31 +37,31 @@ public:
|
|||
mpn_manager();
|
||||
~mpn_manager();
|
||||
|
||||
int compare(mpn_digit const * a, size_t const lnga,
|
||||
mpn_digit const * b, size_t const lngb) const;
|
||||
int compare(mpn_digit const * a, size_t lnga,
|
||||
mpn_digit const * b, size_t lngb) const;
|
||||
|
||||
bool add(mpn_digit const * a, size_t const lnga,
|
||||
mpn_digit const * b, size_t const lngb,
|
||||
mpn_digit *c, size_t const lngc_alloc,
|
||||
bool add(mpn_digit const * a, size_t lnga,
|
||||
mpn_digit const * b, size_t lngb,
|
||||
mpn_digit *c, size_t lngc_alloc,
|
||||
size_t * plngc) const;
|
||||
|
||||
bool sub(mpn_digit const * a, size_t const lnga,
|
||||
mpn_digit const * b, size_t const lngb,
|
||||
bool sub(mpn_digit const * a, size_t lnga,
|
||||
mpn_digit const * b, size_t lngb,
|
||||
mpn_digit * c, mpn_digit * pborrow) const;
|
||||
|
||||
bool mul(mpn_digit const * a, size_t const lnga,
|
||||
mpn_digit const * b, size_t const lngb,
|
||||
bool mul(mpn_digit const * a, size_t lnga,
|
||||
mpn_digit const * b, size_t lngb,
|
||||
mpn_digit * c) const;
|
||||
|
||||
bool div(mpn_digit const * numer, size_t const lnum,
|
||||
mpn_digit const * denom, size_t const lden,
|
||||
bool div(mpn_digit const * numer, size_t lnum,
|
||||
mpn_digit const * denom, size_t lden,
|
||||
mpn_digit * quot,
|
||||
mpn_digit * rem);
|
||||
|
||||
char * to_string(mpn_digit const * a, size_t const lng,
|
||||
char * buf, size_t const lbuf) const;
|
||||
char * to_string(mpn_digit const * a, size_t lng,
|
||||
char * buf, size_t lbuf) const;
|
||||
private:
|
||||
#ifdef _AMD64_
|
||||
#if defined(__LP64__) || defined(_WIN64)
|
||||
class mpn_sbuffer : public sbuffer<mpn_digit> {
|
||||
public:
|
||||
mpn_sbuffer() : sbuffer<mpn_digit>() {}
|
||||
|
@ -88,29 +88,29 @@ private:
|
|||
|
||||
static const mpn_digit zero;
|
||||
mpn_sbuffer u, v, t_ms, t_ab;
|
||||
void display_raw(std::ostream & out, mpn_digit const * a, size_t const lng) const;
|
||||
void display_raw(std::ostream & out, mpn_digit const * a, size_t lng) const;
|
||||
|
||||
size_t div_normalize(mpn_digit const * numer, size_t const lnum,
|
||||
mpn_digit const * denom, size_t const lden,
|
||||
size_t div_normalize(mpn_digit const * numer, size_t lnum,
|
||||
mpn_digit const * denom, size_t lden,
|
||||
mpn_sbuffer & n_numer,
|
||||
mpn_sbuffer & n_denom) const;
|
||||
|
||||
void div_unnormalize(mpn_sbuffer & numer, mpn_sbuffer & denom,
|
||||
size_t const d, mpn_digit * rem) const;
|
||||
size_t d, mpn_digit * rem) const;
|
||||
|
||||
bool div_1(mpn_sbuffer & numer, mpn_digit const denom,
|
||||
bool div_1(mpn_sbuffer & numer, mpn_digit denom,
|
||||
mpn_digit * quot) const;
|
||||
|
||||
bool div_n(mpn_sbuffer & numer, mpn_sbuffer const & denom,
|
||||
mpn_digit * quot, mpn_digit * rem,
|
||||
mpn_sbuffer & ms, mpn_sbuffer & ab) const;
|
||||
|
||||
void trace(mpn_digit const * a, size_t const lnga,
|
||||
mpn_digit const * b, size_t const lngb,
|
||||
void trace(mpn_digit const * a, size_t lnga,
|
||||
mpn_digit const * b, size_t lngb,
|
||||
const char * op) const;
|
||||
|
||||
void trace(mpn_digit const * a, size_t const lnga) const;
|
||||
void trace_nl(mpn_digit const * a, size_t const lnga) const;
|
||||
void trace(mpn_digit const * a, size_t lnga) const;
|
||||
void trace_nl(mpn_digit const * a, size_t lnga) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,7 +30,6 @@ Revision History:
|
|||
#else
|
||||
#error No multi-precision library selected.
|
||||
#endif
|
||||
#include <immintrin.h>
|
||||
|
||||
// Available GCD algorithms
|
||||
// #define EUCLID_GCD
|
||||
|
@ -46,13 +45,18 @@ Revision History:
|
|||
#define LEHMER_GCD
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
// This is needed for _tzcnt_u32 and friends.
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define _trailing_zeros32(X) __builtin_ctz(X)
|
||||
#else
|
||||
#define _trailing_zeros32(X) _tzcnt_u32(X)
|
||||
#endif
|
||||
|
||||
#if defined(_AMD64_)
|
||||
#if defined(__LP64__) || defined(_WIN64)
|
||||
#if defined(__GNUC__)
|
||||
#define _trailing_zeros64(X) __builtin_ctzll(X)
|
||||
#else
|
||||
|
|
|
@ -94,10 +94,8 @@ public:
|
|||
|
||||
obj_ref & operator=(obj_ref && n) {
|
||||
SASSERT(&m_manager == &n.m_manager);
|
||||
if (this != &n) {
|
||||
std::swap(m_obj, n.m_obj);
|
||||
n.reset();
|
||||
}
|
||||
std::swap(m_obj, n.m_obj);
|
||||
n.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -298,9 +298,14 @@ void insert_produce_proofs(param_descrs & r) {
|
|||
}
|
||||
|
||||
void insert_timeout(param_descrs & r) {
|
||||
r.insert("timeout", CPK_UINT, "(default: infty) timeout in milliseconds.");
|
||||
r.insert("timeout", CPK_UINT, "(default: infty) timeout in milliseconds.", "4294967295");
|
||||
}
|
||||
|
||||
void insert_rlimit(param_descrs & r) {
|
||||
r.insert("rlimit", CPK_UINT, "default resource limit used for solvers. Unrestricted when set to 0.", "0");
|
||||
}
|
||||
|
||||
|
||||
class params {
|
||||
friend class params_ref;
|
||||
struct value {
|
||||
|
|
|
@ -139,5 +139,6 @@ void insert_max_steps(param_descrs & r);
|
|||
void insert_produce_models(param_descrs & r);
|
||||
void insert_produce_proofs(param_descrs & r);
|
||||
void insert_timeout(param_descrs & r);
|
||||
void insert_rlimit(param_descrs & r);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -58,6 +58,12 @@ public:
|
|||
inc_ref(n);
|
||||
m_buffer.push_back(n);
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
void push_back(obj_ref<T,M> && n) {
|
||||
m_buffer.push_back(n.get());
|
||||
n.steal();
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
SASSERT(!m_buffer.empty());
|
||||
|
|
|
@ -99,8 +99,8 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <typename W, typename M>
|
||||
ref_vector_core& push_back(obj_ref<W,M> && n) {
|
||||
template <typename M>
|
||||
ref_vector_core& push_back(obj_ref<T,M> && n) {
|
||||
m_nodes.push_back(n.get());
|
||||
n.steal();
|
||||
return *this;
|
||||
|
@ -306,6 +306,18 @@ public:
|
|||
// prevent abuse:
|
||||
ref_vector & operator=(ref_vector const & other) = delete;
|
||||
|
||||
bool operator==(ref_vector const& other) const {
|
||||
if (other.size() != this->size()) return false;
|
||||
for (unsigned i = this->size(); i-- > 0; ) {
|
||||
if (other[i] != (*this)[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(ref_vector const& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool forall(std::function<bool(T*)>& predicate) const {
|
||||
for (T* t : *this)
|
||||
if (!predicate(t))
|
||||
|
|
|
@ -16,240 +16,43 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifdef _CYGWIN
|
||||
// Hack to make CreateTimerQueueTimer available on cygwin
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
|
||||
#include "util/z3_exception.h"
|
||||
#include "util/z3_omp.h"
|
||||
#if defined(_WINDOWS) || defined(_CYGWIN)
|
||||
// Windows
|
||||
#include<windows.h>
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
// macOS
|
||||
#include<mach/mach.h>
|
||||
#include<mach/clock.h>
|
||||
#include<sys/time.h>
|
||||
#include<sys/errno.h>
|
||||
#include<pthread.h>
|
||||
#elif defined(_LINUX_) || defined(_FREEBSD_) || defined(_NetBSD_)
|
||||
// Linux & FreeBSD & NetBSD
|
||||
#include<errno.h>
|
||||
#include<pthread.h>
|
||||
#include<sched.h>
|
||||
#include<time.h>
|
||||
// ---------
|
||||
#else
|
||||
// Other platforms
|
||||
#endif
|
||||
|
||||
#include "util/scoped_timer.h"
|
||||
#ifdef _CYGWIN
|
||||
#undef min
|
||||
#undef max
|
||||
#endif
|
||||
#include "util/util.h"
|
||||
#include<climits>
|
||||
#include "util/z3_omp.h"
|
||||
#include <chrono>
|
||||
#include <climits>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
|
||||
struct scoped_timer::imp {
|
||||
event_handler * m_eh;
|
||||
#if defined(_WINDOWS) || defined(_CYGWIN)
|
||||
HANDLE m_timer;
|
||||
bool m_first;
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
// macOS
|
||||
pthread_t m_thread_id;
|
||||
pthread_attr_t m_attributes;
|
||||
unsigned m_interval;
|
||||
pthread_mutex_t m_mutex;
|
||||
pthread_cond_t m_condition_var;
|
||||
struct timespec m_end_time;
|
||||
#elif defined(_LINUX_) || defined(_FREEBSD_) || defined(_NETBSD_)
|
||||
// Linux & FreeBSD & NetBSD
|
||||
pthread_t m_thread_id;
|
||||
pthread_mutex_t m_mutex;
|
||||
pthread_cond_t m_cond;
|
||||
unsigned m_ms;
|
||||
bool m_initialized;
|
||||
bool m_signal_sent;
|
||||
#else
|
||||
// Other
|
||||
#endif
|
||||
private:
|
||||
std::thread m_thread;
|
||||
std::timed_mutex m_mutex;
|
||||
|
||||
#if defined(_WINDOWS) || defined(_CYGWIN)
|
||||
static void CALLBACK abort_proc(PVOID param, BOOLEAN timer_or_wait_fired) {
|
||||
imp * obj = static_cast<imp*>(param);
|
||||
if (obj->m_first) {
|
||||
obj->m_first = false;
|
||||
}
|
||||
else {
|
||||
obj->m_eh->operator()(TIMEOUT_EH_CALLER);
|
||||
static void thread_func(unsigned ms, event_handler * eh, std::timed_mutex * mutex) {
|
||||
auto end = std::chrono::steady_clock::now() + std::chrono::milliseconds(ms);
|
||||
|
||||
while (!mutex->try_lock_until(end)) {
|
||||
if (std::chrono::steady_clock::now() >= end) {
|
||||
eh->operator()(TIMEOUT_EH_CALLER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mutex->unlock();
|
||||
}
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
// macOS
|
||||
static void * thread_func(void * arg) {
|
||||
scoped_timer::imp * st = static_cast<scoped_timer::imp*>(arg);
|
||||
|
||||
pthread_mutex_lock(&st->m_mutex);
|
||||
|
||||
int e = pthread_cond_timedwait(&st->m_condition_var, &st->m_mutex, &st->m_end_time);
|
||||
if (e != 0 && e != ETIMEDOUT)
|
||||
throw default_exception("failed to start timed wait");
|
||||
st->m_eh->operator()(TIMEOUT_EH_CALLER);
|
||||
|
||||
pthread_mutex_unlock(&st->m_mutex);
|
||||
|
||||
return st;
|
||||
}
|
||||
#elif defined(_LINUX_) || defined(_FREEBSD_) || defined(_NETBSD_)
|
||||
static void* thread_func(void *arg) {
|
||||
scoped_timer::imp *st = static_cast<scoped_timer::imp*>(arg);
|
||||
|
||||
struct timespec end_time;
|
||||
clock_gettime(CLOCK_REALTIME, &end_time);
|
||||
end_time.tv_sec += st->m_ms / 1000u;
|
||||
end_time.tv_nsec += (st->m_ms % 1000u) * 1000000ull;
|
||||
// check for overflow
|
||||
if (end_time.tv_nsec >= 1000000000) {
|
||||
++end_time.tv_sec;
|
||||
end_time.tv_nsec -= 1000000000;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&st->m_mutex);
|
||||
st->m_initialized = true;
|
||||
int e = 0;
|
||||
// `pthread_cond_timedwait()` may spuriously wake even if the signal
|
||||
// was not sent so we loop until a timeout occurs or the signal was
|
||||
// **really** sent.
|
||||
while (!(e == 0 && st->m_signal_sent)) {
|
||||
e = pthread_cond_timedwait(&st->m_cond, &st->m_mutex, &end_time);
|
||||
ENSURE(e == 0 || e == ETIMEDOUT);
|
||||
if (e == ETIMEDOUT)
|
||||
break;
|
||||
}
|
||||
pthread_mutex_unlock(&st->m_mutex);
|
||||
|
||||
if (e == ETIMEDOUT)
|
||||
st->m_eh->operator()(TIMEOUT_EH_CALLER);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
// Other
|
||||
#endif
|
||||
|
||||
|
||||
imp(unsigned ms, event_handler * eh):
|
||||
m_eh(eh) {
|
||||
#if defined(_WINDOWS) || defined(_CYGWIN)
|
||||
m_first = true;
|
||||
CreateTimerQueueTimer(&m_timer,
|
||||
NULL,
|
||||
abort_proc,
|
||||
this,
|
||||
0,
|
||||
ms,
|
||||
WT_EXECUTEINTIMERTHREAD);
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
// macOS
|
||||
m_interval = ms?ms:0xFFFFFFFF;
|
||||
if (pthread_attr_init(&m_attributes) != 0)
|
||||
throw default_exception("failed to initialize timer thread attributes");
|
||||
if (pthread_cond_init(&m_condition_var, nullptr) != 0)
|
||||
throw default_exception("failed to initialize timer condition variable");
|
||||
if (pthread_mutex_init(&m_mutex, nullptr) != 0)
|
||||
throw default_exception("failed to initialize timer mutex");
|
||||
|
||||
clock_serv_t host_clock;
|
||||
mach_timespec_t now;
|
||||
unsigned long long nano = static_cast<unsigned long long>(m_interval) * 1000000ull;
|
||||
|
||||
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &host_clock);
|
||||
m_end_time.tv_sec = nano / 1000000000ull;
|
||||
m_end_time.tv_nsec = nano % 1000000000ull;
|
||||
clock_get_time(host_clock, &now);
|
||||
ADD_MACH_TIMESPEC(&m_end_time, &now);
|
||||
|
||||
|
||||
if (pthread_create(&m_thread_id, &m_attributes, &thread_func, this) != 0)
|
||||
throw default_exception("failed to start timer thread");
|
||||
#elif defined(_LINUX_) || defined(_FREEBSD_) || defined(_NETBSD_)
|
||||
// Linux & FreeBSD & NetBSD
|
||||
m_ms = ms;
|
||||
m_initialized = false;
|
||||
m_signal_sent = false;
|
||||
ENSURE(pthread_mutex_init(&m_mutex, NULL) == 0);
|
||||
ENSURE(pthread_cond_init(&m_cond, NULL) == 0);
|
||||
ENSURE(pthread_create(&m_thread_id, NULL, &thread_func, this) == 0);
|
||||
#else
|
||||
// Other platforms
|
||||
#endif
|
||||
public:
|
||||
imp(unsigned ms, event_handler * eh) {
|
||||
m_mutex.lock();
|
||||
m_thread = std::thread(thread_func, ms, eh, &m_mutex);
|
||||
}
|
||||
|
||||
~imp() {
|
||||
#if defined(_WINDOWS) || defined(_CYGWIN)
|
||||
DeleteTimerQueueTimer(NULL,
|
||||
m_timer,
|
||||
INVALID_HANDLE_VALUE);
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
// macOS
|
||||
|
||||
// If the waiting-thread is not up and waiting yet,
|
||||
// we can make sure that it finishes quickly by
|
||||
// setting the end-time to zero.
|
||||
m_end_time.tv_sec = 0;
|
||||
m_end_time.tv_nsec = 0;
|
||||
|
||||
// Otherwise it's already up and waiting, and
|
||||
// we can send a signal on m_condition_var:
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
pthread_cond_signal(&m_condition_var);
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
|
||||
if (pthread_join(m_thread_id, nullptr) != 0) {
|
||||
warning_msg("failed to join thread");
|
||||
return;
|
||||
}
|
||||
if (pthread_mutex_destroy(&m_mutex) != 0) {
|
||||
warning_msg("failed to destroy pthread mutex");
|
||||
return;
|
||||
}
|
||||
if (pthread_cond_destroy(&m_condition_var) != 0) {
|
||||
warning_msg("failed to destroy pthread condition variable");
|
||||
return;
|
||||
}
|
||||
if (pthread_attr_destroy(&m_attributes) != 0) {
|
||||
warning_msg("failed to destroy pthread attributes object");
|
||||
return;
|
||||
}
|
||||
#elif defined(_LINUX_) || defined(_FREEBSD_) || defined(_NETBSD_)
|
||||
// Linux & FreeBSD & NetBSD
|
||||
bool init = false;
|
||||
|
||||
// spin until timer thread has been created
|
||||
while (!init) {
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
init = m_initialized;
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
if (!init)
|
||||
sched_yield();
|
||||
}
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
m_signal_sent = true;
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
// Perform signal outside of lock to avoid waking timing thread twice.
|
||||
pthread_cond_signal(&m_cond);
|
||||
|
||||
pthread_join(m_thread_id, NULL);
|
||||
pthread_cond_destroy(&m_cond);
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
#else
|
||||
// Other Platforms
|
||||
#endif
|
||||
m_mutex.unlock();
|
||||
m_thread.join();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
scoped_timer::scoped_timer(unsigned ms, event_handler * eh) {
|
||||
|
@ -260,6 +63,5 @@ scoped_timer::scoped_timer(unsigned ms, event_handler * eh) {
|
|||
}
|
||||
|
||||
scoped_timer::~scoped_timer() {
|
||||
if (m_imp)
|
||||
dealloc(m_imp);
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
|
|
@ -20,171 +20,60 @@ Revision History:
|
|||
#ifndef STOPWATCH_H_
|
||||
#define STOPWATCH_H_
|
||||
|
||||
#if defined(_WINDOWS) || defined(_CYGWIN) || defined(_MINGW)
|
||||
|
||||
// Does this redefinition work?
|
||||
|
||||
#include <windows.h>
|
||||
#include "util/debug.h"
|
||||
#include <chrono>
|
||||
|
||||
class stopwatch
|
||||
{
|
||||
private:
|
||||
LARGE_INTEGER m_elapsed;
|
||||
LARGE_INTEGER m_last_start_time;
|
||||
LARGE_INTEGER m_last_stop_time;
|
||||
LARGE_INTEGER m_frequency;
|
||||
typedef decltype(std::chrono::steady_clock::now()) clock_t;
|
||||
typedef decltype(std::chrono::steady_clock::now() - std::chrono::steady_clock::now()) duration_t;
|
||||
|
||||
clock_t m_start;
|
||||
duration_t m_elapsed;
|
||||
#if Z3DEBUG
|
||||
bool m_running = false;
|
||||
#endif
|
||||
|
||||
// FIXME: just use auto with VS 2015+
|
||||
static clock_t get() {
|
||||
return std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
public:
|
||||
stopwatch() {
|
||||
QueryPerformanceFrequency(&m_frequency);
|
||||
reset();
|
||||
reset();
|
||||
}
|
||||
|
||||
~stopwatch() {};
|
||||
|
||||
void add (const stopwatch &s) {/* TODO */}
|
||||
|
||||
void reset() { m_elapsed.QuadPart = 0; }
|
||||
|
||||
void start() {
|
||||
QueryPerformanceCounter(&m_last_start_time);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
QueryPerformanceCounter(&m_last_stop_time);
|
||||
m_elapsed.QuadPart += m_last_stop_time.QuadPart - m_last_start_time.QuadPart;
|
||||
void add(const stopwatch &s) {
|
||||
m_elapsed += s.m_elapsed;
|
||||
}
|
||||
|
||||
double get_seconds() const {
|
||||
return static_cast<double>(m_elapsed.QuadPart / static_cast<double>(m_frequency.QuadPart)) ;
|
||||
void reset() {
|
||||
m_elapsed = duration_t::zero();
|
||||
DEBUG_CODE(m_running = false;);
|
||||
}
|
||||
|
||||
void start() {
|
||||
SASSERT(!m_running);
|
||||
DEBUG_CODE(m_running = true;);
|
||||
m_start = get();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
SASSERT(m_running);
|
||||
DEBUG_CODE(m_running = false;);
|
||||
m_elapsed += get() - m_start;
|
||||
}
|
||||
|
||||
double get_seconds() const {
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(m_elapsed).count() / 1000.0;
|
||||
}
|
||||
|
||||
double get_current_seconds() const {
|
||||
LARGE_INTEGER t;
|
||||
QueryPerformanceCounter(&t);
|
||||
return static_cast<double>( (t.QuadPart - m_last_start_time.QuadPart) / static_cast<double>(m_frequency.QuadPart));
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(get() - m_start).count() / 1000.0;
|
||||
}
|
||||
};
|
||||
|
||||
#undef max
|
||||
#undef min
|
||||
|
||||
|
||||
#elif defined(__APPLE__) && defined (__MACH__) // macOS
|
||||
|
||||
#include<mach/mach.h>
|
||||
#include<mach/clock.h>
|
||||
|
||||
class stopwatch {
|
||||
unsigned long long m_time; // elapsed time in ns
|
||||
bool m_running;
|
||||
clock_serv_t m_host_clock;
|
||||
mach_timespec_t m_start;
|
||||
|
||||
public:
|
||||
stopwatch():m_time(0), m_running(false) {
|
||||
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &m_host_clock);
|
||||
}
|
||||
|
||||
~stopwatch() {}
|
||||
|
||||
void add (const stopwatch &s) {m_time += s.m_time;}
|
||||
|
||||
void reset() {
|
||||
m_time = 0ull;
|
||||
}
|
||||
|
||||
void start() {
|
||||
if (!m_running) {
|
||||
clock_get_time(m_host_clock, &m_start);
|
||||
m_running = true;
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
if (m_running) {
|
||||
mach_timespec_t _stop;
|
||||
clock_get_time(m_host_clock, &_stop);
|
||||
m_time += (_stop.tv_sec - m_start.tv_sec) * 1000000000ull;
|
||||
m_time += (_stop.tv_nsec - m_start.tv_nsec);
|
||||
m_running = false;
|
||||
}
|
||||
}
|
||||
|
||||
double get_seconds() const {
|
||||
if (m_running) {
|
||||
const_cast<stopwatch*>(this)->stop();
|
||||
/* update m_time */
|
||||
const_cast<stopwatch*>(this)->start();
|
||||
}
|
||||
return static_cast<double>(m_time)/static_cast<double>(1000000000ull);
|
||||
}
|
||||
|
||||
double get_current_seconds() const {
|
||||
return get_seconds();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#else // Linux
|
||||
|
||||
#include<ctime>
|
||||
|
||||
#ifndef CLOCK_PROCESS_CPUTIME_ID
|
||||
/* BSD */
|
||||
# define CLOCK_PROCESS_CPUTIME_ID CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
class stopwatch {
|
||||
unsigned long long m_time; // elapsed time in ns
|
||||
bool m_running;
|
||||
struct timespec m_start;
|
||||
|
||||
public:
|
||||
stopwatch():m_time(0), m_running(false) {
|
||||
}
|
||||
|
||||
~stopwatch() {}
|
||||
|
||||
void add (const stopwatch &s) {m_time += s.m_time;}
|
||||
|
||||
void reset() {
|
||||
m_time = 0ull;
|
||||
}
|
||||
|
||||
void start() {
|
||||
if (!m_running) {
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &m_start);
|
||||
m_running = true;
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
if (m_running) {
|
||||
struct timespec _stop;
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &_stop);
|
||||
m_time += (_stop.tv_sec - m_start.tv_sec) * 1000000000ull;
|
||||
if (m_time != 0 || _stop.tv_nsec >= m_start.tv_nsec)
|
||||
m_time += (_stop.tv_nsec - m_start.tv_nsec);
|
||||
m_running = false;
|
||||
}
|
||||
}
|
||||
|
||||
double get_seconds() const {
|
||||
if (m_running) {
|
||||
const_cast<stopwatch*>(this)->stop();
|
||||
/* update m_time */
|
||||
const_cast<stopwatch*>(this)->start();
|
||||
}
|
||||
return static_cast<double>(m_time)/static_cast<double>(1000000000ull);
|
||||
}
|
||||
|
||||
double get_current_seconds() const {
|
||||
return get_seconds();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct scoped_watch {
|
||||
stopwatch &m_sw;
|
||||
|
|
|
@ -28,7 +28,7 @@ struct str_hash_proc {
|
|||
unsigned operator()(char const * s) const { return string_hash(s, static_cast<unsigned>(strlen(s)), 17); }
|
||||
};
|
||||
struct str_eq_proc { bool operator()(char const * s1, char const * s2) const { return strcmp(s1, s2) == 0; } };
|
||||
typedef ptr_hashtable<char, str_hash_proc, str_eq_proc> str_hashtable;
|
||||
typedef ptr_hashtable<const char, str_hash_proc, str_eq_proc> str_hashtable;
|
||||
|
||||
#endif /* STR_HASHTABLE_H_ */
|
||||
|
||||
|
|
|
@ -35,20 +35,19 @@ class internal_symbol_table {
|
|||
public:
|
||||
|
||||
char const * get_str(char const * d) {
|
||||
char * result;
|
||||
const char * result;
|
||||
#pragma omp critical (cr_symbol)
|
||||
{
|
||||
char * r_d = const_cast<char *>(d);
|
||||
str_hashtable::entry * e;
|
||||
if (m_table.insert_if_not_there_core(r_d, e)) {
|
||||
if (m_table.insert_if_not_there_core(d, e)) {
|
||||
// new entry
|
||||
size_t l = strlen(d);
|
||||
// store the hash-code before the string
|
||||
size_t * mem = static_cast<size_t*>(m_region.allocate(l + 1 + sizeof(size_t)));
|
||||
*mem = e->get_hash();
|
||||
mem++;
|
||||
result = reinterpret_cast<char*>(mem);
|
||||
memcpy(result, d, l+1);
|
||||
result = reinterpret_cast<const char*>(mem);
|
||||
memcpy(mem, d, l+1);
|
||||
// update the entry with the new ptr.
|
||||
e->set_data(result);
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
explicit symbol(char const * d);
|
||||
explicit symbol(unsigned idx):
|
||||
m_data(BOXTAGINT(char const *, idx, 1)) {
|
||||
#ifndef _AMD64_
|
||||
#if !defined(__LP64__) && !defined(_WIN64)
|
||||
SASSERT(idx < (SIZE_MAX >> PTR_ALIGNMENT));
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ Revision History:
|
|||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include "util/z3_omp.h"
|
||||
#include "util/util.h"
|
||||
#include "util/timeout.h"
|
||||
#include "util/error_codes.h"
|
||||
|
@ -34,26 +33,21 @@ namespace {
|
|||
class g_timeout_eh : public event_handler {
|
||||
public:
|
||||
void operator()(event_handler_caller_t caller_id) override {
|
||||
#pragma omp critical (g_timeout_cs)
|
||||
{
|
||||
std::cout << "timeout\n";
|
||||
m_caller_id = caller_id;
|
||||
if (g_on_timeout)
|
||||
g_on_timeout();
|
||||
if (g_timeout)
|
||||
delete g_timeout;
|
||||
g_timeout = nullptr;
|
||||
throw z3_error(ERR_TIMEOUT);
|
||||
}
|
||||
std::cout << "timeout\n";
|
||||
m_caller_id = caller_id;
|
||||
if (g_on_timeout)
|
||||
g_on_timeout();
|
||||
throw z3_error(ERR_TIMEOUT);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void set_timeout(long ms) {
|
||||
if (g_timeout)
|
||||
delete g_timeout;
|
||||
static g_timeout_eh eh;
|
||||
|
||||
g_timeout = new scoped_timer(ms, new g_timeout_eh());
|
||||
void set_timeout(long ms) {
|
||||
SASSERT(!g_timeout);
|
||||
// this is leaked, but since it's only used in the shell, it's ok
|
||||
g_timeout = new scoped_timer(ms, &eh);
|
||||
}
|
||||
|
||||
void register_on_timeout_proc(void (*proc)()) {
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
timer.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2009-01-06.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include "util/util.h"
|
||||
#include "util/memory_manager.h"
|
||||
#include "util/stopwatch.h"
|
||||
#include "util/timer.h"
|
||||
|
||||
timer::timer(){
|
||||
m_watch = alloc(stopwatch);
|
||||
start();
|
||||
}
|
||||
|
||||
timer::~timer() {
|
||||
dealloc(m_watch);
|
||||
}
|
||||
|
||||
void timer::start() {
|
||||
m_watch->start();
|
||||
}
|
||||
|
||||
double timer::get_seconds() {
|
||||
return m_watch->get_current_seconds();
|
||||
}
|
||||
|
|
@ -19,21 +19,29 @@ Revision History:
|
|||
#ifndef TIMER_H_
|
||||
#define TIMER_H_
|
||||
|
||||
class stopwatch;
|
||||
#include "util/stopwatch.h"
|
||||
|
||||
/**
|
||||
\brief Wrapper for the stopwatch class. It hides windows.h dependency.
|
||||
\brief Wrapper for the stopwatch class.
|
||||
*/
|
||||
class timer {
|
||||
stopwatch * m_watch;
|
||||
stopwatch m_watch;
|
||||
public:
|
||||
timer();
|
||||
~timer();
|
||||
void start();
|
||||
double get_seconds();
|
||||
bool timeout(unsigned secs) { return secs > 0 && secs != UINT_MAX && get_seconds() > secs; }
|
||||
bool ms_timeout(unsigned ms) { return ms > 0 && ms != UINT_MAX && get_seconds() * 1000 > ms; }
|
||||
timer() {
|
||||
m_watch.start();
|
||||
}
|
||||
|
||||
double get_seconds() const {
|
||||
return m_watch.get_current_seconds();
|
||||
}
|
||||
|
||||
bool timeout(unsigned secs) const {
|
||||
return secs != 0 && secs != UINT_MAX && get_seconds() > secs;
|
||||
}
|
||||
|
||||
bool ms_timeout(unsigned ms) const {
|
||||
return ms != 0 && ms != UINT_MAX && get_seconds() * 1000 > ms;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* TIMER_H_ */
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ void finalize_trace() {
|
|||
}
|
||||
|
||||
void enable_trace(const char * tag) {
|
||||
get_enabled_trace_tags().insert(const_cast<char *>(tag));
|
||||
get_enabled_trace_tags().insert(tag);
|
||||
}
|
||||
|
||||
void enable_all_trace(bool flag) {
|
||||
|
@ -46,12 +46,12 @@ void enable_all_trace(bool flag) {
|
|||
}
|
||||
|
||||
void disable_trace(const char * tag) {
|
||||
get_enabled_trace_tags().erase(const_cast<char *>(tag));
|
||||
get_enabled_trace_tags().erase(tag);
|
||||
}
|
||||
|
||||
bool is_trace_enabled(const char * tag) {
|
||||
return g_enable_all_trace_tags ||
|
||||
(g_enabled_trace_tags && get_enabled_trace_tags().contains(const_cast<char *>(tag)));
|
||||
(g_enabled_trace_tags && get_enabled_trace_tags().contains(tag));
|
||||
}
|
||||
|
||||
void close_trace() {
|
||||
|
|
|
@ -24,10 +24,6 @@ Revision History:
|
|||
#undef max
|
||||
#undef min
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#undef max
|
||||
#undef min
|
||||
#endif
|
||||
#include<fstream>
|
||||
|
||||
#ifdef _TRACE
|
||||
|
|
|
@ -63,14 +63,6 @@ static_assert(sizeof(int64_t) == 8, "64 bits");
|
|||
|
||||
#define VEC2PTR(_x_) ((_x_).size() ? &(_x_)[0] : 0)
|
||||
|
||||
#ifdef _WINDOWS
|
||||
// Disable thread local declspec as it seems to not work downlevel.
|
||||
// #define THREAD_LOCAL __declspec(thread)
|
||||
#define THREAD_LOCAL
|
||||
#else
|
||||
#define THREAD_LOCAL
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define STD_CALL __cdecl
|
||||
#else
|
||||
|
|
|
@ -88,7 +88,7 @@ void format2ostream(std::ostream & out, char const* msg, va_list args) {
|
|||
#ifdef _WINDOWS
|
||||
size_t msg_len = _vscprintf(msg, args_copy);
|
||||
#else
|
||||
size_t msg_len = vsnprintf(NULL, 0, msg, args_copy);
|
||||
size_t msg_len = vsnprintf(nullptr, 0, msg, args_copy);
|
||||
#endif
|
||||
va_end(args_copy);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue