private void StartProcessingThread(IManagedCommunicationBlock communicationBlock, IManagedMemoryBlock memoryBlock) { var threadActivated = new AutoResetEvent(false); ThreadPool.QueueUserWorkItem((state) => { var processEvents = new WaitHandle[] { communicationBlock.ProfilerRequestsInformation, memoryBlock.ProfilerHasResults }; threadActivated.Set(); do { switch (WaitHandle.WaitAny(processEvents, new TimeSpan(0, 0, 1))) { case WaitHandle.WaitTimeout: break; case 0: _communicationManager.HandleCommunicationBlock(communicationBlock, (cB, mB) => { }); break; case 1: { var data = _communicationManager.HandleMemoryBlock(memoryBlock); _messageQueue.Enqueue(data); } break; } } while (_continueWait); }); threadActivated.WaitOne(); }
private WaitCallback ProcessBlock(IManagedCommunicationBlock communicationBlock, IManagedMemoryBlock memoryBlock, WaitHandle terminateThread, EventWaitHandle threadActivated, EventWaitHandle threadTerminated) { return(state => { var processEvents = new WaitHandle[] { communicationBlock.ProfilerRequestsInformation, memoryBlock.ProfilerHasResults, terminateThread }; threadActivated.Set(); while (true) { switch (WaitHandle.WaitAny(processEvents)) { case 0: _communicationManager.HandleCommunicationBlock(communicationBlock, (cB, mB) => { }); break; case 1: var data = _communicationManager.HandleMemoryBlock(memoryBlock); _messageQueue.Enqueue(data); break; case 2: threadTerminated.Set(); return; } } }); }
private static void SendChunkAndWaitForConfirmation(int writeSize, IManagedCommunicationBlock mcb) { mcb.StreamAccessorComms.Seek(0, SeekOrigin.Begin); mcb.StreamAccessorComms.Write(mcb.DataCommunication, 0, writeSize); WaitHandle.SignalAndWait(mcb.InformationReadyForProfiler, mcb.InformationReadByProfiler, 10000, false); mcb.InformationReadByProfiler.Reset(); }
private static void SendChunkAndWaitForConfirmation(int writeSize, IManagedCommunicationBlock mcb) { mcb.StreamAccessorComms.Seek(0, SeekOrigin.Begin); mcb.StreamAccessorComms.Write(mcb.DataCommunication, 0, writeSize); mcb.StreamAccessorComms.Flush(); WaitHandle.SignalAndWait(mcb.InformationReadyForProfiler, mcb.InformationReadByProfiler, 10000, false); mcb.InformationReadByProfiler.Reset(); }
/// <summary> /// Process a communication related message from a profiler /// </summary> /// <param name="mcb"></param> /// <param name="offloadHandling"></param> public void HandleCommunicationBlock(IManagedCommunicationBlock mcb, Action <ManagedBufferBlock> offloadHandling) { mcb.ProfilerRequestsInformation.Reset(); mcb.StreamAccessorComms.Seek(0, SeekOrigin.Begin); mcb.StreamAccessorComms.Read(mcb.DataCommunication, 0, _messageHandler.ReadSize); var writeSize = _messageHandler.StandardMessage((MSG_Type)BitConverter.ToInt32(mcb.DataCommunication, 0), mcb, SendChunkAndWaitForConfirmation, offloadHandling); SendChunkAndWaitForConfirmation(writeSize, mcb); }
/// <summary> /// Process a communication related message from a profiler /// </summary> /// <param name="mcb"></param> /// <param name="offloadHandling"></param> public void HandleCommunicationBlock(IManagedCommunicationBlock mcb, Action<ManagedBufferBlock> offloadHandling) { mcb.ProfilerRequestsInformation.Reset(); mcb.StreamAccessorComms.Seek(0, SeekOrigin.Begin); mcb.StreamAccessorComms.Read(mcb.DataCommunication, 0, _messageHandler.ReadSize); var writeSize = _messageHandler.StandardMessage((MSG_Type)BitConverter.ToInt32(mcb.DataCommunication, 0), mcb, SendChunkAndWaitForConfirmation, offloadHandling); SendChunkAndWaitForConfirmation(writeSize, mcb); }
private Tuple <EventWaitHandle, EventWaitHandle> StartProcessingThread(IManagedCommunicationBlock communicationBlock, IManagedMemoryBlock memoryBlock) { var terminateThread = new ManualResetEvent(false); var threadTerminated = new ManualResetEvent(false); using (var threadActivated = new AutoResetEvent(false)) { ThreadPool.QueueUserWorkItem(ProcessBlock(communicationBlock, memoryBlock, terminateThread, threadActivated, threadTerminated)); threadActivated.WaitOne(); } return(new Tuple <EventWaitHandle, EventWaitHandle>(terminateThread, threadTerminated)); }
private int HandleGetBranchPointsMessage(IntPtr pinnedMemory, IManagedCommunicationBlock mcb, Action <int, IManagedCommunicationBlock> chunkReady) { var writeSize = 0; var response = new MSG_GetBranchPoints_Response(); try { var request = _marshalWrapper.PtrToStructure <MSG_GetBranchPoints_Request>(pinnedMemory); BranchPoint[] origPoints; _profilerCommunication.GetBranchPoints(request.processPath, request.modulePath, request.assemblyName, request.functionToken, out origPoints); var num = origPoints.Maybe(o => o.Length); var index = 0; var chunk = Marshal.SizeOf(typeof(MSG_BranchPoint)); do { writeSize = Marshal.SizeOf(typeof(MSG_GetBranchPoints_Response)); response.more = num > GbpBufSize; response.count = num > GbpBufSize ? GbpBufSize : num; _marshalWrapper.StructureToPtr(response, pinnedMemory, false); var point = new MSG_BranchPoint(); for (var i = 0; i < response.count; i++) { point.offset = origPoints[index].Offset; point.uniqueId = origPoints[index].UniqueSequencePoint; point.path = origPoints[index].Path; _marshalWrapper.StructureToPtr(point, pinnedMemory + writeSize, false); writeSize += chunk; index++; } if (response.more) { chunkReady(writeSize, mcb); num -= GbpBufSize; } } while (response.more); } catch (Exception ex) { DebugLogger.ErrorFormat("HandleGetBranchPointsMessage => {0}:{1}", ex.GetType(), ex); response.more = false; response.count = 0; _marshalWrapper.StructureToPtr(response, pinnedMemory, false); } return(writeSize); }
private WaitCallback ProcessBlock(IManagedCommunicationBlock communicationBlock, IManagedMemoryBlock memoryBlock, WaitHandle terminateThread, EventWaitHandle threadActivated, EventWaitHandle threadTerminated) { return(state => { var processEvents = new [] { communicationBlock.ProfilerRequestsInformation, memoryBlock.ProfilerHasResults, terminateThread }; threadActivated.Set(); while (true) { switch (WaitHandle.WaitAny(processEvents)) { case 0: _communicationManager.HandleCommunicationBlock(communicationBlock, (cB, mB) => { }); break; case 1: var data = _communicationManager.HandleMemoryBlock(memoryBlock); // don't let the queue get too big as using too much memory causes // problems i.e. the target process closes down but the host takes // ages to shutdown; this is a compromise. _messageQueue.Enqueue(data); if (_messageQueue.Count > 400) { do { Thread.Yield(); } while (_messageQueue.Count > 200); } break; case 2: threadTerminated.Set(); return; } } }); }
/// <summary> /// Process a Standard Message /// </summary> /// <param name="msgType"></param> /// <param name="mcb"></param> /// <param name="chunkReady"></param> /// <param name="offloadHandling"></param> /// <returns></returns> public int StandardMessage(MSG_Type msgType, IManagedCommunicationBlock mcb, Action <int, IManagedCommunicationBlock> chunkReady, Action <ManagedBufferBlock> offloadHandling) { IntPtr pinnedMemory = mcb.PinnedDataCommunication.AddrOfPinnedObject(); var writeSize = 0; switch (msgType) { case MSG_Type.MSG_TrackAssembly: writeSize = HandleTrackAssemblyMessage(pinnedMemory); break; case MSG_Type.MSG_GetSequencePoints: writeSize = HandleGetSequencePointsMessage(pinnedMemory, mcb, chunkReady); break; case MSG_Type.MSG_GetBranchPoints: writeSize = HandleGetBranchPointsMessage(pinnedMemory, mcb, chunkReady); break; case MSG_Type.MSG_TrackMethod: writeSize = HandleTrackMethodMessage(pinnedMemory); break; case MSG_Type.MSG_AllocateMemoryBuffer: writeSize = HandleAllocateBufferMessage(offloadHandling, pinnedMemory); break; case MSG_Type.MSG_CloseChannel: writeSize = HandleCloseChannelMessage(pinnedMemory); break; case MSG_Type.MSG_TrackProcess: writeSize = HandleTrackProcessMessage(pinnedMemory); break; default: throw new InvalidOperationException(); } return(writeSize); }
/// <summary> /// Process a Standard Message /// </summary> /// <param name="msgType"></param> /// <param name="mcb"></param> /// <param name="chunkReady"></param> /// <param name="offloadHandling"></param> /// <returns></returns> public int StandardMessage(MSG_Type msgType, IManagedCommunicationBlock mcb, Action<int, IManagedCommunicationBlock> chunkReady, Action<ManagedBufferBlock> offloadHandling) { IntPtr pinnedMemory = mcb.PinnedDataCommunication.AddrOfPinnedObject(); var writeSize = 0; switch (msgType) { case MSG_Type.MSG_TrackAssembly: writeSize = HandleTrackAssemblyMessage(pinnedMemory); break; case MSG_Type.MSG_GetSequencePoints: writeSize = HandleGetSequencePointsMessage(pinnedMemory, mcb, chunkReady); break; case MSG_Type.MSG_GetBranchPoints: writeSize = HandleGetBranchPointsMessage(pinnedMemory, mcb, chunkReady); break; case MSG_Type.MSG_TrackMethod: writeSize = HandleTrackMethodMessage(pinnedMemory); break; case MSG_Type.MSG_AllocateMemoryBuffer: writeSize = HandleAllocateBufferMessage(offloadHandling, pinnedMemory); break; case MSG_Type.MSG_CloseChannel: writeSize = HandleCloseChannelMessage(pinnedMemory); break; case MSG_Type.MSG_TrackProcess: writeSize = HandleTrackProcessMessage(pinnedMemory); break; default: throw new InvalidOperationException(); } return writeSize; }
private Tuple <ManualResetEvent, ManualResetEvent> StartProcessingThread(IManagedCommunicationBlock communicationBlock, IManagedMemoryBlock memoryBlock) { var threadActivated = new AutoResetEvent(false); var terminateThread = new ManualResetEvent(false); var threadTerminated = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem((state) => { var processEvents = new WaitHandle[] { communicationBlock.ProfilerRequestsInformation, memoryBlock.ProfilerHasResults, terminateThread, }; threadActivated.Set(); while (true) { switch (WaitHandle.WaitAny(processEvents)) { case 0: _communicationManager.HandleCommunicationBlock(communicationBlock, (cB, mB) => { }); break; case 1: { var data = _communicationManager.HandleMemoryBlock(memoryBlock); _messageQueue.Enqueue(data); } break; case 2: threadTerminated.Set(); return; } } }); threadActivated.WaitOne(); return(new Tuple <ManualResetEvent, ManualResetEvent>(terminateThread, threadTerminated)); }
private int HandleGetSequencePointsMessage(IntPtr pinnedMemory, IManagedCommunicationBlock mcb, Action<int, IManagedCommunicationBlock> chunkReady) { var writeSize = 0; var response = new MSG_GetSequencePoints_Response(); try { var request = _marshalWrapper.PtrToStructure<MSG_GetSequencePoints_Request>(pinnedMemory); InstrumentationPoint[] origPoints; _profilerCommunication.GetSequencePoints(request.processName, request.modulePath, request.assemblyName, request.functionToken, out origPoints); var num = origPoints.Maybe(o => o.Length); var index = 0; var chunk = Marshal.SizeOf(typeof (MSG_SequencePoint)); do { writeSize = Marshal.SizeOf(typeof (MSG_GetSequencePoints_Response)); response.more = num > GspBufSize; response.count = num > GspBufSize ? GspBufSize : num; _marshalWrapper.StructureToPtr(response, pinnedMemory, false); var point = new MSG_SequencePoint(); for (var i = 0; i < response.count; i++) { point.offset = origPoints[index].Offset; point.uniqueId = origPoints[index].UniqueSequencePoint; _marshalWrapper.StructureToPtr(point, pinnedMemory + writeSize, false); writeSize += chunk; index++; } if (response.more) { chunkReady(writeSize, mcb); num -= GspBufSize; } } while (response.more); } catch (Exception ex) { DebugLogger.ErrorFormat("HandleGetSequencePointsMessage => {0}:{1}", ex.GetType(), ex.Message); response.more = false; response.count = 0; _marshalWrapper.StructureToPtr(response, pinnedMemory, false); } return writeSize; }
private Tuple<EventWaitHandle, EventWaitHandle> StartProcessingThread(IManagedCommunicationBlock communicationBlock, IManagedMemoryBlock memoryBlock) { var terminateThread = new ManualResetEvent(false); var threadTerminated = new ManualResetEvent(false); using (var threadActivated = new AutoResetEvent(false)) { ThreadPool.QueueUserWorkItem(ProcessBlock(communicationBlock, memoryBlock, terminateThread, threadActivated, threadTerminated)); threadActivated.WaitOne(); } return new Tuple<EventWaitHandle, EventWaitHandle>(terminateThread, threadTerminated); }
private WaitCallback ProcessBlock(IManagedCommunicationBlock communicationBlock, IManagedMemoryBlock memoryBlock, WaitHandle terminateThread, EventWaitHandle threadActivated, EventWaitHandle threadTerminated) { return state => { var processEvents = new [] { communicationBlock.ProfilerRequestsInformation, memoryBlock.ProfilerHasResults, terminateThread }; threadActivated.Set(); while(true) { switch (WaitHandle.WaitAny(processEvents)) { case 0: _communicationManager.HandleCommunicationBlock(communicationBlock, (cB, mB) => { }); break; case 1: var data = _communicationManager.HandleMemoryBlock(memoryBlock); // don't let the queue get too big as using too much memory causes // problems i.e. the target process closes down but the host takes // ages to shutdown; this is a compromise. _messageQueue.Enqueue(data); if (_messageQueue.Count > 400) { do { Thread.Yield(); } while (_messageQueue.Count > 200); } break; case 2: threadTerminated.Set(); return; } } }; }
private Tuple<ManualResetEvent, ManualResetEvent> StartProcessingThread(IManagedCommunicationBlock communicationBlock, IManagedMemoryBlock memoryBlock) { var threadActivated = new AutoResetEvent(false); var terminateThread = new ManualResetEvent(false); var threadTerminated = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem((state) => { var processEvents = new WaitHandle[] { communicationBlock.ProfilerRequestsInformation, memoryBlock.ProfilerHasResults, terminateThread, }; threadActivated.Set(); while(true) { switch (WaitHandle.WaitAny(processEvents)) { case 0: _communicationManager.HandleCommunicationBlock(communicationBlock, (cB, mB) => { }); break; case 1: { var data = _communicationManager.HandleMemoryBlock(memoryBlock); _messageQueue.Enqueue(data); } break; case 2: threadTerminated.Set(); return; } } }); threadActivated.WaitOne(); return new Tuple<ManualResetEvent, ManualResetEvent>(terminateThread, threadTerminated); }
// TODO: change pinnedMemory to an byte[], pass in mcb as well public int StandardMessage(MSG_Type msgType, IManagedCommunicationBlock mcb, Action<int, IManagedCommunicationBlock> chunkReady, Action<IManagedCommunicationBlock, IManagedMemoryBlock> offloadHandling) { IntPtr pinnedMemory = mcb.PinnedDataCommunication.AddrOfPinnedObject(); var writeSize = 0; switch (msgType) { case MSG_Type.MSG_TrackAssembly: { var msgTA = _marshalWrapper.PtrToStructure<MSG_TrackAssembly_Request>(pinnedMemory); if (!String.IsNullOrEmpty(msgTA.modulePath) && msgTA.modulePath.StartsWith("@")) { msgTA.modulePath = this._moduleLocator.LocateForAssembly(msgTA.assemblyName); } var responseTA = new MSG_TrackAssembly_Response(); responseTA.track = _profilerCommunication.TrackAssembly(msgTA.modulePath, msgTA.assemblyName); _marshalWrapper.StructureToPtr(responseTA, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof (MSG_TrackAssembly_Response)); } break; case MSG_Type.MSG_GetSequencePoints: { var msgGSP = _marshalWrapper.PtrToStructure<MSG_GetSequencePoints_Request>(pinnedMemory); InstrumentationPoint[] origPoints; if (!String.IsNullOrEmpty(msgGSP.modulePath) && msgGSP.modulePath.StartsWith("@")) { msgGSP.modulePath = this._moduleLocator.LocateForAssembly(msgGSP.assemblyName); } var responseCSP = new MSG_GetSequencePoints_Response(); _profilerCommunication.GetSequencePoints(msgGSP.modulePath, msgGSP.assemblyName, msgGSP.functionToken, out origPoints); var num = origPoints == null ? 0 : origPoints.Length; var index = 0; var chunk = Marshal.SizeOf(typeof (MSG_SequencePoint)); do { writeSize = Marshal.SizeOf(typeof (MSG_GetSequencePoints_Response)); responseCSP.more = num > GSP_BufSize; responseCSP.count = num > GSP_BufSize ? GSP_BufSize : num; _marshalWrapper.StructureToPtr(responseCSP, pinnedMemory, false); for (var i = 0; i < responseCSP.count; i++) { var point = new MSG_SequencePoint(); point.offset = origPoints[index].Offset; point.uniqueId = origPoints[index].UniqueSequencePoint; _marshalWrapper.StructureToPtr(point, pinnedMemory + writeSize, false); writeSize += chunk; index++; } if (responseCSP.more) { chunkReady(writeSize, mcb); num -= GSP_BufSize; } } while (responseCSP.more); } break; case MSG_Type.MSG_GetBranchPoints: { var msgGBP = _marshalWrapper.PtrToStructure<MSG_GetBranchPoints_Request>(pinnedMemory); if (!String.IsNullOrEmpty(msgGBP.modulePath) && msgGBP.modulePath.StartsWith("@")) { msgGBP.modulePath = this._moduleLocator.LocateForAssembly(msgGBP.assemblyName); } BranchPoint[] origPoints; var responseCSP = new MSG_GetBranchPoints_Response(); _profilerCommunication.GetBranchPoints(msgGBP.modulePath, msgGBP.assemblyName, msgGBP.functionToken, out origPoints); var num = origPoints == null ? 0 : origPoints.Length; var index = 0; var chunk = Marshal.SizeOf(typeof (MSG_BranchPoint)); do { writeSize = Marshal.SizeOf(typeof (MSG_GetBranchPoints_Response)); responseCSP.more = num > GBP_BufSize; responseCSP.count = num > GBP_BufSize ? GBP_BufSize : num; _marshalWrapper.StructureToPtr(responseCSP, pinnedMemory, false); for (var i = 0; i < responseCSP.count; i++) { var point = new MSG_BranchPoint(); point.offset = origPoints[index].Offset; point.uniqueId = origPoints[index].UniqueSequencePoint; point.path = origPoints[index].Path; _marshalWrapper.StructureToPtr(point, pinnedMemory + writeSize, false); writeSize += chunk; index++; } if (responseCSP.more) { chunkReady(writeSize, mcb); num -= GBP_BufSize; } } while (responseCSP.more); } break; case MSG_Type.MSG_TrackMethod: { var msgTM = _marshalWrapper.PtrToStructure<MSG_TrackMethod_Request>(pinnedMemory); var responseTM = new MSG_TrackMethod_Response(); uint uniqueId; responseTM.track = _profilerCommunication.TrackMethod(msgTM.modulePath, msgTM.assemblyName, msgTM.functionToken, out uniqueId); responseTM.uniqueId = uniqueId; _marshalWrapper.StructureToPtr(responseTM, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof(MSG_TrackMethod_Response)); } break; case MSG_Type.MSG_AllocateMemoryBuffer: { var msgAB = _marshalWrapper.PtrToStructure<MSG_AllocateBuffer_Request>(pinnedMemory); var block = _memoryManager.AllocateMemoryBuffer(msgAB.bufferSize, _bufferId); var responseAB = new MSG_AllocateBuffer_Response {allocated = true, bufferId = _bufferId }; _marshalWrapper.StructureToPtr(responseAB, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof(MSG_AllocateBuffer_Response)); _bufferId++; offloadHandling(block.Item1, block.Item2); } break; } return writeSize; }
// TODO: change pinnedMemory to an byte[], pass in mcb as well public int StandardMessage(MSG_Type msgType, IManagedCommunicationBlock mcb, Action <int, IManagedCommunicationBlock> chunkReady, Action <ManagedBufferBlock> offloadHandling) { IntPtr pinnedMemory = mcb.PinnedDataCommunication.AddrOfPinnedObject(); var writeSize = 0; switch (msgType) { case MSG_Type.MSG_TrackAssembly: { var msgTA = _marshalWrapper.PtrToStructure <MSG_TrackAssembly_Request>(pinnedMemory); var responseTA = new MSG_TrackAssembly_Response(); responseTA.track = _profilerCommunication.TrackAssembly(msgTA.modulePath, msgTA.assemblyName); _marshalWrapper.StructureToPtr(responseTA, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof(MSG_TrackAssembly_Response)); } break; case MSG_Type.MSG_GetSequencePoints: { var responseGSP = new MSG_GetSequencePoints_Response(); try { var msgGSP = _marshalWrapper.PtrToStructure <MSG_GetSequencePoints_Request>(pinnedMemory); InstrumentationPoint[] origPoints; _profilerCommunication.GetSequencePoints(msgGSP.modulePath, msgGSP.assemblyName, msgGSP.functionToken, out origPoints); var num = origPoints == null ? 0 : origPoints.Length; var index = 0; var chunk = Marshal.SizeOf(typeof(MSG_SequencePoint)); do { writeSize = Marshal.SizeOf(typeof(MSG_GetSequencePoints_Response)); responseGSP.more = num > GSP_BufSize; responseGSP.count = num > GSP_BufSize ? GSP_BufSize : num; _marshalWrapper.StructureToPtr(responseGSP, pinnedMemory, false); for (var i = 0; i < responseGSP.count; i++) { var point = new MSG_SequencePoint(); point.offset = origPoints[index].Offset; point.uniqueId = origPoints[index].UniqueSequencePoint; _marshalWrapper.StructureToPtr(point, pinnedMemory + writeSize, false); writeSize += chunk; index++; } if (responseGSP.more) { chunkReady(writeSize, mcb); num -= GSP_BufSize; } } while (responseGSP.more); } catch (Exception ex) { Console.WriteLine("{0}:{1}", ex.GetType(), ex.Message); responseGSP.more = false; responseGSP.count = 0; _marshalWrapper.StructureToPtr(responseGSP, pinnedMemory, false); } } break; case MSG_Type.MSG_GetBranchPoints: { var responseGBP = new MSG_GetBranchPoints_Response(); try { var msgGBP = _marshalWrapper.PtrToStructure <MSG_GetBranchPoints_Request>(pinnedMemory); BranchPoint[] origPoints; _profilerCommunication.GetBranchPoints(msgGBP.modulePath, msgGBP.assemblyName, msgGBP.functionToken, out origPoints); var num = origPoints == null ? 0 : origPoints.Length; var index = 0; var chunk = Marshal.SizeOf(typeof(MSG_BranchPoint)); do { writeSize = Marshal.SizeOf(typeof(MSG_GetBranchPoints_Response)); responseGBP.more = num > GBP_BufSize; responseGBP.count = num > GBP_BufSize ? GBP_BufSize : num; _marshalWrapper.StructureToPtr(responseGBP, pinnedMemory, false); for (var i = 0; i < responseGBP.count; i++) { var point = new MSG_BranchPoint(); point.offset = origPoints[index].Offset; point.uniqueId = origPoints[index].UniqueSequencePoint; point.path = origPoints[index].Path; _marshalWrapper.StructureToPtr(point, pinnedMemory + writeSize, false); writeSize += chunk; index++; } if (responseGBP.more) { chunkReady(writeSize, mcb); num -= GBP_BufSize; } } while (responseGBP.more); } catch (Exception ex) { Console.WriteLine("{0}:{1}", ex.GetType(), ex.Message); responseGBP.more = false; responseGBP.count = 0; _marshalWrapper.StructureToPtr(responseGBP, pinnedMemory, false); } } break; case MSG_Type.MSG_TrackMethod: { var msgTM = _marshalWrapper.PtrToStructure <MSG_TrackMethod_Request>(pinnedMemory); var responseTM = new MSG_TrackMethod_Response(); uint uniqueId; responseTM.track = _profilerCommunication.TrackMethod(msgTM.modulePath, msgTM.assemblyName, msgTM.functionToken, out uniqueId); responseTM.uniqueId = uniqueId; _marshalWrapper.StructureToPtr(responseTM, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof(MSG_TrackMethod_Response)); } break; case MSG_Type.MSG_AllocateMemoryBuffer: { var msgAB = _marshalWrapper.PtrToStructure <MSG_AllocateBuffer_Request>(pinnedMemory); var block = _memoryManager.AllocateMemoryBuffer(msgAB.bufferSize, _bufferId); var responseAB = new MSG_AllocateBuffer_Response { allocated = true, bufferId = _bufferId }; _marshalWrapper.StructureToPtr(responseAB, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof(MSG_AllocateBuffer_Response)); _bufferId++; offloadHandling(block); } break; case MSG_Type.MSG_CloseChannel: { var msgCC = _marshalWrapper.PtrToStructure <MSG_CloseChannel_Request>(pinnedMemory); var bufferId = msgCC.bufferId; var responseCC = new MSG_CloseChannel_Response { done = true }; _marshalWrapper.StructureToPtr(responseCC, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof(MSG_CloseChannel_Response)); _memoryManager.DeactivateMemoryBuffer(bufferId); } break; } return(writeSize); }
// TODO: change pinnedMemory to an byte[], pass in mcb as well public int StandardMessage(MSG_Type msgType, IManagedCommunicationBlock mcb, Action<int, IManagedCommunicationBlock> chunkReady, Action<ManagedBufferBlock> offloadHandling) { IntPtr pinnedMemory = mcb.PinnedDataCommunication.AddrOfPinnedObject(); var writeSize = 0; switch (msgType) { case MSG_Type.MSG_TrackAssembly: { var msgTA = _marshalWrapper.PtrToStructure<MSG_TrackAssembly_Request>(pinnedMemory); var responseTA = new MSG_TrackAssembly_Response(); responseTA.track = _profilerCommunication.TrackAssembly(msgTA.modulePath, msgTA.assemblyName); _marshalWrapper.StructureToPtr(responseTA, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof (MSG_TrackAssembly_Response)); } break; case MSG_Type.MSG_GetSequencePoints: { var responseGSP = new MSG_GetSequencePoints_Response(); try { var msgGSP = _marshalWrapper.PtrToStructure<MSG_GetSequencePoints_Request>(pinnedMemory); InstrumentationPoint[] origPoints; _profilerCommunication.GetSequencePoints(msgGSP.modulePath, msgGSP.assemblyName, msgGSP.functionToken, out origPoints); var num = origPoints == null ? 0 : origPoints.Length; var index = 0; var chunk = Marshal.SizeOf(typeof (MSG_SequencePoint)); do { writeSize = Marshal.SizeOf(typeof (MSG_GetSequencePoints_Response)); responseGSP.more = num > GSP_BufSize; responseGSP.count = num > GSP_BufSize ? GSP_BufSize : num; _marshalWrapper.StructureToPtr(responseGSP, pinnedMemory, false); for (var i = 0; i < responseGSP.count; i++) { var point = new MSG_SequencePoint(); point.offset = origPoints[index].Offset; point.uniqueId = origPoints[index].UniqueSequencePoint; _marshalWrapper.StructureToPtr(point, pinnedMemory + writeSize, false); writeSize += chunk; index++; } if (responseGSP.more) { chunkReady(writeSize, mcb); num -= GSP_BufSize; } } while (responseGSP.more); } catch (Exception ex) { Console.WriteLine("{0}:{1}", ex.GetType(), ex.Message); responseGSP.more = false; responseGSP.count = 0; _marshalWrapper.StructureToPtr(responseGSP, pinnedMemory, false); } } break; case MSG_Type.MSG_GetBranchPoints: { var responseGBP = new MSG_GetBranchPoints_Response(); try { var msgGBP = _marshalWrapper.PtrToStructure<MSG_GetBranchPoints_Request>(pinnedMemory); BranchPoint[] origPoints; _profilerCommunication.GetBranchPoints(msgGBP.modulePath, msgGBP.assemblyName, msgGBP.functionToken, out origPoints); var num = origPoints == null ? 0 : origPoints.Length; var index = 0; var chunk = Marshal.SizeOf(typeof (MSG_BranchPoint)); do { writeSize = Marshal.SizeOf(typeof (MSG_GetBranchPoints_Response)); responseGBP.more = num > GBP_BufSize; responseGBP.count = num > GBP_BufSize ? GBP_BufSize : num; _marshalWrapper.StructureToPtr(responseGBP, pinnedMemory, false); for (var i = 0; i < responseGBP.count; i++) { var point = new MSG_BranchPoint(); point.offset = origPoints[index].Offset; point.uniqueId = origPoints[index].UniqueSequencePoint; point.path = origPoints[index].Path; _marshalWrapper.StructureToPtr(point, pinnedMemory + writeSize, false); writeSize += chunk; index++; } if (responseGBP.more) { chunkReady(writeSize, mcb); num -= GBP_BufSize; } } while (responseGBP.more); } catch (Exception ex) { Console.WriteLine("{0}:{1}", ex.GetType(), ex.Message); responseGBP.more = false; responseGBP.count = 0; _marshalWrapper.StructureToPtr(responseGBP, pinnedMemory, false); } } break; case MSG_Type.MSG_TrackMethod: { var msgTM = _marshalWrapper.PtrToStructure<MSG_TrackMethod_Request>(pinnedMemory); var responseTM = new MSG_TrackMethod_Response(); uint uniqueId; responseTM.track = _profilerCommunication.TrackMethod(msgTM.modulePath, msgTM.assemblyName, msgTM.functionToken, out uniqueId); responseTM.uniqueId = uniqueId; _marshalWrapper.StructureToPtr(responseTM, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof(MSG_TrackMethod_Response)); } break; case MSG_Type.MSG_AllocateMemoryBuffer: { var msgAB = _marshalWrapper.PtrToStructure<MSG_AllocateBuffer_Request>(pinnedMemory); var block = _memoryManager.AllocateMemoryBuffer(msgAB.bufferSize, _bufferId); var responseAB = new MSG_AllocateBuffer_Response {allocated = true, bufferId = _bufferId }; _marshalWrapper.StructureToPtr(responseAB, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof(MSG_AllocateBuffer_Response)); _bufferId++; offloadHandling(block); } break; case MSG_Type.MSG_CloseChannel: { var msgCC = _marshalWrapper.PtrToStructure<MSG_CloseChannel_Request>(pinnedMemory); var bufferId = msgCC.bufferId; var responseCC = new MSG_CloseChannel_Response { done = true }; _marshalWrapper.StructureToPtr(responseCC, pinnedMemory, false); writeSize = Marshal.SizeOf(typeof(MSG_CloseChannel_Response)); _memoryManager.DeactivateMemoryBuffer(bufferId); } break; } return writeSize; }