INOS
inosmacro.h
Go to the documentation of this file.
1 //******************************************************************************
26 //******************************************************************************
27 
28 #if !defined( INC_INOSMACRO_H )
29 #define INC_INOSMACRO_H
30 
31 //------------------------------------------------------------------------------
32 // includes
33 //------------------------------------------------------------------------------
34 
35 #include <inostype.h>
36 
37 //------------------------------------------------------------------------------
38 // macros
39 //------------------------------------------------------------------------------
40 
51 #define LOAD_SETBE16(address, value) inos_setbe16((uint16*)address, value)
52 
57 #define LOAD_GETBE16(address) inos_getbe16((uint16*)address)
58 
63 #define LOAD_SETBE32(address, value) inos_setbe32((uint32*)address, value)
64 
69 #define LOAD_GETBE32(address) inos_getbe32((uint32*)address)
70 
71 //------------------------------------------------------------------------------
72 // CPP exception macros
73 //------------------------------------------------------------------------------
74 
75 #ifdef INOS_CPP_EXCEPTION_SUPPORT
76 
79 #define INOS_TRY \
80  try { \
81  SINOSExceptionGuard __inosTryGuard; \
82 
83 
85 #define INOS_CATCH(Exception) \
86  } catch (Exception) \
87 
88 
97 #ifdef _MSC_VER
98 #define INOS_THROW(ExceptionClass, ... ) \
99  { ExceptionClass __inosEx(__VA_ARGS__); __inosEx.OnThrow(__FILE__, __LINE__); throw __inosEx; }
100 #else
101 #define INOS_THROW(ExceptionClass, args... ) \
102  { ExceptionClass __inosEx(args); __inosEx.OnThrow(__FILE__, __LINE__); throw __inosEx; }
103 #endif
104 #else
105 
108 #define INOS_TRY \
109  static_assert(0, "One needs to enable C++ Exception feature to use this macro");
110 
113 #define INOS_CATCH(Exception) \
114  static_assert(0, "One needs to enable C++ Exception feature to use this macro");
115 
118 #define INOS_THROW(ExceptionClass, args... ) \
119  static_assert(0, "One needs to enable C++ Exception feature to use this macro");
120 
121 #endif
122 
123 //------------------------------------------------------------------------------
124 // enum X macros
125 //------------------------------------------------------------------------------
141 #define INOS_DEFINE_ENUM_CODE_X(id, code, ...) id = code,
142 #define INOS_DEFINE_ENUM_CODE(defines, ...) \
143  enum __VA_ARGS__ { \
144  defines(INOS_DEFINE_ENUM_CODE_X) \
145  };
146 
147 /* \brief X Macro to create a combo data string from an emum or definition list */
148 #define INOS_DEFINE_COMBO_DATA_X(id, code, ...) #code";"#id";"
149 #define INOS_DEFINE_COMBO_DATA(defines, ...) defines(INOS_DEFINE_COMBO_DATA_X)
150 
151 
152 //------------------------------------------------------------------------------
153 // MISC macros
154 //------------------------------------------------------------------------------
155 
156 #if INOS_BYTE_ORDER == INOS_LITTLE_ENDIAN
157 #define INOS_HW_WRITE8(address, value) \
158  *((volatile uint8*)((uintptr)(address)^1)) = (value);
159 #define INOS_HW_READ8(address) \
160  *((volatile uint8*)((uintptr)(address)^1))
161 #define INOS_HW_ADDR8(address) \
162  ((uint8*)((uintptr)(address)^1))
163 #define INOS_HW_WRITE16(address, value) \
164  *((volatile uint16*)((uintptr)(address)^2)) = (value);
165 #define INOS_HW_READ16(address) \
166  *((volatile uint16*)((uintptr)(address)^2))
167 #define INOS_HW_ADDR16(address) \
168  ((uint16*)((uintptr)(address)^2))
169 #else
170 #define INOS_HW_WRITE8(address, value) \
171  *((volatile uint8*)(address)) = (value);
172 #define INOS_HW_READ8(address) \
173  *((volatile uint8*)(address))
174 #define INOS_HW_ADDR8(address) \
175  ((uint8*)(address))
176 #define INOS_HW_WRITE16(address, value) \
177  *((volatile uint16*)(address)) = (value);
178 #define INOS_HW_READ16(address) \
179  *((volatile uint16*)(address))
180 #define INOS_HW_ADDR16(address) \
181  ((uint16*)(address))
182 #endif
183 #define INOS_HW_WRITE32(address, value) \
184  *((volatile uint32*)((uintptr)(address))) = (value);
185 #define INOS_HW_READ32(address) \
186  *((volatile uint32*)((uintptr)(address)))
187 #define INOS_HW_ADDR32(address) \
188  ((volatile uint32*)((uintptr)(address)))
189 
190 #if !defined(INOS_MULTICORE) || defined(_MSC_VER)
191 
192  // Implementation note: At least on certain platforms, it could theoretically
193  // make sense to always use the 'multi core' implementation below. But to
194  // follow the "never change a running system" rule, I decided to leave this
195  // implementation intact for non-multi-core systems - and therefore only
196  // change the implementation of 'symmetric multi core systems', which are
197  // of limited spread at this time.
198 
201  #define INOS_OR(variable, mask) \
202  { \
203  uint32 __msr__ = INOSDisableInterrupts(); \
204  variable |= (mask); \
205  INOSEnableInterrupts(__msr__); \
206  }
207 
210  #define INOS_AND(variable, mask) \
211  { \
212  uint32 __msr__ = INOSDisableInterrupts(); \
213  variable &= (mask); \
214  INOSEnableInterrupts(__msr__); \
215  }
216 
220  #define INOS_ADD(variable, value) \
221  { \
222  uint32 __msr__ = INOSDisableInterrupts(); \
223  variable += (value); \
224  INOSEnableInterrupts(__msr__); \
225  }
226 
229  #define INOS_SET(variable, value) \
230  { \
231  uint32 __msr__ = INOSDisableInterrupts(); \
232  variable = (value); \
233  INOSEnableInterrupts(__msr__); \
234  }
235 
236  #define INOS_SET_8 INOS_SET
237 
238  #define INOS_SET_MB(variable, value) \
239  INOSMemoryBarrier(); \
240  variable = (value); \
241  INOSMemoryBarrier();
242 
243 #else
244 
245  // Implementation note: The macros are enclosed in brackets '{ ... }' to
246  // prevent code, using these macros, from storing the returned value. This
247  // seems to make sense to ensure that these macros behave the same ways as
248  // the non-multi-core ones, to ensure 'cross compilation' of the user code.
249  //
250  // Note: From respect to the C++11 memory model, these operation just
251  // guarantee to be 'atomic', but they don't guarantee ordering
252  // across CPUs, means: They do NOT guarantee that all previously
253  // performed store operations are 'sync out' (msync & co), which
254  // clearly improves performance. Manually sync (e.g. using a
255  // std::atomic_thread_fence(...) if required. But what they DO
256  // guarantee is that they won't be reordered by the compiler,
257  // thus the usage of an "optimization barrier". The latter is
258  // guaranteed because I assume that the non-SMP versions (see
259  // above) also caused this as a side effect of the 'volatile asm'
260  // statements used by INOSDisableInterrupts. Thus, I expected the
261  // least "behavioral change" for existing code. But this assumption
262  // has not been proven and may be wrong.
263 
273  #define INOS_OR(variable, mask) { \
274  INOSOptimizationBarrier(); \
275  __atomic_or_fetch(&variable, mask, __ATOMIC_RELAXED); \
276  INOSOptimizationBarrier(); \
277  }
278 
280  #define INOS_AND(variable, mask) { \
281  INOSOptimizationBarrier(); \
282  __atomic_and_fetch(&variable, mask, __ATOMIC_RELAXED); \
283  INOSOptimizationBarrier(); \
284  }
285 
289  #define INOS_ADD(variable, value) { \
290  INOSOptimizationBarrier(); \
291  __atomic_add_fetch(&variable, value, __ATOMIC_RELAXED); \
292  INOSOptimizationBarrier(); \
293  }
294 
296  #define INOS_SET(variable, value) { \
297  INOSOptimizationBarrier(); \
298  __atomic_store_n(&variable, value, __ATOMIC_RELAXED); \
299  INOSOptimizationBarrier(); \
300  }
301 
306  #define INOS_SET_8(variable, value) { \
307  INOSOptimizationBarrier(); \
308  __atomic_store(&variable, &value, __ATOMIC_RELAXED); \
309  INOSOptimizationBarrier(); \
310  }
311 
318  #define INOS_SET_MB(variable, value) \
319  INOSMemoryBarrier(); \
320  INOS_SET(variable, value); \
321  INOSMemoryBarrier();
322 
323 #endif
324 
326 #define INOS_ADD_ INOS_ADD
327 
332 #define DF_INOS_SYNCHRONOUS ((CINOSSync *) 0)
333 
337 #define DF_INOS_ASYNCHRONOUS ((CINOSSync *) 1)
338 
344 #define DF_INOS_DELEGATE ((CINOSSync *) 2)
345 
349 #define DF_INOS_SYNCH_LAST ((CINOSSync *) 2)
350 //
351 #define DF_INOS_LOG_TRIGGER_TYPE_TESTPOINT uint8(0)
352 #define DF_INOS_LOG_TRIGGER_TYPE_OVERRUN uint8(1)
353 #define DF_INOS_LOG_TRIGGER_TYPE_POSTOVERRUN uint8(2)
354 #define DF_INOS_LOG_TRIGGER_TYPE_TASK uint8(3)
355 #define DF_INOS_LOG_TRIGGER_TYPE_VARLOG uint8(4)
356 #define DF_INOS_LOG_TRIGGER_TYPE_USER uint8(5)
357 #define DF_INOS_LOG_TRIGGER_TYPE_UNKNOWN uint8(255)
358 #define DF_INOS_LOG_SINGLE uint8(0)
359 #define DF_INOS_LOG_ENDLESS uint8(1)
360 
361 // --- locking cache -----------------------------------------------------------
362 
363 #ifdef INOS_CACHE_LOCK_SUPPORT
364 #define ICACHE __attribute__ ((section (".icache")))
365 #define DCACHE __attribute__ ((section (".dcache")))
366 #else
367 #define ICACHE
368 #define DCACHE
369 #endif
370 
371 // --- critical irq support ----------------------------------------------------
372 
373 #ifdef INOS_CRITICAL_SUPPORT
374 #define ICRITICAL __attribute__ ((section (".icritical")))
375 #define DCRITICAL __attribute__ ((section (".dcritical")))
376 #else
377 #define ICRITICAL
378 #define DCRITICAL
379 #endif
380 
381 // --- database table structure registration -----------------------------------
382 
383 #if defined(INOS_DESKTOP) || defined(INOS_64)
384 
385 struct SStructDef
386 {
387  // constructor
388  SStructDef(const char* apName, const char* apBaseName, uint32 auSize)
389  : m_pName(apName), m_pBaseName(apBaseName), m_uSize(auSize)
390  {
391  m_pNext = m_pFirst;
392  m_pFirst = this;
393  };
394  // get pointer to first
395  static SStructDef* GetFirst()
396  {
397  return m_pFirst;
398  };
399  // get pointer to next in list
400  SStructDef* GetNext() const
401  {
402  return m_pNext;
403  };
404  const char* m_pName;
405  const char* m_pBaseName;
406  uint32 m_uSize;
407  SStructDef* m_pNext;
408  static SStructDef* m_pFirst;
409 };
410 
411 struct SStructColumnDef
412 {
413  // constructor
414  SStructColumnDef(SStructDef* apStruct, const char* apName, uint32 auType, uint32 auOffset,
415  uint32 auArrayLength, int64 aValue)
416  : m_pName(apName), m_uType(auType), m_uOffset(auOffset),
417  m_uArrayLength(auArrayLength), m_pStruct(apStruct)
418  {
419  m_Default.i = aValue;
420  m_pNext = m_pFirst;
421  m_pFirst = this;
422  };
423  SStructColumnDef(SStructDef* apStruct, const char* apName, uint32 auType, uint32 auOffset,
424  uint32 auArrayLength, uint64 aValue)
425  : m_pName(apName), m_uType(auType), m_uOffset(auOffset),
426  m_uArrayLength(auArrayLength), m_pStruct(apStruct)
427  {
428  m_Default.u = aValue;
429  m_pNext = m_pFirst;
430  m_pFirst = this;
431  };
432  SStructColumnDef(SStructDef* apStruct, const char* apName, uint32 auType, uint32 auOffset,
433  uint32 auArrayLength, double aValue)
434  : m_pName(apName), m_uType(auType), m_uOffset(auOffset),
435  m_uArrayLength(auArrayLength), m_pStruct(apStruct)
436  {
437  m_Default.d = aValue;
438  m_pNext = m_pFirst;
439  m_pFirst = this;
440  };
441  // get pointer to first
442  static SStructColumnDef* GetFirst()
443  {
444  return m_pFirst;
445  };
446  // get pointer to next in list
447  SStructColumnDef* GetNext() const
448  {
449  return m_pNext;
450  };
451  const char* m_pName;
452  uint32 m_uType;
453  uint32 m_uOffset;
454  uint32 m_uArrayLength;
455  union {
456  int64 i;
457  uint64 u;
458  double d;
459  } m_Default;
460  SStructDef* m_pStruct;
461  SStructColumnDef* m_pNext;
462  static SStructColumnDef* m_pFirst;
463 };
464 
465 #define DECLARE_STRUCT_BEGIN(aStructName, aTableName, aBaseTable) \
466  char aStructName##tablename[] = aTableName; \
467  char aStructName##basetable[] = aBaseTable; \
468  SStructDef aStructName##_desc ( \
469  (char *)&aStructName##tablename, \
470  (char *)&aStructName##basetable, \
471  sizeof(aStructName) \
472  );
473 #define DECLARE_STRUCT_END(aStructName)
474 
475 // offsetof is undefined on non-POD types (specifically occurring here: ones
476 // with a virtual destructor), however in cases where it actually does not work
477 // (e.g. virtual inheritance), this has never worked, so suppressing the
478 // warning seems okay.
479 // GCC < 13 has a bug where diagnostic pragmas inside macros are ignored
480 // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578), so in that case disable
481 // the warning globally from here on.
482 #if defined(__GNUC__) && __GNUC__ < 13
483 #pragma GCC diagnostic ignored "-Winvalid-offsetof"
484 #endif
485 #define DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, aType, aSize, aValue) \
486  _Pragma("GCC diagnostic push") \
487  _Pragma("GCC diagnostic ignored \"-Winvalid-offsetof\"") \
488  char aStructName##aMemberName##name[] = aPublicName; \
489  SStructColumnDef aStructName##aMemberName##_desc ( \
490  &aStructName##_desc, \
491  (char *) &aStructName##aMemberName##name, \
492  aType, \
493  (uintptr) offsetof(aStructName, aMemberName), \
494  aSize, \
495  aValue); \
496  _Pragma("GCC diagnostic pop")
497 #define DECLARE_STRUCT_INT8(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
498  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_int8, aArrayLength, (int64) aValue)
499 #define DECLARE_STRUCT_UINT8(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
500  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_uint8, aArrayLength, (uint64) aValue)
501 #define DECLARE_STRUCT_INT16(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
502  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_int16, aArrayLength, (int64) aValue)
503 #define DECLARE_STRUCT_UINT16(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
504  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_uint16, aArrayLength, (uint64) aValue)
505 #define DECLARE_STRUCT_UINT16_NOCHECK(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
506  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_uint16, aArrayLength, (uint64) aValue)
507 #define DECLARE_STRUCT_INT32(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
508  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_int32, aArrayLength, (int64) aValue)
509 #define DECLARE_STRUCT_UINT32(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
510  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_uint32, aArrayLength, (uint64) aValue)
511 #define DECLARE_STRUCT_INT64(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
512  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_int64, aArrayLength, (int64) aValue)
513 #define DECLARE_STRUCT_UINT64(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
514  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_uint64, aArrayLength, (uint64) aValue)
515 #define DECLARE_STRUCT_FLOAT(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
516  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_float, aArrayLength, (double) aValue)
517 #define DECLARE_STRUCT_DOUBLE(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
518  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_double, aArrayLength, (double) aValue)
519 #define DECLARE_STRUCT_REAL32(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
520  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_real32, aArrayLength, (double) aValue)
521 #define DECLARE_STRUCT_REAL64(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
522  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_real64, aArrayLength, (double) aValue)
523 #define DECLARE_STRUCT_FIXED32(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
524  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_fixed32, aArrayLength, (double) aValue)
525 #define DECLARE_STRUCT_FIXED64(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
526  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_fixed64, aArrayLength, (double) aValue)
527 #define DECLARE_STRUCT_STRING(aStructName, aPublicName, aMemberName, aValue) \
528  char aStructName##aMemberName##value[] = aValue; \
529  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_string, sizeof(aStructName::aMemberName), (uint64) &aStructName##aMemberName##value)
530 #define DECLARE_STRUCT_CHAR(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
531  char aStructName##aMemberName##value[aArrayLength] = aValue;\
532  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_string, aArrayLength, (uint64) &aStructName##aMemberName##value)
533 #define DECLARE_STRUCT_FILE(aStructName, aPublicName, aMemberName, aValue) \
534  char aStructName##aMemberName##value[] = aValue; \
535  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_file, sizeof(aStructName::aMemberName), (uint64) &aStructName##aMemberName##value)
536 #define DECLARE_STRUCT_BINARY(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
537  char aStructName##aMemberName##value[aArrayLength] = aValue;\
538  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_binary, aArrayLength, (uint64) &aStructName##aMemberName##value)
539 #else // end if defined(INOS_DESKTOP)
540 #define STRUCT_DEF __attribute__ ((section (".struct_def"))) __attribute__ ((unused))
541 #define STRUCT_NAM __attribute__ ((section (".struct_nam")))
542 
543 #define DECLARE_STRUCT_BEGIN(aStructName, aTableName, aBaseTable) \
544  STRUCT_NAM char aStructName##tablename[] = aTableName; \
545  STRUCT_NAM char aStructName##basetable[] = aBaseTable; \
546  STRUCT_DEF char* aStructName##ptablename = (char *) &aStructName##tablename; \
547  STRUCT_DEF char* aStructName##pbasetable = (char *) &aStructName##basetable; \
548  STRUCT_DEF uint32 aStructName##size = sizeof(aStructName); \
549  STRUCT_DEF uint32 aStructName##align1 = 0;
550 
551 #define DECLARE_STRUCT_END(aStructName) \
552  STRUCT_DEF uint32 aStructName##end = 0; \
553  STRUCT_DEF uint32 aStructName##align2 = 0;
554 
555 #define DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, aType, aSize) \
556  STRUCT_NAM char aStructName##aMemberName##name[] = aPublicName; \
557  STRUCT_DEF char* aStructName##aMemberName##pname = (char *) &aStructName##aMemberName##name;\
558  STRUCT_DEF uint32 aStructName##aMemberName##type = aType; \
559  STRUCT_DEF uint32 aStructName##aMemberName##offset = (uintptr) &((aStructName *)0x100)->aMemberName - 0x100; \
560  STRUCT_DEF uint32 aStructName##aMemberName##size = aSize;
561 
562 #define DECLARE_STRUCT_INT8(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
563  static_assert((sizeof(aStructName::aMemberName) == sizeof(int8)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(int8))), "Detected type mismatch registering struct member for dt2"); \
564  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_int8, aArrayLength) \
565  STRUCT_DEF int64 aStructName##aMemberName##value = aValue;
566 #define DECLARE_STRUCT_UINT8(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
567  static_assert((sizeof(aStructName::aMemberName) == sizeof(uint8)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(uint8))), "Detected type mismatch registering struct member for dt2"); \
568  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_uint8, aArrayLength) \
569  STRUCT_DEF uint64 aStructName##aMemberName##value = aValue;
570 #define DECLARE_STRUCT_INT16(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
571  static_assert((sizeof(aStructName::aMemberName) == sizeof(int16)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(int16))), "Detected type mismatch registering struct member for dt2"); \
572  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_int16, aArrayLength) \
573  STRUCT_DEF int64 aStructName##aMemberName##value = aValue;
574 #define DECLARE_STRUCT_UINT16(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
575  static_assert((sizeof(aStructName::aMemberName) == sizeof(uint16)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(uint16))), "Detected type mismatch registering struct member for dt2"); \
576  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_uint16, aArrayLength) \
577  STRUCT_DEF uint64 aStructName##aMemberName##value = aValue;
578 #define DECLARE_STRUCT_UINT16_NOCHECK(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
579  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_uint16, aArrayLength) \
580  STRUCT_DEF uint64 aStructName##aMemberName##value = aValue;
581 #define DECLARE_STRUCT_INT32(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
582  static_assert((sizeof(aStructName::aMemberName) == sizeof(int32)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(int32))), "Detected type mismatch registering struct member for dt2"); \
583  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_int32, aArrayLength) \
584  STRUCT_DEF int64 aStructName##aMemberName##value = aValue;
585 #define DECLARE_STRUCT_UINT32(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
586  static_assert((sizeof(aStructName::aMemberName) == sizeof(uint32)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(uint32))), "Detected type mismatch registering struct member for dt2"); \
587  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_uint32, aArrayLength) \
588  STRUCT_DEF uint64 aStructName##aMemberName##value = aValue;
589 #define DECLARE_STRUCT_INT64(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
590  static_assert((sizeof(aStructName::aMemberName) == sizeof(int64)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(int64))), "Detected type mismatch registering struct member for dt2"); \
591  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_int64, aArrayLength) \
592  STRUCT_DEF int64 aStructName##aMemberName##value = aValue;
593 #define DECLARE_STRUCT_UINT64(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
594  static_assert((sizeof(aStructName::aMemberName) == sizeof(uint64)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(uint64))), "Detected type mismatch registering struct member for dt2"); \
595  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_uint64, aArrayLength) \
596  STRUCT_DEF uint64 aStructName##aMemberName##value = aValue;
597 #define DECLARE_STRUCT_FLOAT(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
598  static_assert((sizeof(aStructName::aMemberName) == sizeof(float)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(float))), "Detected type mismatch registering struct member for dt2"); \
599  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_float, aArrayLength) \
600  STRUCT_DEF double aStructName##aMemberName##value = aValue;
601 #define DECLARE_STRUCT_DOUBLE(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
602  static_assert((sizeof(aStructName::aMemberName) == sizeof(double)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(double))), "Detected type mismatch registering struct member for dt2"); \
603  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_double, aArrayLength) \
604  STRUCT_DEF double aStructName##aMemberName##value = aValue;
605 #define DECLARE_STRUCT_REAL32(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
606  static_assert((sizeof(aStructName::aMemberName) == sizeof(real32)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(real32))), "Detected type mismatch registering struct member for dt2"); \
607  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_real32, aArrayLength) \
608  STRUCT_DEF double aStructName##aMemberName##value = aValue;
609 #define DECLARE_STRUCT_REAL64(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
610  static_assert((sizeof(aStructName::aMemberName) == sizeof(real64)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(real64))), "Detected type mismatch registering struct member for dt2"); \
611  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_real64, aArrayLength) \
612  STRUCT_DEF double aStructName##aMemberName##value = aValue;
613 #define DECLARE_STRUCT_FIXED32(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
614  static_assert((sizeof(aStructName::aMemberName) == sizeof(fixed32)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(fixed32))), "Detected type mismatch registering struct member for dt2"); \
615  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_fixed32, aArrayLength) \
616  STRUCT_DEF double aStructName##aMemberName##value = aValue;
617 #define DECLARE_STRUCT_FIXED64(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
618  static_assert((sizeof(aStructName::aMemberName) == sizeof(fixed64)) || (sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(fixed64))), "Detected type mismatch registering struct member for dt2"); \
619  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_fixed64, aArrayLength) \
620  STRUCT_DEF double aStructName##aMemberName##value = aValue;
621 #define DECLARE_STRUCT_STRING(aStructName, aPublicName, aMemberName, aValue) \
622  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_string, sizeof(((aStructName *)0)->aMemberName))\
623  STRUCT_NAM char aStructName##aMemberName##value[] = aValue;\
624  STRUCT_DEF char* aStructName##aMemberName##pvalue = (char *) &aStructName##aMemberName##value;\
625  STRUCT_DEF uint32 aStructName##aMemberName##dummy = 0;
626 #define DECLARE_STRUCT_CHAR(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
627  static_assert(sizeof(aStructName::aMemberName) == (aArrayLength * sizeof(char)), "Detected type mismatch registering struct member for dt2"); \
628  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_string, aArrayLength)\
629  STRUCT_NAM char aStructName##aMemberName##value[aArrayLength] = aValue;\
630  STRUCT_DEF char* aStructName##aMemberName##pvalue = (char *) &aStructName##aMemberName##value;\
631  STRUCT_DEF uint32 aStructName##aMemberName##dummy = 0;
632 #define DECLARE_STRUCT_FILE(aStructName, aPublicName, aMemberName, aValue) \
633  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_file, sizeof(((aStructName *)0)->aMemberName))\
634  STRUCT_NAM char aStructName##aMemberName##value[] = aValue;\
635  STRUCT_DEF char* aStructName##aMemberName##pvalue = (char *) &aStructName##aMemberName##value;\
636  STRUCT_DEF uint32 aStructName##aMemberName##dummy = 0;
637 #define DECLARE_STRUCT_BINARY(aStructName, aPublicName, aMemberName, aValue, aArrayLength) \
638  DECLARE_STRUCT_MEMBER(aStructName, aPublicName, aMemberName, defType_binary, aArrayLength)\
639  STRUCT_NAM char aStructName##aMemberName##value[aArrayLength] = aValue;\
640  STRUCT_DEF char* aStructName##aMemberName##pvalue = (char *) &aStructName##aMemberName##value;\
641  STRUCT_DEF uint32 aStructName##aMemberName##dummy = 0;
642 #endif // not INOS_DESKTOP
643 
644 #ifdef _MSC_VER
645  #define INOS_LIKELY(x) (x)
646  #define INOS_UNLIKELY(x) (x)
647  #define INOS_NO_INLINE
648  #define INOS_FORMAT(a,b)
649  #define INOS_COMPILE_OPTIMIZED
650 #else
651  #define INOS_LIKELY(x) __builtin_expect(!!(x), 1)
652  #define INOS_UNLIKELY(x) __builtin_expect(!!(x), 0)
653  #define INOS_NO_INLINE __attribute__ ((noinline))
654  #if defined(INOS_WINDOWS)
655  #define INOS_FORMAT(a,b)
656  #else
657  #define INOS_FORMAT(a,b) __attribute__ ((format (printf, a, b)))
658  #endif
659  #if defined(__clang__)
660  #define INOS_COMPILE_OPTIMIZED
661  #define INOS_COMPILE_NONOPTIMIZED __attribute__ ((optnone))
662  #else
663  #define INOS_COMPILE_OPTIMIZED __attribute__((optimize("-O2")))
664  #define INOS_COMPILE_NONOPTIMIZED __attribute__((optimize("-O0")))
665  #endif
666  #if defined(INOS_OCRAM_SUPPORT)
667  #define INOS_OCRAM __attribute__((section(".ocram")))
668  #define INOS_OCRAM_DATA __attribute__((section(".ocramdata")))
669  extern char __OCRAM_START[];
670  extern uintnbr __ocrambgn;
671  #define INOS_OCRAM_ADDR(var) (void*) ((uintptr) &var - reinterpret_cast<uintptr>(__OCRAM_START) + __ocrambgn)
672  #else
673  #define INOS_OCRAM
674  #define INOS_OCRAM_DATA
675  #endif
676 #endif
677 
682 void INOS_NO_INLINE DoAssert(const char* apCondition, const char* apFile, const int aiLine);
684 void INOS_NO_INLINE DoAssertMsg(const char* apCondition, const char* apFile, const int aiLine, const char* apMsg, ...) INOS_FORMAT(4,5);
685 
691 extern bool g_bThrowExceptionOnAssert;
692 
696 #define ASSERT_ALWAYS(f) \
697  if (INOS_UNLIKELY(!(f))){ \
698  DoAssert(#f, __FILE__, __LINE__); \
699  }
700 
705 #ifdef _MSC_VER
706  #define ASSERT_ALWAYS_MSG(f, i_Msg, ...) \
707  if( INOS_UNLIKELY(!(f)) ) { \
708  DoAssertMsg(#f, __FILE__, __LINE__, i_Msg, __VA_ARGS__); \
709  }
710 #else
711  #define ASSERT_ALWAYS_MSG(f, i_Msg, i_Args...) \
712  if( INOS_UNLIKELY(!(f)) ) { \
713  DoAssertMsg(#f, __FILE__, __LINE__, i_Msg, ##i_Args); \
714  }
715 #endif
716 
717 #ifdef _DEBUG
718  #define ASSERT(f) \
719  if (INOS_UNLIKELY(!(f))){ \
720  DoAssert(#f, __FILE__, __LINE__); \
721  }
722 #else // _DEBUG
723  #define ASSERT(f) ((void)0)
724 #endif // !_DEBUG
725 
726 #ifdef INOS_CONCURRENCY_CHECK
727 //------------------------------------------------------------------------------
728 //--- class CINOSConcurrencyCheck ----------------------------------------------
729 //------------------------------------------------------------------------------
730 //
736 //
737 //
738 // include concurrency check
739 #include "cinosconcurrencycheck.h"
740 
743 #define INOS_CONCURRENCY_CHECK_DECLARE CINOSConcurrencyCheck m_ConcurrencyCheck;
744 
749 #define INOS_CONCURRENCY_CHECK_CLAIM(ref) (ref)->m_ConcurrencyCheck.Claim();
750 
756 #define INOS_CONCURRENCY_CHECK_FREE(ref) (ref)->m_ConcurrencyCheck.Free();
757 
758 #else
759 
760 #define INOS_CONCURRENCY_CHECK_DECLARE
761 #define INOS_CONCURRENCY_CHECK_CLAIM(Check)
762 #define INOS_CONCURRENCY_CHECK_FREE(Check)
763 
764 #endif
765 
769 
775 #if defined(INOS_TESTING) and !defined(INOS_DESKTOP)
776  #define INOS_TESTING_INTERRUPTION_POINT Relinquish();
777 #else
778  #define INOS_TESTING_INTERRUPTION_POINT
779 #endif
780 
781 /* define by INOS for historical reasons: prior C++11, there was no
782  static_assert and therefore INOS defined this macro. Now that C++11 provides
783  it, INOS still provides this macro for backward compatibility. New code should
784  prefer C++11 static_assert over this macro.
785  */
786 #define STATIC_ASSERT(e, msg) \
787  static_assert(e, #msg);
788 
789 // make a sizeof for a struct member, sizeof(aClass::aMember) is not allowed anymore
790 #define sizeofm(aClass, aMember) sizeof(((aClass*)0x100)->aMember)
791 // make a offsetof that accepts classes, offsetof(aClass::aMember) only works for POD
792 #define inos_offsetof(aClass, aMember) (uintnbr)((char*)&(((aClass*)0x100)->aMember)-(char*)0x100)
793 
794 #if !defined(INOS_DESKTOP)
795 
796 /*
797  * single-evaluated MIN/MAX macros
798  * based on https://stackoverflow.com/questions/3437404/min-and-max-in-c
799  */
800 #define INOS_MIN(a, b) ({ \
801  __typeof__ (a) _a = (a); \
802  __typeof__ (b) _b = (b); \
803  _a < _b ? _a : _b; \
804 })
805 
806 #define INOS_MAX(a, b) ({ \
807  __typeof__ (a) _a = (a); \
808  __typeof__ (b) _b = (b); \
809  _a > _b ? _a : _b; \
810 })
811 
812 #else
813 
814 /*
815  * poor man's MIN/MAX macros (due to lack of typeof operator in VC++)
816  */
817 #define INOS_MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
818 #define INOS_MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
819 
820 #endif
821 
822 
824 #define INOS_STRINGIFY(x) #x
825 
826 /*
827  * macro to convert numeric literals to string.
828  *
829  * useful for compile-time concatenation.
830  * see https://stackoverflow.com/a/5459929
831  */
832 #define INOS_STR(x) INOS_STRINGIFY(x)
833 
841 #define INOS_IGNORE_WARNING(warning) \
842  _Pragma(INOS_STRINGIFY(GCC diagnostic push)) \
843  _Pragma(INOS_STRINGIFY(GCC diagnostic ignored warning))
844 #define INOS_RESTORE_WARNING \
845  _Pragma(INOS_STRINGIFY(GCC diagnostic pop))
846 
848 #define INOS_IGNORE_WARNING_DEPRECATED INOS_IGNORE_WARNING("-Wdeprecated-declarations")
849 
858 #ifndef INOS_DEPRECATED
859  #if __cplusplus >= 201402L
860  #define INOS_DEPRECATED(msg) [[deprecated(msg)]]
861  #else
862  #define INOS_DEPRECATED(msg)
863  #endif
864 #endif
865 
866 //------------------------------------------------------------------------------
867 // templates to staticly (at compile time) generate a bitmap form a list of values.
868 //------------------------------------------------------------------------------
869 //
870 template<typename T, uint8... Values>
872 
873 template<typename T, uint8 First, uint8... Values>
874 struct TINOSStaticBitmap<T, First, Values...> {
875 public:
876  static const T s_uBitmap = 1<<First | TINOSStaticBitmap<T,Values...>::s_uBitmap;
877 };
878 template<typename T>
879 struct TINOSStaticBitmap<T> {
880 public:
881  static const T s_uBitmap = 0;
882 };
883 
884 //------------------------------------------------------------------------------
885 // makros to staticly (at compile time) generate a bitmap form a list of values.
886 //------------------------------------------------------------------------------
887 // Use this makros by simply listing bit values, e.g.:
888 // STATIC_UINT8_BITMAP(0, 1, 4, 7) -> 0b10010011 -> 0x93
889 
890 #define STATIC_UINT64_BITMAP(...) (TINOSStaticBitmap<uint64,__VA_ARGS__>::s_uBitmap)
891 #define STATIC_UINT32_BITMAP(...) (TINOSStaticBitmap<uint32,__VA_ARGS__>::s_uBitmap)
892 #define STATIC_UINT16_BITMAP(...) (TINOSStaticBitmap<uint16,__VA_ARGS__>::s_uBitmap)
893 #define STATIC_UINT8_BITMAP(...) (TINOSStaticBitmap<uint8,__VA_ARGS__>::s_uBitmap)
894 
895 //------------------------------------------------------------------------------
896 // templates for safe type-casting
897 //------------------------------------------------------------------------------
898 //
899 /*
900  * this cast performs conversion between two types and checks that
901  * the value stays the same, i.e. there's no loss of precision.
902  *
903  * This is useful to convert from uint64 to uint32 under the assumption that
904  * only the lower 32-bit of the uint64 values are used, and raise an asset otherwise
905  *
906  * based on https://stackoverflow.com/questions/23830292/c-static-cast-with-assert
907  *
908  * if you get here while debugging, this probably means that you need to use
909  * "bigger" types (e.g. uint64) for the variables involved in the statement
910  * that triggered the assert.
911  */
912 template<typename TO, typename FROM>
913 inline TO checked_static_cast(const FROM& from_value)
914 {
915  TO to_value = static_cast<TO>(from_value);
916  FROM back_value = static_cast<FROM>(to_value);
917  ASSERT_ALWAYS_MSG(from_value == back_value,
918  "casting a value resulted in loss of information/precision");
919  return to_value;
920 }
921 
922 //------------------------------------------------------------------------------
923 // end of file
924 //------------------------------------------------------------------------------
925 
926 #endif // INC_INOSMACRO_H
inostype.h
The type definition file.
ASSERT_ALWAYS_MSG
#define ASSERT_ALWAYS_MSG(f, i_Msg, i_Args...)
Definition: inosmacro.h:711
g_bThrowExceptionOnAssert
bool g_bThrowExceptionOnAssert
TINOSStaticBitmap
Definition: inosmacro.h:871