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
85#define INOS_CATCH(Exception) \
86 } catch (Exception) \
87
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)
337#define DF_INOS_ASYNCHRONOUS ((CINOSSync *) 1)
344#define DF_INOS_DELEGATE ((CINOSSync *) 2)
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
385struct 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;
408 static SStructDef* m_pFirst;
409};
410
411struct 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),
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),
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),
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;
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
682void INOS_NO_INLINE DoAssert(const char* apCondition, const char* apFile, const int aiLine);
684void INOS_NO_INLINE DoAssertMsg(const char* apCondition, const char* apFile, const int aiLine, const char* apMsg, ...) INOS_FORMAT(4,5);
685
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//
870template<typename T, uint8... Values>
872
873template<typename T, uint8 First, uint8... Values>
875public:
876 static const T s_uBitmap = 1<<First | TINOSStaticBitmap<T,Values...>::s_uBitmap;
877};
878template<typename T>
880public:
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 */
912template<typename TO, typename FROM>
913inline 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);
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
CINOSMcModuleWaitObj * m_pNext
pointer to next in chain
Definition cinosmcmodule.h:1890
Definition cinosmcmodule.h:1900
#define ASSERT_ALWAYS_MSG(f, i_Msg, i_Args...)
Definition inosmacro.h:711
bool g_bThrowExceptionOnAssert
The type definition file.
Definition inosmacro.h:871