// ---------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // ---------------------------------------------------------------------------- using System; using System.Runtime.CompilerServices; using Microsoft.Singularity.Transform; using Microsoft.Singularity.Eventing; using Microsoft.Singularity.V1.Services; // patterns namespace Microsoft.Singularity.EventTemplate { [Pattern][Data] public struct EachParam { } [Pattern][EventEnum] public enum BasicEnum { } [Pattern] public class EachParam_DataType { public static readonly ushort TypeID = 0; } [Pattern] [Event] [Template] public abstract class EachSourceClass : EventSource { [Pattern] [Event] public abstract bool EachLogMethod([Case][EventEnum]BasicEnum eachBasicEnumParam, [Case][Data]EachParam eachParam); // temporary static string for each method that defines a printf format // todo: move into attribute parameters public static string EachLogMethod_Format; // generate template code new public static uint ControlFlag; // separate flag for each meth public static readonly uint EachLogMethod_Flag; // separate handle for the type defined for each meth public static UIntPtr EachLogMethod_Handle; public static UIntPtr BasicEnum_Handle; // class constructor to intialize flag bits static EachSourceClass() { ControlFlag = 0; uint flag = 0x10000; Transform.For("EachLogMethod"); EachLogMethod_Format = null; EachLogMethod_Flag = flag; BasicEnum_Handle = 0; flag = flag << 1; if (flag == 0) { throw new Exception("Flag overflow - too many methods in EachSourceClass"); } Transform.EndFor(); } // template for static creation method new public static EachSourceClass Create(string sourcename, uint size, uint storageOptions, uint sourceFlags) { EventingStorage storage = EventingStorage.CreateLocalStorage(storageOptions, size); if (storage == null) { DebugStub.WriteLine("Failure to create local storage " + sourcename); DebugStub.Break(); return null; } EachSourceClass Source = new EachSourceClass_Impl(sourcename, storage, sourceFlags); if (Source != null) { if (!Source.Register()) { DebugStub.WriteLine("Error initializing the source " + sourcename); return null; } } return Source; } // struct to hold event parameters for each method public struct EachLogMethod_Event { public EachParam eachParam; public int eachBasicEnumParam; } internal EachSourceClass(string sourceName, EventingStorage storage, uint controlFlags) :base(sourceName, storage, controlFlags) {} } [Template] internal class EachSourceClass_Impl : EachSourceClass { [NoHeapAllocation] public override bool EachLogMethod([Case][EventEnum]BasicEnum eachBasicEnumParam, [Case][Data]EachParam eachParam) { if ((ControlFlags & EachLogMethod_Flag) != 0) { unsafe { EachLogMethod_Event Event; Transform.For("eachParam"); Event.eachParam = eachParam; Transform.EndFor(); Transform.For("eachBasicEnumParam"); Event.eachBasicEnumParam = (int)eachBasicEnumParam; Transform.EndFor(); return (LogEntry(ControlFlags, EachLogMethod_Handle, (byte *)&Event, sizeof(EachLogMethod_Event)) != 0); } } return false; } public override bool Register() { if (!base.Register()) { return false; } if (HostController == null) { return false; } RegisterEnumSymbols(); DataType2 dt2 = new DataType2(); string s = "EachSourceClass"; Transform.For("EachLogMethod"); string format = EachLogMethod_Format != null ? EachSourceClass.EachLogMethod_Format : "{0}"; if (HostController.RegisterEvent(s + ".EachLogMethod", format, ref EachLogMethod_Handle)) { DebugStub.WriteLine("register event succeeded"); Transform.For("eachParam"); HostController.RegisterEventField(EachSourceClass.EachLogMethod_Handle, "eachParam", 0, dt2.__EachParam); Transform.EndFor(); // // HACK!!!!! Some instruction is needed here, otherwise, the transform // will merge the enumeration below with the one above // producing a mismatch in the order of argumets in the structure declaration // DebugStub.WriteLine("Registering enums"); Transform.For("eachBasicEnumParam"); HostController.RegisterEventGenericField(EachSourceClass.EachLogMethod_Handle, "eachBasicEnumParam", 0, sizeof(int), BasicEnum_Handle); Transform.EndFor(); } else { // The event might have been registered already // Check whether we foundit already in the table or not if (EachSourceClass.EachLogMethod_Handle == 0) { return false; } } Transform.EndFor(); return true; } internal EachSourceClass_Impl(string sourceName, EventingStorage storage, uint controlFlags) :base(sourceName, storage, controlFlags) {} } }