
Module: ppl/ppl Branch: master Commit: 67042a165fa0d65c0d7460f62808f742407944da URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=67042a165fa0d...
Author: Enea Zaffanella zaffanella@cs.unipr.it Date: Mon Mar 30 12:16:24 2009 +0200
Added timeout functions to the OCaml interface. Also removed duplicate CATCH_ALL macro definitions in the Prolog and OCaml interfaces.
---
Watchdog/src/Watchdog.defs.hh | 2 + interfaces/OCaml/ppl_ocaml_common.cc | 80 ++++++++++++++++++++-------- interfaces/OCaml/ppl_ocaml_common.defs.hh | 20 +++++++ interfaces/OCaml/ppl_ocaml_globals.ml | 6 ++ interfaces/OCaml/ppl_ocaml_globals.mli | 6 ++ interfaces/Prolog/ppl_prolog_common.cc | 66 ------------------------ 6 files changed, 91 insertions(+), 89 deletions(-)
diff --git a/Watchdog/src/Watchdog.defs.hh b/Watchdog/src/Watchdog.defs.hh index 733c355..7104e16 100644 --- a/Watchdog/src/Watchdog.defs.hh +++ b/Watchdog/src/Watchdog.defs.hh @@ -41,9 +41,11 @@ extern "C" void PWL_handle_timeout(int signum); //! A watchdog timer. class Watchdog { public: + // TODO: reconsider whether `units' should be an unsigned. template <typename Flag_Base, typename Flag> Watchdog(int units, const Flag_Base* volatile& holder, Flag& flag);
+ // TODO: reconsider whether `units' should be an unsigned. Watchdog(int units, void (*function)()); ~Watchdog();
diff --git a/interfaces/OCaml/ppl_ocaml_common.cc b/interfaces/OCaml/ppl_ocaml_common.cc index d3a3177..c623139 100644 --- a/interfaces/OCaml/ppl_ocaml_common.cc +++ b/interfaces/OCaml/ppl_ocaml_common.cc @@ -21,7 +21,6 @@ For the most up-to-date information see the Parma Polyhedra Library site: http://www.cs.unipr.it/ppl/ . */
#include "ppl_ocaml_common.defs.hh" -//#include <stdexcept>
namespace Parma_Polyhedra_Library {
@@ -79,29 +78,31 @@ class PFunc { } };
-#define CATCH_ALL \ - catch(std::bad_alloc&) { \ - caml_raise_out_of_memory(); \ - } \ - catch(std::invalid_argument& e) { \ - caml_invalid_argument(const_cast<char*>(e.what())); \ - } \ - catch(std::overflow_error& e) { \ - caml_raise_with_string(*caml_named_value("PPL_arithmetic_overflow"), \ - (const_cast<char*>(e.what()))); \ - } \ - catch(std::runtime_error& e) { \ - caml_raise_with_string(*caml_named_value("PPL_internal_error"), \ - (const_cast<char*>(e.what()))); \ - } \ - catch(std::exception& e) { \ - caml_raise_with_string(*caml_named_value("PPL_unknown_standard_exception"), \ - (const_cast<char*>(e.what()))); \ - } \ - catch(...) { \ - caml_raise_constant(*caml_named_value("PPL_unexpected_error")); \ + +#ifdef PPL_WATCHDOG_LIBRARY_ENABLED + +Parma_Watchdog_Library::Watchdog* p_timeout_object = 0; + +void +reset_timeout() { + if (p_timeout_object) { + delete p_timeout_object; + p_timeout_object = 0; + abandon_expensive_computations = 0; } +}
+#endif // PPL_WATCHDOG_LIBRARY_ENABLED + +void +handle_timeout_exception() { +#ifdef PPL_WATCHDOG_LIBRARY_ENABLED + assert(p_timeout_object); + reset_timeout(); +#endif + caml_raise_with_string(*caml_named_value("PPL_timeout_exception"), + "timeout expired"); +}
namespace {
@@ -1201,7 +1202,6 @@ ppl_set_rounding_for_PPL(value unit) try { } CATCH_ALL
- extern "C" CAMLprim value ppl_restore_pre_PPL_rounding(value unit) try { @@ -1210,3 +1210,37 @@ ppl_restore_pre_PPL_rounding(value unit) try { CAMLreturn(Val_unit); } CATCH_ALL + +extern "C" +CAMLprim value +ppl_set_timeout(value time) try { + CAMLparam1(time); +#ifndef PPL_WATCHDOG_LIBRARY_ENABLED + const char* what = "PPL OCaml interface usage error:\n" + "ppl_set_timeout: the PPL Watchdog library is not enabled."; + throw std::runtime_error(what); +#else + // In case a timeout was already set. + reset_timeout(); + unsigned cpp_time = value_to_unsigned_native<unsigned>(time); + static timeout_exception e; + using Parma_Watchdog_Library::Watchdog; + p_timeout_object = new Watchdog(cpp_time, abandon_expensive_computations, e); + CAMLreturn(Val_unit); +#endif // PPL_WATCHDOG_LIBRARY_ENABLED +} +CATCH_ALL + +extern "C" +CAMLprim value +ppl_reset_timeout(value unit) try { + CAMLparam1(unit); +#ifndef PPL_WATCHDOG_LIBRARY_ENABLED + throw std::runtime_error("PPL OCaml interface error:\n" + "the PPL Watchdog library is not enabled."); +#else + reset_timeout(); + CAMLreturn(Val_unit); +#endif // PPL_WATCHDOG_LIBRARY_ENABLED +} +CATCH_ALL diff --git a/interfaces/OCaml/ppl_ocaml_common.defs.hh b/interfaces/OCaml/ppl_ocaml_common.defs.hh index 1555518..05d87de 100644 --- a/interfaces/OCaml/ppl_ocaml_common.defs.hh +++ b/interfaces/OCaml/ppl_ocaml_common.defs.hh @@ -24,6 +24,9 @@ site: http://www.cs.unipr.it/ppl/ . */ #define PPL_ppl_ocaml_common_defs_hh 1
#include "ppl.hh" +#ifdef PPL_WATCHDOG_LIBRARY_ENABLED +#include "pwl.hh" +#endif #include "interfaced_boxes.hh" #include "marked_pointers.hh"
@@ -155,6 +158,20 @@ private: std::vector<dimension_type> vec; };
+class timeout_exception : public Parma_Polyhedra_Library::Throwable { +public: + void throw_me() const { + throw *this; + } + int priority() const { + return 0; + } + timeout_exception() { + } +}; + +void handle_timeout_exception(); + } // namespace OCaml
} // namespace Interfaces @@ -176,6 +193,9 @@ catch(std::bad_alloc&) { \ caml_raise_with_string(*caml_named_value("PPL_internal_error"), \ (const_cast<char*>(e.what()))); \ } \ + catch(timeout_exception&) { \ + handle_timeout_exception(); \ + } \ catch(std::exception& e) { \ caml_raise_with_string(*caml_named_value("PPL_unknown_standard_exception"), \ (const_cast<char*>(e.what()))); \ diff --git a/interfaces/OCaml/ppl_ocaml_globals.ml b/interfaces/OCaml/ppl_ocaml_globals.ml index 06e66bf..1d9fb22 100644 --- a/interfaces/OCaml/ppl_ocaml_globals.ml +++ b/interfaces/OCaml/ppl_ocaml_globals.ml @@ -138,6 +138,12 @@ unit -> unit = "ppl_set_rounding_for_PPL" external ppl_restore_pre_PPL_rounding: unit -> unit = "ppl_restore_pre_PPL_rounding"
+external ppl_set_timeout: +int -> unit = "ppl_set_timeout" + +external ppl_reset_timeout: +unit -> unit = "ppl_reset_timeout" + external ppl_new_MIP_Problem_from_space_dimension: int -> mip_problem = "ppl_new_MIP_Problem_from_space_dimension"
diff --git a/interfaces/OCaml/ppl_ocaml_globals.mli b/interfaces/OCaml/ppl_ocaml_globals.mli index 8973162..dcc6d22 100644 --- a/interfaces/OCaml/ppl_ocaml_globals.mli +++ b/interfaces/OCaml/ppl_ocaml_globals.mli @@ -137,6 +137,12 @@ val ppl_set_rounding_for_PPL: val ppl_restore_pre_PPL_rounding: unit -> unit
+val ppl_set_timeout: + int -> unit + +val ppl_reset_timeout: + unit -> unit + type mip_problem
val ppl_new_MIP_Problem_from_space_dimension: diff --git a/interfaces/Prolog/ppl_prolog_common.cc b/interfaces/Prolog/ppl_prolog_common.cc index 2a43542..782a368 100644 --- a/interfaces/Prolog/ppl_prolog_common.cc +++ b/interfaces/Prolog/ppl_prolog_common.cc @@ -622,72 +622,6 @@ handle_exception(const timeout_exception&) { Prolog_raise_exception(et); }
-#define CATCH_ALL \ - catch (const Prolog_unsigned_out_of_range& e) { \ - handle_exception(e); \ - } \ - catch (const not_unsigned_integer& e) { \ - handle_exception(e); \ - } \ - catch (const non_linear& e) { \ - handle_exception(e); \ - } \ - catch (const not_a_variable& e) { \ - handle_exception(e); \ - } \ - catch (const not_an_integer& e) { \ - handle_exception(e); \ - } \ - catch (const ppl_handle_mismatch& e) { \ - handle_exception(e); \ - } \ - catch (const not_an_optimization_mode& e) { \ - handle_exception(e); \ - } \ - catch (const not_a_complexity_class& e) { \ - handle_exception(e); \ - } \ - catch (const not_a_control_parameter_name& e) { \ - handle_exception(e); \ - } \ - catch (const not_a_control_parameter_value& e) { \ - handle_exception(e); \ - } \ - catch (const not_universe_or_empty& e) { \ - handle_exception(e); \ - } \ - catch (const not_a_relation& e) { \ - handle_exception(e); \ - } \ - catch (const not_a_nil_terminated_list& e) { \ - handle_exception(e); \ - } \ - catch (const PPL_integer_out_of_range& e) { \ - handle_exception(e); \ - } \ - catch (const unknown_interface_error& e) { \ - handle_exception(e); \ - } \ - catch (const timeout_exception& e) { \ - handle_exception(e); \ - } \ - catch(const std::overflow_error& e) { \ - handle_exception(e); \ - } \ - catch(const std::length_error& e) { \ - handle_exception(e); \ - } \ - catch (const std::bad_alloc& e) { \ - handle_exception(e); \ - } \ - catch (const std::exception& e) { \ - handle_exception(e); \ - } \ - catch (...) { \ - handle_exception(); \ - } \ - return PROLOG_FAILURE - Prolog_term_ref variable_term(dimension_type varid) { Prolog_term_ref v = Prolog_new_term_ref();