1/**************************************************************************** 2* Copyright (C) 2016 Intel Corporation. All Rights Reserved. 3* 4* Permission is hereby granted, free of charge, to any person obtaining a 5* copy of this software and associated documentation files (the "Software"), 6* to deal in the Software without restriction, including without limitation 7* the rights to use, copy, modify, merge, publish, distribute, sublicense, 8* and/or sell copies of the Software, and to permit persons to whom the 9* Software is furnished to do so, subject to the following conditions: 10* 11* The above copyright notice and this permission notice (including the next 12* paragraph) shall be included in all copies or substantial portions of the 13* Software. 14* 15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21* IN THE SOFTWARE. 22* 23* @file ${filename} 24* 25* @brief Event handler interface. auto-generated file 26* 27* DO NOT EDIT 28* 29******************************************************************************/ 30#pragma once 31 32#include "common/os.h" 33#include "${event_header}" 34#include <fstream> 35#include <sstream> 36 37namespace ArchRast 38{ 39 ////////////////////////////////////////////////////////////////////////// 40 /// EventHandlerFile - interface for handling events. 41 ////////////////////////////////////////////////////////////////////////// 42 class EventHandlerFile : public EventHandler 43 { 44 public: 45 EventHandlerFile(uint32_t id) 46 : mBufOffset(0) 47 { 48#if defined(_WIN32) 49 DWORD pid = GetCurrentProcessId(); 50 TCHAR procname[MAX_PATH]; 51 GetModuleFileName(NULL, procname, MAX_PATH); 52 const char* pBaseName = strrchr(procname, '\\'); 53 std::stringstream outDir; 54 outDir << KNOB_DEBUG_OUTPUT_DIR << pBaseName << "_" << pid << std::ends; 55 CreateDirectory(outDir.str().c_str(), NULL); 56 57 char buf[255]; 58 // There could be multiple threads creating thread pools. We 59 // want to make sure they are uniquly identified by adding in 60 // the creator's thread id into the filename. 61 sprintf(buf, "%s\\ar_event%d_%d.bin", outDir.str().c_str(), GetCurrentThreadId(), id); 62 mFilename = std::string(buf); 63#else 64 char buf[255]; 65 // There could be multiple threads creating thread pools. We 66 // want to make sure they are uniquly identified by adding in 67 // the creator's thread id into the filename. 68 sprintf(buf, "%s/ar_event%d_%d.bin", "/tmp", GetCurrentThreadId(), id); 69 mFilename = std::string(buf); 70#endif 71 } 72 73 virtual ~EventHandlerFile() 74 { 75 FlushBuffer(); 76 } 77 78 ////////////////////////////////////////////////////////////////////////// 79 /// @brief Flush buffer to file. 80 bool FlushBuffer() 81 { 82 if (mBufOffset > 0) 83 { 84 if (mBufOffset == mHeaderBufOffset) 85 { 86 // Nothing to flush. Only header has been generated. 87 return false; 88 } 89 90 std::ofstream file; 91 file.open(mFilename, std::ios::out | std::ios::app | std::ios::binary); 92 93 if (!file.is_open()) 94 { 95 SWR_ASSERT(0, "ArchRast: Could not open event file!"); 96 return false; 97 } 98 99 file.write((char*)mBuffer, mBufOffset); 100 file.close(); 101 102 mBufOffset = 0; 103 mHeaderBufOffset = 0; // Reset header offset so its no longer considered. 104 } 105 return true; 106 } 107 108 ////////////////////////////////////////////////////////////////////////// 109 /// @brief Write event and its payload to the memory buffer. 110 void Write(uint32_t eventId, const char* pBlock, uint32_t size) 111 { 112 if ((mBufOffset + size + sizeof(eventId)) > mBufferSize) 113 { 114 if (!FlushBuffer()) 115 { 116 // Don't corrupt what's already in the buffer? 117 /// @todo Maybe add corrupt marker to buffer here in case we can open file in future? 118 return; 119 } 120 } 121 122 memcpy(&mBuffer[mBufOffset], (char*)&eventId, sizeof(eventId)); 123 mBufOffset += sizeof(eventId); 124 memcpy(&mBuffer[mBufOffset], pBlock, size); 125 mBufOffset += size; 126 } 127 128% for name in protos['event_names']: 129 ////////////////////////////////////////////////////////////////////////// 130 /// @brief Handle ${name} event 131 virtual void Handle(${name} event) 132 { 133% if protos['events'][name]['num_fields'] == 0: 134 Write(${protos['events'][name]['event_id']}, (char*)&event.data, 0); 135% else: 136 Write(${protos['events'][name]['event_id']}, (char*)&event.data, sizeof(event.data)); 137%endif 138 } 139% endfor 140 141 ////////////////////////////////////////////////////////////////////////// 142 /// @brief Everything written to buffer this point is the header. 143 virtual void MarkHeader() 144 { 145 mHeaderBufOffset = mBufOffset; 146 } 147 148 std::string mFilename; 149 150 static const uint32_t mBufferSize = 1024; 151 uint8_t mBuffer[mBufferSize]; 152 uint32_t mBufOffset{0}; 153 uint32_t mHeaderBufOffset{0}; 154 }; 155} 156