[PPL-devel] [GIT] ppl/ppl(master): Added timeout functions to the OCaml interface.
Enea Zaffanella
zaffanella at cs.unipr.it
Mon Mar 30 11:18:53 CEST 2009
Module: ppl/ppl
Branch: master
Commit: 67042a165fa0d65c0d7460f62808f742407944da
URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=67042a165fa0d65c0d7460f62808f742407944da
Author: Enea Zaffanella <zaffanella at 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();
More information about the PPL-devel
mailing list