swr: [rasterizer archrast] fix open file handle limit issue
authorTim Rowley <timothy.o.rowley@intel.com>
Sat, 29 Oct 2016 06:08:09 +0000 (01:08 -0500)
committerTim Rowley <timothy.o.rowley@intel.com>
Mon, 14 Nov 2016 15:02:17 +0000 (09:02 -0600)
Buffer events ourselves and then when that's full or we're destroying
the context then write the contents to file. Previously, we're relying
ofstream to buffer for us.

Reviewed-by: Bruce Cherniak <bruce.cherniak@intel.com>
src/gallium/drivers/swr/rasterizer/scripts/templates/ar_eventhandlerfile_h.template

index 0a651a4e4a57f01719b91ae6fda45e8244f23924..97eca59f564318d7d1ea576f62f7ce9fa6d6eb2f 100644 (file)
@@ -43,6 +43,7 @@ namespace ArchRast
     {
     public:
         EventHandlerFile(uint32_t id)
+        : mBufOffset(0)
         {
 #if defined(_WIN32)
             DWORD pid = GetCurrentProcessId();
@@ -71,21 +72,55 @@ namespace ArchRast
 
         virtual ~EventHandlerFile()
         {
-            if (mFile.is_open()) mFile.close();
+            FlushBuffer();
         }
 
+        //////////////////////////////////////////////////////////////////////////
+        /// @brief Flush buffer to file.
+        bool FlushBuffer()
+        {
+            if (mBufOffset > 0)
+            {
+                std::ofstream file;
+                file.open(mFilename, std::ios::out | std::ios::app | std::ios::binary);
+
+                if (!file.is_open())
+                {
+                    SWR_ASSERT(0, "ArchRast: Could not open event file!");
+                    return false;
+                }
+
+                file.write((char*)mBuffer, mBufOffset);
+                file.close();
+
+                mBufOffset = 0;
+            }
+            return true;
+        }
+
+        //////////////////////////////////////////////////////////////////////////
+        /// @brief Write event and its payload to the memory buffer.
         void Write(uint32_t eventId, const char* pBlock, uint32_t size)
         {
-            if (!mFile.is_open())
+            if ((mBufOffset + size + sizeof(eventId)) > mBufferSize)
             {
-                mFile.open(mFilename, std::ios::out | std::ios::app | std::ios::binary);
+                if (!FlushBuffer())
+                {
+                    // Don't corrupt what's already in the buffer?
+                    /// @todo Maybe add corrupt marker to buffer here in case we can open file in future?
+                    return;
+                }
             }
 
-            mFile.write((char*)&eventId, sizeof(eventId));
-            mFile.write(pBlock, size);
+            memcpy(&mBuffer[mBufOffset], (char*)&eventId, sizeof(eventId));
+            mBufOffset += sizeof(eventId);
+            memcpy(&mBuffer[mBufOffset], pBlock, size);
+            mBufOffset += size;
         }
 
 % for name in protos['event_names']:
+        //////////////////////////////////////////////////////////////////////////
+        /// @brief Handle ${name} event
         virtual void Handle(${name}& event)
         {
 % if protos['events'][name]['num_fields'] == 0:
@@ -96,7 +131,10 @@ namespace ArchRast
         }
 % endfor
 
-        std::ofstream mFile;
         std::string mFilename;
+
+        static const uint32_t mBufferSize = 1024;
+        uint8_t mBuffer[mBufferSize];
+        uint32_t mBufOffset{0};
     };
 }