SIMLIB/C++  3.07
internal.h
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 //! \file internal.h Internal header file for SIMLIB/C++
3 //
4 // Copyright (c) 1991-2004 Petr Peringer
5 //
6 // This library is licensed under GNU Library GPL. See the file COPYING.
7 //
8 
9 /**
10  * @mainpage SIMLIB
11  * @author Petr Peringer
12  * @author David Martinek (fuzzy subsystem)
13  * @author David Leška (numerical integration subsystem)
14  *
15  * SIMLIB/C++ is the SIMulation LIBrary for C++ programming language
16  *
17  * \section intro Introduction
18  *
19  * This documentation is experimental for now.
20  * It is made by program doxygen and is not complete.
21  * Fuzzy extension documentation is not generated.
22  * You can edit doxygen.config to improve it.
23  *
24  */
25 
26 //! \example _test_.cc
27 //! This is simple example for basic testing of SIMLIB/C++.
28 //! <br> Usage: make test
29 
30 //! \example examples/ball.cc Bouncing ball example
31 //! \example examples/ball2.cc Bouncing ball example
32 //! \example examples/bessel.cc
33 //! \example examples/ctest.cc
34 //! \example examples/heating.cc Relay example
35 //! \example examples/lorenz.cc Lorenz equation
36 //! \example examples/model2.cc Queuing system
37 //! \example examples/model2-timeout.cc
38 //! \example examples/multiexp.cc Queuing system, multiple experiments
39 //! \example examples/rc.cc Electrical RC circuit
40 //! \example examples/rlc.cc
41 //! \example examples/test3D.cc
42 //! \example examples/wheel.cc mass+spring+damper
43 //! \example examples/wheel2.cc ..., multiple experiments
44 
45 //
46 // SIMLIB internal declarations
47 //
48 
49 #ifndef __SIMLIB__INTERNAL_H__
50 #define __SIMLIB__INTERNAL_H__
51 
52 #ifndef __SIMLIB__
53 # error "simlib.h should be included first"
54 #endif
55 
56 namespace simlib3 {
57 
58 ////////////////////////////////////////////////////////////////////////////
59 //! Class for internal registration of modules.
60 class SIMLIB_module { // internal class for SIMLIB cleanup (atexit)
61  const char *string; // module identification string
62  SIMLIB_module(const SIMLIB_module&); // disable copy-ctr
63  SIMLIB_module &operator= (const SIMLIB_module&); // disable =
64  public:
65  SIMLIB_module();
66  int Init(const char *s);
67  ~SIMLIB_module(); // last? module can do ATEXIT cleaning
68 };
69 
70 ////////////////////////////////////////////////////////////////////////////
71 //! Create single global registration object in each SIMLIB module.
72 /// Should be first initialized object in the module
74 
75 //! values indicate current phase of experiment
77  START, // before first Init() call
78  INITIALIZATION, // after Init() call
79  SIMULATION, // inside Run() call
80  TERMINATION, // after Run() call
81  ERROREXIT // fatal error handling phase
82 };
83 //! This variable contains the current phase of experiment
84 //! (used for internal checking)
85 extern const SIMLIB_Phase_t &Phase;
86 
87 ////////////////////////////////////////////////////////////////////////////
88 // debugging ...
89 //TODO: minimize
90 //#define NDEBUG // uncomment if you don't want to compile debug info
91 
92 #ifdef NDEBUG
93 # define Dprintf(s)
94 # define DEBUG(c,s)
95 # define DEBUG_INFO
96 #else
97  extern double SIMLIB_Time; // simulation time
98 # define DEBUG_INFO "/debug"
99  extern unsigned long SIMLIB_debug_flag; // debugging flags
100 # define Dprintf(f) \
101  do { if( SIMLIB_debug_flag ) \
102  { _Print("DEBUG: T=%-10g ", SIMLIB_Time); \
103  _Print f; _Print("\n"); \
104  } }while(0)
105 # define DEBUG(c,f) \
106  do{ if( SIMLIB_debug_flag & (c) ) \
107  { _Print("DEBUG: T=%-10g ", SIMLIB_Time); \
108  _Print f; _Print("\n"); \
109  } }while(0)
110  // classification of DEBUG messages
111 # define DBG_ALL ~0UL // print all debugging info
112 # define DBG_NEW (1UL) // new/delete (memory allocation)
113 # define DBG_CTR (1UL<<1) // ctr/dtr (creation/destruction)
114 # define DBG_INIT (1UL<<2) // initialization
115 # define DBG_CHG (1UL<<3) // object changes
116 # define DBG_STEP (1UL<<4) // continuous step control
117 # define DBG_CONTI (1UL<<5) // continuous blocks
118 # define DBG_FACSTO (1UL<<6) // Enter,Leave,Seize,Release
119 # define DBG_PROCESS (1UL<<7) // Process
120 # define DBG_QUEUE (1UL<<8) // Queue operations
121 # define DBG_CALENDAR (1UL<<9) // Scheduling
122 # define DBG_SIMULATOR (1UL<<10) // Simulator actions - control
123 # define DBG_BEXPR (1UL<<11) // Block expressions
124 # define DBG_WU (1UL<<12) // WaitUntil
125 # define DBG_NUMINT (1UL<<13) // numerical integration methods
126 # define DBG_THREAD (1UL<<14) // Process-switching
127 # define DBG_MODULE (1UL<<15) // Module cleanup: id_string,...
128 # define DBG_ATEXIT (1UL<<16) // SIMLIB_atexit
129 #endif // NDEBUG
130 
131 
132 ////////////////////////////////////////////////////////////////////////////
133 /// \def SIMLIB_IMPLEMENTATION
134 /// internal module identification
135 #define SIMLIB_IMPLEMENTATION \
136  _Pragma("GCC diagnostic push") \
137  _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") \
138  static int SIMLIB_module_num = \
139  SIMLIB_module_id.Init( \
140  "(" __FILE__ \
141  ", SIMLIB-" SIMLIB_VERSION DEBUG_INFO \
142  ", " SIMLIB_SYSTEM \
143  "/" SIMLIB_COMPILER \
144  ", " __DATE__ " " __TIME__ \
145  ")" \
146  ); \
147  _Pragma("GCC diagnostic pop")
148 
149 // SIMLIB atexit function (for internal use only)
150 typedef void (*SIMLIB_atexit_function_t)();
152 
153 ////////////////////////////////////////////////////////////////////////////
154 // error handling functions
155 //
156 
157 #include "errors.h" // error messages (generated by program generr)
158 
159 /// print specific error messages
160 [[noreturn]] void SIMLIB_error(const enum _ErrEnum ErrMsgNum);
161 
162 /// print formatted error messages
163 [[noreturn]] void SIMLIB_error(const char *fmt, ... );
164 
165 /// print internal error messages
166 [[noreturn]] void SIMLIB_error(const char *file, const int line);
167 #define SIMLIB_internal_error() SIMLIB_error(__FILE__, __LINE__)
168 
169 /// print warnings
170 void SIMLIB_warning(const enum _ErrEnum ErrMsgNum);
171 /// print warnings
172 void SIMLIB_warning(const char *fmt, ... );
173 
174 ////////////////////////////////////////////////////////////////////////////
175 // types:
176 //
177 typedef void (*VoidFunctionPtr)(); // ptr to void function
178 
179 
180 ////////////////////////////////////////////////////////////////////////////
181 // internal variables:
182 //
183 
184 extern bool SIMLIB_DynamicFlag; // in dynamic section
185 extern bool SIMLIB_ResetStatus; // restart flag
186 
187 extern SIMLIB_Phase_t SIMLIB_Phase; // phase of simulation experiment
188 
189 extern Entity *SIMLIB_Current; // currently active entity
190 
191 extern int SIMLIB_ERRNO; // error number
192 
193 extern bool SIMLIB_ConditionFlag; // change of condition vector
194 extern bool SIMLIB_ContractStepFlag; // requests shorter step
195 extern double SIMLIB_ContractStep; // requested step size
196 
197 extern double SIMLIB_StepStartTime; // last step time
198 extern double SIMLIB_DeltaTime; // Time-s_StepStartTime
199 
200 extern double SIMLIB_OptStep; // optimal step
201 extern double SIMLIB_MinStep; // minimal step
202 extern double SIMLIB_MaxStep; // max. step
203 extern double SIMLIB_StepSize; // actual step
204 
205 extern double SIMLIB_AbsoluteError; // absolute error tolerance
206 extern double SIMLIB_RelativeError; // relative error
207 
208 extern double SIMLIB_StartTime; // time of simulation start
209 extern double SIMLIB_Time; // simulation time
210 extern double SIMLIB_NextTime; // next-event time
211 extern double SIMLIB_EndTime; // time of simulation end
212 
213 // TODO: move to context (public methods with prefix calendar::?)
214 
215 //! Special namespace for calendar implementation.
216 //!
217 //! This is for internal use only.
218 namespace SQS {
219  void ScheduleAt(Entity *e, double t);// time t
220  Entity *GetFirst(); // remove first item
221  void Get(Entity *e); // remove entity e
222  bool Empty(); // ?empty calendar
223  void Clear(); // remove all items
224  int debug_print();
225 };
226 
227 /// macro for simple assignement to internal time variables
228 #define _SetTime(t,x) (SIMLIB_##t = x)
229 
230 void SIMLIB_Dynamic(); // TODO: optimize!
231 void SIMLIB_DoActions(); // dispatch events and processes
232 void SIMLIB_ContinueInit(); // initialize variables
233 void SIMLIB_DoConditions(); // perform state events
234 void SIMLIB_WUClear(); // clear WUList
235 
236 
237 //////////////////////////////////////////////////////////////////////////
238 // MACROS --- Hooks into simulation control algorithm
239 //
240 // we use static pointers to void function()
241 // function can be installed by calling INSTALL_HOOK(hook_name,function)
242 // used mainly in run.cc
243 
244 // definition of hook-pointer-variable name and hook-install-function name
245 // the names are internal and _can_ be changed here:
246 #define HOOK_PTR_NAME(id) SIMLIB_Hook_Ptr_##id
247 #define HOOK_INST_NAME(id) SIMLIB_Install_hook_##id
248 
249 /////////////////////////////////////////////////////////////////////////////
250 // INSTALL_HOOK --- macro for hook function installation
251 // parameters:
252 // name of hook
253 // function to install as hook -- prototype should be: void f();
254 //
255 #define INSTALL_HOOK(name,function) do {\
256  void HOOK_INST_NAME(name) (void (*f)()); /* prototype */ \
257  HOOK_INST_NAME(name)(function); /* call of installer */ \
258  }while (0)
259 
260 
261 /////////////////////////////////////////////////////////////////////////////
262 // DEFINE_HOOK --- macro for hook definition
263 // parameter:
264 // name of hook
265 // can be used at global scope
266 //
267 #define DEFINE_HOOK(name) \
268  static void (* HOOK_PTR_NAME(name) )() = 0; \
269  void HOOK_INST_NAME(name)(void (*f)()) { HOOK_PTR_NAME(name) = f; }
270 
271 
272 /////////////////////////////////////////////////////////////////////////////
273 // CALL_HOOK --- macro for checked hook calling
274 // parameter:
275 // name of hook
276 // can be used in the same module as DEFINE_HOOK (static)
277 //
278 #define CALL_HOOK(name) \
279  if( HOOK_PTR_NAME(name) ) HOOK_PTR_NAME(name) ()
280 
281 
282 ////////////////////////////////////////////////////////////////////////////
283 // auxiliary functions TODO: ### remove, use std version
284 //
285 inline double min(double a, double b) { return ((a)>(b)?(b):(a)); }
286 inline double max(double a, double b) { return ((a)>(b)?(a):(b)); }
287 
288 
289 ////////////////////////////////////////////////////////////////////////////
290 //! internal method for flag manipulation
291 /// is used for algebraic loop checking in continuous blocks
292 ///
293 inline bool SimObject::TestAndSetFlag(bool new_value, unsigned mask) {
294  bool old_value = (_flags & mask)!=0;
295  if(new_value)
296  _flags |= mask;
297  else
298  _flags &= ~mask;
299  return old_value;
300 }
301 
302 ////////////////////////////////////////////////////////////////////////////
303 //! class for algebraic loop detection
304 /// AlgLoopDetector object should be used in Value() method only
305 /// it checks for recursion in continuous block expression evaluation <br>
306 /// User should remove algebraic loop manualy using special block (see AlgLoop solvers)
309  /// begin checking for recursion in Value() calling
310  void lock() {
311  if(block->TestAndSetFlag(true,SimObject::_EVAL_FLAG)) // was evaluated
312  SIMLIB_error(AlgLoopDetected); // recursive call detected
313  }
314  /// end checking for recursion
315  void unlock() {
317  }
318  public:
319  AlgLoopDetector(aContiBlock *x): block(x) { lock(); }
320  ~AlgLoopDetector() { unlock(); }
321 };
322 
323 
324 ////////////////////////////////////////////////////////////////////////////
325 // printf-like function for creating name strings
326 std::string SIMLIB_create_tmp_name(const char *fmt, ...);
327 
328 } // namespace
329 
330 #endif //__SIMLIB__INTERNAL_H__
331 
332 // end
333 
void unlock()
end checking for recursion
Definition: internal.h:315
aContiBlock * block
Definition: internal.h:308
void SIMLIB_error(const enum _ErrEnum N)
print error message and abort program
Definition: error.cc:38
double SIMLIB_NextTime
Definition: run.cc:42
void SIMLIB_Dynamic()
performs evaluation of integrators and status blocks
Definition: continuous.cc:35
double SIMLIB_StepStartTime
last step time
Definition: intg.cc:34
double SIMLIB_ContractStep
requested step size
Definition: intg.cc:59
double SIMLIB_StartTime
Definition: run.cc:40
bool SIMLIB_ResetStatus
flag set if there is a need for integration method restart
Definition: intg.cc:86
void Get(Entity *e)
remove selected entity activation record from calendar
Definition: calendar.cc:1308
void SIMLIB_DoConditions()
Definition: cond.cc:139
bool SIMLIB_DynamicFlag
in dynamic section
Definition: intg.cc:56
AlgLoopDetector(aContiBlock *x)
Definition: internal.h:319
Implementation of class CalendarList interface is static - using global functions in SQS namespace...
Definition: algloop.cc:32
double max(double a, double b)
Definition: internal.h:286
double SIMLIB_RelativeError
relative error
Definition: intg.cc:43
int SIMLIB_ERRNO
Definition: intg.cc:32
void SIMLIB_DoActions()
Definition: run.cc:135
class for algebraic loop detection AlgLoopDetector object should be used in Value() method only it ch...
Definition: internal.h:307
const char * string
Definition: internal.h:61
void SIMLIB_warning(const enum _ErrEnum N)
print warning message and continue
Definition: error.cc:74
std::string SIMLIB_create_tmp_name(const char *fmt,...)
printf-like function to create temporary name (the length of temporary names is limited) used only ...
Definition: name.cc:80
abstract base class for active entities (Process, Event) instances of derived classes provide Behavio...
Definition: simlib.h:375
unsigned long SIMLIB_debug_flag
Definition: debug.cc:32
double SIMLIB_StepSize
actual step
Definition: intg.cc:40
Test t(F)
void ScheduleAt(Entity *e, double t)
schedule entity e at given time t using scheduling priority from e
Definition: calendar.cc:1287
double min(double a, double b)
Definition: internal.h:285
abstract base for continuous blocks with single output suitable for expression-tree building and eval...
Definition: simlib.h:832
double SIMLIB_EndTime
Definition: run.cc:43
double SIMLIB_AbsoluteError
absolute error
Definition: intg.cc:42
int Init(const char *s)
Definition: atexit.cc:56
const SIMLIB_Phase_t & Phase
This variable contains the current phase of experiment (used for internal checking) ...
Definition: run.cc:58
Entity * GetFirst()
remove entity with minimum activation time
Definition: calendar.cc:1327
SIMLIB_module & operator=(const SIMLIB_module &)
bool SIMLIB_ContractStepFlag
requests shorter step
Definition: intg.cc:58
_ErrEnum
Definition: errors.cc:10
void SIMLIB_ContinueInit()
Definition: intg.cc:125
double SIMLIB_Time
Definition: internal.h:209
static SIMLIB_module SIMLIB_module_id
Create single global registration object in each SIMLIB module.
Definition: internal.h:73
bool Empty()
empty calendar predicate
Definition: calendar.cc:1280
Entity * SIMLIB_Current
Definition: run.cc:53
SIMLIB_Phase_t
values indicate current phase of experiment
Definition: internal.h:76
bool TestAndSetFlag(bool new_value, unsigned n)
internal method for flag manipulation is used for algebraic loop checking in continuous blocks ...
Definition: internal.h:293
bool SIMLIB_ConditionFlag
Definition: cond.cc:30
void lock()
begin checking for recursion in Value() calling
Definition: internal.h:310
double SIMLIB_MinStep
minimal step
Definition: intg.cc:38
SIMLIB_Phase_t SIMLIB_Phase
Definition: run.cc:57
double SIMLIB_DeltaTime
Time-SIMLIB_StepStartTime.
Definition: intg.cc:35
void(* SIMLIB_atexit_function_t)()
Definition: internal.h:150
int debug_print()
Definition: calendar.cc:1351
void SIMLIB_WUClear()
Definition: run.cc:123
Class for internal registration of modules.
Definition: internal.h:60
void SIMLIB_atexit(SIMLIB_atexit_function_t p)
Definition: atexit.cc:26
void(* VoidFunctionPtr)()
Definition: internal.h:177
double SIMLIB_OptStep
optimal step
Definition: intg.cc:37
_ErrEnum
Definition: errors.h:9
void Clear()
remove all scheduled entities
Definition: calendar.cc:1346
double SIMLIB_MaxStep
max. step
Definition: intg.cc:39