////////////////////////////////////////////////////////////////////////////////
//
//  Microsoft Research Singularity
//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//
//  File:   SystemEvents.inl
//
//  Note: 
//


//  Fill in the missing macro with default empty definitions
//  This is helpful for easier maintanance of the code and macros
//  as the consummers only need to provide the definitions that they would like to handle
// 
//  NOTE: at the end of the file, all definitions are cleared
//  

#ifndef DECLARE_STRUCTURE_BEGIN
#define DECLARE_STRUCTURE_BEGIN(x,d) 
#endif

#ifndef DECLARE_STRUCTURE_END
#define DECLARE_STRUCTURE_END(x) 
#endif

#ifndef DECLARE_FIELD
#define DECLARE_FIELD(s,t,n)
#endif

#ifndef DECLARE_SPECIAL_FIELD
#define DECLARE_SPECIAL_FIELD(s,t,n)
#endif

#ifndef DECLARE_EXTENDED_ARRAY_FIELD
#define DECLARE_EXTENDED_ARRAY_FIELD(s,t,n)
#endif

#ifndef DECLARE_VALUE
#define DECLARE_VALUE(s,v,f,n)
#endif

#ifndef DECLARE_GENERIC_FIELD
#define DECLARE_GENERIC_FIELD(s,t,sz,t1,n)
#endif

#ifndef DECLARE_ENUM_BEGIN
#define DECLARE_ENUM_BEGIN(x,sz) 
#endif

#ifndef DECLARE_ENUM_END
#define DECLARE_ENUM_END(x) 
#endif

#ifdef _CONSTANT_DEFINITIONS

    #define RECORD_EVENT_METADATA_FLAG      0x8000
    #define RECORD_EVENT_TYPE_ARRAY_FLAG    0x4000

    #define RECORD_EVENT_TYPE           (RECORD_EVENT_METADATA_FLAG | 0x0100)
    #define RECORD_EVENT_FIELD          (RECORD_EVENT_METADATA_FLAG | 0x0200)
    #define RECORD_EVENT_SOURCE         (RECORD_EVENT_METADATA_FLAG | 0x0300)
    #define RECORD_EVENT_CONTROLLER     (RECORD_EVENT_METADATA_FLAG | 0x0400)
    #define RECORD_EVENT_VALUE          (RECORD_EVENT_METADATA_FLAG | 0x0800)
    #define RECORD_EVENT_GENERIC_FIELD  (RECORD_EVENT_METADATA_FLAG | 0x1000)
    #define RECORD_EVENT_ENUM           (RECORD_EVENT_METADATA_FLAG | 0x2000)

    #define GENERIC_TYPE_SIGNATURE         0x0001

#endif  // _CONSTANT_DEFINITIONS

DECLARE_STRUCTURE_BEGIN(MEMORY_HEADER, "")

    DECLARE_FIELD(MEMORY_HEADER, TYPE_uint16, Size)
    DECLARE_FIELD(MEMORY_HEADER, TYPE_uint16, Link)
    DECLARE_FIELD(MEMORY_HEADER, TYPE_uint16, Offset)
    DECLARE_FIELD(MEMORY_HEADER, TYPE_uint16, Flags)
    DECLARE_FIELD(MEMORY_HEADER, TYPE_uint64, Timestamp)
    DECLARE_FIELD(MEMORY_HEADER, TYPE_UIntPtr, Type)
    DECLARE_FIELD(MEMORY_HEADER, TYPE_uint16, TID)
    DECLARE_FIELD(MEMORY_HEADER, TYPE_uint16, Cpu)
     
DECLARE_STRUCTURE_END(MEMORY_HEADER)

DECLARE_ENUM_BEGIN(LOG_SEVERITY,TYPE_uint8)
    DECLARE_VALUE(LOG_SEVERITY, 0xe, 0, Fatal)
    DECLARE_VALUE(LOG_SEVERITY, 0xc, 0, Error)
    DECLARE_VALUE(LOG_SEVERITY, 0xa, 0, Warning)
    DECLARE_VALUE(LOG_SEVERITY, 0x8, 0, Notice)
    DECLARE_VALUE(LOG_SEVERITY, 0x6, 0, Trace)
    DECLARE_VALUE(LOG_SEVERITY, 0x4, 0, Audit)
    DECLARE_VALUE(LOG_SEVERITY, 0x2, 0, Debug)
DECLARE_ENUM_END(LOG_SEVERITY)

DECLARE_STRUCTURE_BEGIN(LOG_EXCEPTION, "Throw {0}, Handler {1}")

    DECLARE_FIELD(LOG_EXCEPTION, TYPE_UIntPtr, ThrowFrom)
    DECLARE_FIELD(LOG_EXCEPTION, TYPE_UIntPtr, Handler)
    
    DECLARE_EXTENDED_ARRAY_FIELD(LOG_EXCEPTION, TYPE_string, ExceptionName)
    
DECLARE_STRUCTURE_END(LOG_EXCEPTION)

//
//  GC profiler structures
//

DECLARE_STRUCTURE_BEGIN(GC_FUNCTION, "")

    DECLARE_FIELD(GC_FUNCTION, TYPE_uint32, FnIdx)
    DECLARE_FIELD(GC_FUNCTION, TYPE_UIntPtr, IP)
    
DECLARE_STRUCTURE_END(GC_FUNCTION)

DECLARE_STRUCTURE_BEGIN(GC_ALLOCATION, "")

    DECLARE_FIELD(GC_ALLOCATION, TYPE_uint32, TID)
    DECLARE_FIELD(GC_ALLOCATION, TYPE_uint32, StkNo)
    DECLARE_FIELD(GC_ALLOCATION, TYPE_UIntPtr, Object)
    
DECLARE_STRUCTURE_END(GC_ALLOCATION)

DECLARE_STRUCTURE_BEGIN(GC_INTERVAL, "")

    DECLARE_FIELD(GC_INTERVAL, TYPE_uint64, Delta)
    
DECLARE_STRUCTURE_END(GC_INTERVAL)

DECLARE_STRUCTURE_BEGIN(GC_TYPE, "")

    DECLARE_FIELD(GC_TYPE, TYPE_uint32, TypeId)
    DECLARE_EXTENDED_ARRAY_FIELD(GC_TYPE, TYPE_string, Name)
    
DECLARE_STRUCTURE_END(GC_TYPE)

DECLARE_STRUCTURE_BEGIN(GC_STACK, "")

    DECLARE_FIELD(GC_STACK, TYPE_uint32, StkNo)
    DECLARE_FIELD(GC_STACK, TYPE_uint32, TypeId)
    DECLARE_FIELD(GC_STACK, TYPE_uint32, Size)
    DECLARE_EXTENDED_ARRAY_FIELD(GC_STACK, TYPE_uint32, fncList)
    
DECLARE_STRUCTURE_END(GC_STACK)

DECLARE_STRUCTURE_BEGIN(GC_OBJECT, "")

    DECLARE_EXTENDED_ARRAY_FIELD(GC_OBJECT, TYPE_UIntPtr, ParameterList)
    
DECLARE_STRUCTURE_END(GC_OBJECT)

DECLARE_STRUCTURE_BEGIN(GC_GENERATIONS, "")

    DECLARE_EXTENDED_ARRAY_FIELD(GC_GENERATIONS, TYPE_int32, Genrations)
    
DECLARE_STRUCTURE_END(GC_GENERATIONS)

DECLARE_STRUCTURE_BEGIN(GC_ROOTS, "")

    DECLARE_EXTENDED_ARRAY_FIELD(GC_ROOTS, TYPE_UIntPtr, Roots)
    
DECLARE_STRUCTURE_END(GC_ROOTS)

DECLARE_STRUCTURE_BEGIN(LEGACY_LOG_ENTRY, "Log {0}:{1} {3*}")

    DECLARE_GENERIC_FIELD(LEGACY_LOG_ENTRY, TYPE_uint8, sizeof(uint8), LOG_SEVERITY, severity)
    DECLARE_FIELD(LEGACY_LOG_ENTRY, TYPE_uint16, PID)
    DECLARE_FIELD(LEGACY_LOG_ENTRY, TYPE_UIntPtr, IP)
    DECLARE_EXTENDED_ARRAY_FIELD(LEGACY_LOG_ENTRY, TYPE_string, Msg)
    DECLARE_FIELD(LEGACY_LOG_ENTRY, TYPE_UIntPtr, arg0)
    DECLARE_FIELD(LEGACY_LOG_ENTRY, TYPE_UIntPtr, arg1)
    DECLARE_FIELD(LEGACY_LOG_ENTRY, TYPE_UIntPtr, arg2)
    DECLARE_FIELD(LEGACY_LOG_ENTRY, TYPE_UIntPtr, arg3)
    DECLARE_FIELD(LEGACY_LOG_ENTRY, TYPE_UIntPtr, arg4)
    DECLARE_FIELD(LEGACY_LOG_ENTRY, TYPE_UIntPtr, arg5)
    
    DECLARE_EXTENDED_ARRAY_FIELD(LEGACY_LOG_ENTRY, TYPE_string, StrArg0)
    DECLARE_EXTENDED_ARRAY_FIELD(LEGACY_LOG_ENTRY, TYPE_string, StrArg1)
    
DECLARE_STRUCTURE_END(LEGACY_LOG_ENTRY)

DECLARE_STRUCTURE_BEGIN(MONITORING_ENTRY, "{0}:{1}:{2}:{3} - ({4},{5},{6},{7},{8})  {9}")

    DECLARE_FIELD(MONITORING_ENTRY, TYPE_uint16, PID)
    DECLARE_FIELD(MONITORING_ENTRY, TYPE_uint16, Provider)
    DECLARE_FIELD(MONITORING_ENTRY, TYPE_uint16, Type)
    DECLARE_FIELD(MONITORING_ENTRY, TYPE_uint16, version)
    DECLARE_FIELD(MONITORING_ENTRY, TYPE_uint32, arg0)
    DECLARE_FIELD(MONITORING_ENTRY, TYPE_uint32, arg1)
    DECLARE_FIELD(MONITORING_ENTRY, TYPE_uint32, arg2)
    DECLARE_FIELD(MONITORING_ENTRY, TYPE_uint32, arg3)
    DECLARE_FIELD(MONITORING_ENTRY, TYPE_uint32, arg4)
    
    DECLARE_EXTENDED_ARRAY_FIELD(MONITORING_ENTRY, TYPE_string, Text)
    
DECLARE_STRUCTURE_END(MONITORING_ENTRY)

#ifndef _LOGGING_TO_REPOSITORY

DECLARE_STRUCTURE_BEGIN(EVENT_FIELD_DESCRIPTOR, "")
    DECLARE_SPECIAL_FIELD(EVENT_FIELD_DESCRIPTOR, struct _EVENT_FIELD_DESCRIPTOR *, fieldsLink)
    DECLARE_FIELD(EVENT_FIELD_DESCRIPTOR, TYPE_uint16, Offset)
    DECLARE_FIELD(EVENT_FIELD_DESCRIPTOR, TYPE_uint16, Type)
    DECLARE_EXTENDED_ARRAY_FIELD(EVENT_FIELD_DESCRIPTOR, TYPE_string, Name)
DECLARE_STRUCTURE_END(EVENT_FIELD_DESCRIPTOR)

DECLARE_STRUCTURE_BEGIN(EVENT_GENERIC_TYPE_DESCRIPTOR, "")
    DECLARE_SPECIAL_FIELD(EVENT_GENERIC_TYPE_DESCRIPTOR, struct _EVENT_FIELD_DESCRIPTOR *, fieldsLink)
    DECLARE_FIELD(EVENT_GENERIC_TYPE_DESCRIPTOR, TYPE_uint16, Offset)
    DECLARE_FIELD(EVENT_GENERIC_TYPE_DESCRIPTOR, TYPE_uint16, Type)
    DECLARE_FIELD(EVENT_GENERIC_TYPE_DESCRIPTOR, TYPE_uint16, Size)
    DECLARE_FIELD(EVENT_GENERIC_TYPE_DESCRIPTOR, TYPE_UIntPtr, GenericTypeHandle)
    DECLARE_EXTENDED_ARRAY_FIELD(EVENT_GENERIC_TYPE_DESCRIPTOR, TYPE_string, Name)
DECLARE_STRUCTURE_END(EVENT_GENERIC_TYPE_DESCRIPTOR)

DECLARE_STRUCTURE_BEGIN(EVENT_DESCRIPTOR, "")
    DECLARE_SPECIAL_FIELD(EVENT_DESCRIPTOR, struct _EVENT_FIELD_DESCRIPTOR *, fieldsLink)
    DECLARE_FIELD(EVENT_DESCRIPTOR, TYPE_uint16, Size)
    DECLARE_EXTENDED_ARRAY_FIELD(EVENT_DESCRIPTOR, TYPE_string, Name)
    DECLARE_EXTENDED_ARRAY_FIELD(EVENT_DESCRIPTOR, TYPE_string, Description)
DECLARE_STRUCTURE_END(EVENT_DESCRIPTOR)

DECLARE_STRUCTURE_BEGIN(EVENT_VALUE_DESCRIPTOR, "")
    DECLARE_SPECIAL_FIELD(EVENT_VALUE_DESCRIPTOR, struct _EVENT_VALUE_DESCRIPTOR *, fieldsLink)
    DECLARE_FIELD(EVENT_VALUE_DESCRIPTOR, TYPE_uint8, FlagLetter)
    DECLARE_FIELD(EVENT_VALUE_DESCRIPTOR, TYPE_uint64, Value)
    DECLARE_EXTENDED_ARRAY_FIELD(EVENT_VALUE_DESCRIPTOR, TYPE_string, Name)
DECLARE_STRUCTURE_END(EVENT_VALUE_DESCRIPTOR)

DECLARE_STRUCTURE_BEGIN(ENUM_DESCRIPTOR, "")
    DECLARE_SPECIAL_FIELD(ENUM_DESCRIPTOR, struct _EVENT_VALUE_DESCRIPTOR *, fieldsLink)
    DECLARE_FIELD(ENUM_DESCRIPTOR, TYPE_uint16, Type)
    DECLARE_FIELD(ENUM_DESCRIPTOR, TYPE_uint64, FlagsMask)
    DECLARE_EXTENDED_ARRAY_FIELD(ENUM_DESCRIPTOR, TYPE_string, Name)
    DECLARE_EXTENDED_ARRAY_FIELD(ENUM_DESCRIPTOR, TYPE_string, Description)
DECLARE_STRUCTURE_END(ENUM_DESCRIPTOR)

DECLARE_STRUCTURE_BEGIN(MEMORY_ZONE, "")
    DECLARE_SPECIAL_FIELD(MEMORY_ZONE, struct _MEMORY_ZONE *, Link)
    DECLARE_SPECIAL_FIELD(MEMORY_ZONE, struct _MEMORY_ZONE *, BkLink)
    DECLARE_SPECIAL_FIELD(MEMORY_ZONE, volatile TYPE_uint32, ZoneSize)
    DECLARE_SPECIAL_FIELD(MEMORY_ZONE, ZONE_ALLOCATION_POINTER, Allocation)
    DECLARE_SPECIAL_FIELD(MEMORY_ZONE, ZONE_READY_LIST, ReadyList)
    DECLARE_FIELD(MEMORY_ZONE, TYPE_UIntPtr, StorageHandle)
    DECLARE_SPECIAL_FIELD(MEMORY_ZONE, TYPE_uint32, Generation)
    DECLARE_SPECIAL_FIELD(MEMORY_ZONE, TYPE_uint16, LastSyncPoint)
    DECLARE_SPECIAL_FIELD(MEMORY_ZONE, TYPE_uint16, Reserved)
DECLARE_STRUCTURE_END(MEMORY_ZONE)

DECLARE_STRUCTURE_BEGIN(MEMORY_STORAGE, "")
    DECLARE_SPECIAL_FIELD(MEMORY_STORAGE, struct _MEMORY_STORAGE *, Link)
    DECLARE_FIELD(MEMORY_STORAGE, TYPE_uint32, StorageSize)
    DECLARE_FIELD(MEMORY_STORAGE, TYPE_uint32, ZoneCount)
    DECLARE_FIELD(MEMORY_STORAGE, TYPE_uint16, DefaultZoneSize)
    DECLARE_FIELD(MEMORY_STORAGE, TYPE_uint32, Flags)
    DECLARE_SPECIAL_FIELD(MEMORY_STORAGE, PMEMORY_ZONE, MemoryZoneLink)
    DECLARE_SPECIAL_FIELD(MEMORY_STORAGE, PMEMORY_ZONE, BkLink)
    DECLARE_SPECIAL_FIELD(MEMORY_STORAGE, PMEMORY_ZONE, ZoneCursor)
    DECLARE_SPECIAL_FIELD(MEMORY_ZONE, TYPE_uint32, Generation)
DECLARE_STRUCTURE_END(MEMORY_STORAGE)

DECLARE_STRUCTURE_BEGIN(SOURCE_DESCRIPTOR, "")
    DECLARE_FIELD(SOURCE_DESCRIPTOR, TYPE_UIntPtr, Link)
    DECLARE_FIELD(SOURCE_DESCRIPTOR, TYPE_PCHAR, Name)
    DECLARE_FIELD(SOURCE_DESCRIPTOR, TYPE_UIntPtr, StorageHandle)
    DECLARE_FIELD(SOURCE_DESCRIPTOR, TYPE_UIntPtr, EventTypeHandle)
    DECLARE_FIELD(SOURCE_DESCRIPTOR, TYPE_UIntPtr, DebuggerBufferAddress)
    DECLARE_FIELD(SOURCE_DESCRIPTOR, TYPE_uint32, ControlFlags)
    DECLARE_FIELD(SOURCE_DESCRIPTOR, TYPE_uint16, Count)
    DECLARE_FIELD(SOURCE_DESCRIPTOR, TYPE_uint16, EntrySize)
DECLARE_STRUCTURE_END(SOURCE_DESCRIPTOR)

DECLARE_STRUCTURE_BEGIN(EXTERNAL_CONTROLLER_DESCRIPTOR, "")
    DECLARE_SPECIAL_FIELD(EXTERNAL_CONTROLLER_DESCRIPTOR, struct _EXTERNAL_CONTROLLER_DESCRIPTOR *, Link)
    DECLARE_FIELD(EXTERNAL_CONTROLLER_DESCRIPTOR, TYPE_UIntPtr, ControllerHandle)
    DECLARE_FIELD(EXTERNAL_CONTROLLER_DESCRIPTOR, TYPE_UIntPtr, ContextHandle)
DECLARE_STRUCTURE_END(EXTERNAL_CONTROLLER_DESCRIPTOR)

DECLARE_STRUCTURE_BEGIN(QUERY_VIEW, "")
    DECLARE_SPECIAL_FIELD(QUERY_VIEW, struct _QUERY_VIEW *, Link)
    DECLARE_SPECIAL_FIELD(QUERY_VIEW, PMEMORY_STORAGE, Storage)
    DECLARE_SPECIAL_FIELD(QUERY_VIEW, PMEMORY_ZONE, StartZone)
    DECLARE_SPECIAL_FIELD(QUERY_VIEW, PMEMORY_ZONE, CurrentZone)
    DECLARE_SPECIAL_FIELD(QUERY_VIEW, PMEMORY_HEADER, CurrentEntry)
    DECLARE_FIELD(QUERY_VIEW, TYPE_uint32, QueryGeneration)
    DECLARE_FIELD(QUERY_VIEW, TYPE_uint32, ZoneGeneration)
    DECLARE_FIELD(QUERY_VIEW, TYPE_uint32, CurrentEntryIndex)
    DECLARE_FIELD(QUERY_VIEW, TYPE_BOOL, Forward)
    DECLARE_FIELD(QUERY_VIEW, TYPE_BOOL, QueryReset)
    DECLARE_FIELD(QUERY_VIEW, TYPE_BOOL, EndOfBuffer)
DECLARE_STRUCTURE_END(QUERY_VIEW)

DECLARE_STRUCTURE_BEGIN(SOURCE_CONTROLLER, "")
    DECLARE_SPECIAL_FIELD(SOURCE_CONTROLLER, PMEMORY_STORAGE, SourceRepository)
    DECLARE_SPECIAL_FIELD(SOURCE_CONTROLLER, PMEMORY_STORAGE, StorageList)
    DECLARE_SPECIAL_FIELD(SOURCE_CONTROLLER, PSOURCE_DESCRIPTOR, SourceDescriptors)
    DECLARE_SPECIAL_FIELD(SOURCE_CONTROLLER, PEXTERNAL_CONTROLLER_DESCRIPTOR, ExternalControllers)
    DECLARE_SPECIAL_FIELD(SOURCE_CONTROLLER, PEXTERNAL_CONTROLLER_DESCRIPTOR, FreeControllerList)
    DECLARE_SPECIAL_FIELD(SOURCE_CONTROLLER, PQUERY_VIEW, QueryViews)
    DECLARE_SPECIAL_FIELD(SOURCE_CONTROLLER, PQUERY_VIEW, FreeQueryViews)
DECLARE_STRUCTURE_END(SOURCE_CONTROLLER)

#endif // #_LOGGING_TO_REPOSITORY

#ifdef _VALIDATE_INVARIANTS

    C_ASSERT(offsetof(EVENT_FIELD_DESCRIPTOR, fieldsLink) == offsetof(EVENT_GENERIC_TYPE_DESCRIPTOR,fieldsLink));
    C_ASSERT(offsetof(EVENT_FIELD_DESCRIPTOR, Offset) == offsetof(EVENT_GENERIC_TYPE_DESCRIPTOR,Offset));
    C_ASSERT(offsetof(EVENT_FIELD_DESCRIPTOR, Type) == offsetof(EVENT_GENERIC_TYPE_DESCRIPTOR,Type));

    C_ASSERT(offsetof(EVENT_DESCRIPTOR, fieldsLink) == offsetof(ENUM_DESCRIPTOR,fieldsLink));

#endif

//
//  Reset all definitions
//

#undef DECLARE_EXTENDED_ARRAY_FIELD
#undef DECLARE_SPECIAL_FIELD
#undef DECLARE_STRUCTURE_BEGIN
#undef DECLARE_STRUCTURE_END
#undef DECLARE_FIELD
#undef DECLARE_VALUE
#undef DECLARE_GENERIC_FIELD
#undef DECLARE_ENUM_BEGIN
#undef DECLARE_ENUM_END

