[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