Fix EventPipe IPC streaming (#23768)
authorSung Yoon Whang <suwhang@microsoft.com>
Sat, 13 Apr 2019 00:11:49 +0000 (17:11 -0700)
committerGitHub <noreply@github.com>
Sat, 13 Apr 2019 00:11:49 +0000 (17:11 -0700)
* Make events stream out faster when we are doing IPC

* Block size should be less during IPC session

* Modify some comments

* Address PR feedback

* more pr feedback

* Fix high volume scenario

* Fix flush

* cleanup

* Only flush when we have buffers written

src/vm/eventpipebuffermanager.cpp
src/vm/eventpipebuffermanager.h
src/vm/eventpipefile.cpp
src/vm/eventpipefile.h
src/vm/fastserializer.cpp
src/vm/fastserializer.h

index e15676e..f08a2b3 100644 (file)
@@ -434,6 +434,7 @@ void EventPipeBufferManager::WriteAllBuffersToFile(EventPipeFile *pFile, LARGE_I
     SpinLockHolder _slh(&m_lock);
 
     // Naively walk the circular buffer, writing the event stream in timestamp order.
+    m_numEventsWritten = 0;
     while(true)
     {
         EventPipeEventInstance *pOldestInstance = NULL;
@@ -470,13 +471,14 @@ void EventPipeBufferManager::WriteAllBuffersToFile(EventPipeFile *pFile, LARGE_I
 
         // Write the oldest event.
         pFile->WriteEvent(*pOldestInstance);
-#ifdef _DEBUG
-        m_numEventsWritten++;
-#endif // _DEBUG
 
+        m_numEventsWritten++;
         // Pop the event from the buffer.
         pOldestContainingList->PopNextEvent(stopTimeStamp);
     }
+
+    if (m_numEventsWritten > 0)
+        pFile->Flush();
 }
 
 EventPipeEventInstance* EventPipeBufferManager::GetNextEvent()
index a7584cc..a6e47f3 100644 (file)
@@ -71,9 +71,9 @@ private:
     unsigned int m_numBuffersLeaked;
     Volatile<LONG> m_numEventsStored;
     Volatile<LONG> m_numEventsDropped;
-    LONG m_numEventsWritten;
 #endif // _DEBUG
 
+    unsigned long m_numEventsWritten;
     // Allocate a new buffer for the specified thread.
     // This function will store the buffer in the thread's buffer list for future use and also return it here.
     // A NULL return value means that a buffer could not be allocated.
index 73fb48e..b2d82e5 100644 (file)
@@ -96,6 +96,20 @@ void EventPipeFile::WriteEvent(EventPipeEventInstance &instance)
     WriteToBlock(instance, metadataId);
 }
 
+void EventPipeFile::Flush()
+{
+    // Write existing buffer to the stream/file regardless of whether it is full or not.
+    CONTRACTL
+    {
+        NOTHROW;
+        GC_NOTRIGGER;
+        MODE_ANY;
+    }
+    CONTRACTL_END;
+    m_pSerializer->WriteObject(m_pBlock); // we write current block to the disk, whether it's full or not
+    m_pBlock->Clear();
+}
+
 void EventPipeFile::WriteEnd()
 {
     CONTRACTL
index d99bcd1..9441ec4 100644 (file)
@@ -21,6 +21,7 @@ public:
     ~EventPipeFile();
 
     void WriteEvent(EventPipeEventInstance &instance);
+    void Flush();
 
     const char *GetTypeName() override
     {
index 2941f6a..0b2c0f6 100644 (file)
@@ -63,7 +63,6 @@ FileStreamWriter::FileStreamWriter(const SString &outputFilePath)
         MODE_ANY;
     }
     CONTRACTL_END;
-
     m_pFileStream = new CFileStream();
     if (FAILED(m_pFileStream->OpenForWrite(outputFilePath)))
     {
index 4d61adc..d5db786 100644 (file)
@@ -16,7 +16,7 @@ class IpcStream;
 
 // the enumeration has a specific set of values to keep it compatible with consumer library
 // it's sibling is defined in https://github.com/Microsoft/perfview/blob/10d1f92b242c98073b3817ac5ee6d98cd595d39b/src/FastSerialization/FastSerialization.cs#L2295
-enum class FastSerializerTags : BYTE
+enum class FastSerializerTags : uint8_t
 {
     Error              = 0, // To improve debugabilty, 0 is an illegal tag.
     NullReference      = 1, // Tag for a null object forwardReference.