diff gsm-fw/riviera/support/exception.h @ 143:afceeeb2cba1

Our nuc-fw is destined to become gsm-fw, so I went ahead and did the big hg mv
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Tue, 12 Nov 2013 05:35:48 +0000
parents nuc-fw/riviera/support/exception.h@dd56546ad9e0
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/riviera/support/exception.h	Tue Nov 12 05:35:48 2013 +0000
@@ -0,0 +1,123 @@
+/*
+ ******************************
+ * 
+ *
+ * Initialial version: Laurent Deniau, Laurent.Deniau@cern.ch
+ *
+ * For more information, please see the paper:
+ * http://cern.ch/Laurent.Deniau/html/oopc/exception.html
+ * 
+ * -----------------------------------------------------------
+ *
+ * Strong rework and adaption to riviera by Christophe Favergeon
+ *
+ ******************************
+ */
+
+#ifndef RVF_EXCEPTION_H
+#define RVF_EXCEPTION_H
+
+#include "../rvf/rvf_api.h"
+#include "../rvf/rvf_target.h"
+
+#include <string.h>
+
+
+
+//#ifndef __STDC__
+//#  error "exception.h needs ISO C compiler to work properly"
+//#endif
+
+#include <setjmp.h>
+
+typedef enum K_RVF_EXCEPTIONS { E_invalid=1, E_not_enough_memory,E_unknown } T_RVF_EXCEPTIONS; 
+
+typedef void (*T_RVF_RELEASE_PROTECTED_POINTER)(void *p);
+
+/*
+  choose context savings
+*/
+
+#define rvf_save_context_buffer_(context)         setjmp(context)
+#define rvf_restore_context_buffer_(context, val) longjmp(context, val)
+
+/*
+  some hidden types used to handle exceptions
+*/
+
+/* type of stack of protected pointer */
+struct _protectedPtr_ {
+  struct _protectedPtr_ *next;
+  struct _protectedPtr_ *previous;
+  void *ptr;
+  T_RVF_RELEASE_PROTECTED_POINTER func;
+};
+
+/* type of stack of exception */
+struct _exceptionContext_ {
+  struct _exceptionContext_ *next;
+  struct _protectedPtr_ *stack;
+  jmp_buf context;
+};
+
+extern struct _exceptionContext_ *const _returnExceptionContext_[MAX_RVF_TASKS];
+extern struct _exceptionContext_ *_currentExceptionContext_[MAX_RVF_TASKS];
+
+/* exception keywords */
+#define try								 \
+  do {									 \
+	struct _exceptionContext_ _localExceptionContext_ ;\
+	memset(&_localExceptionContext_,0,sizeof(struct _exceptionContext_));\
+    _localExceptionContext_.next=_currentExceptionContext_[rvf_get_taskid()];\
+    _currentExceptionContext_[rvf_get_taskid()] = &_localExceptionContext_;		 \
+    do {								 \
+      int const exception =						 \
+              rvf_save_context_buffer_(_currentExceptionContext_[rvf_get_taskid()]->context); \
+      if (!exception) {
+
+#define catch(except)							\
+      } else if ((int)(except) == exception) {				\
+        _currentExceptionContext_[rvf_get_taskid()] = _currentExceptionContext_[rvf_get_taskid()]->next;
+
+#define catch_any							\
+      } else {								\
+        _currentExceptionContext_[rvf_get_taskid()] = _currentExceptionContext_[rvf_get_taskid()]->next;
+
+#define endtry								\
+      }									\
+    } while(0);								\
+    if (_currentExceptionContext_[rvf_get_taskid()] == &_localExceptionContext_) {	\
+      rvf_forget_protected_ptr();\
+      _currentExceptionContext_[rvf_get_taskid()] = _currentExceptionContext_[rvf_get_taskid()]->next;	\
+    }									\
+  } while(0)
+
+#define rethrow throw(exception)
+#define break_try break
+
+/*
+#define return_try(...)						\
+  do {								\
+    _currentExceptionContext_ = _returnExceptionContext_;	\
+    return __VA_ARGS__;						\
+  } while(0)
+*/
+
+#define throw(except) _exceptionThrow_((int)(except))
+
+
+/*
+  extern declarations
+*/
+
+extern void _exceptionThrow_(int except);
+
+extern void rvf_forget_protected_ptr();
+extern void rvf_protect_pointer(T_RVF_MB_ID mb_id,void *p,T_RVF_RELEASE_PROTECTED_POINTER func);
+
+#define RVF_PROTECT(bank,p) rvf_protect_pointer(bank,p,(T_RVF_RELEASE_PROTECTED_POINTER)rvf_free_buf)
+
+#define THROW_IF_ERROR(err) if (err!=0) throw(E_unknown)
+#define THROW_IF_NULL(p) if (p==NULL) throw(E_not_enough_memory)
+#define THROW_IF_YELLOW(b,p) if ((p==NULL) || (rvf_get_mb_status(b)==RVF_YELLOW)) throw(E_not_enough_memory)
+#endif