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 * Generation Command Line: 30 * ${'\n* '.join(cmdline)} 31 * 32 ******************************************************************************/ 33 #pragma once 34 35 #include "common/os.h" 36 #include "${event_header}" 37 #include <fstream> 38 #include <sstream> 39 #include <thread> 40 41 namespace ArchRast 42 { 43 ////////////////////////////////////////////////////////////////////////// 44 /// EventHandlerFile - interface for handling events. 45 ////////////////////////////////////////////////////////////////////////// 46 class EventHandlerFile : public EventHandler 47 { 48 public: EventHandlerFile(uint32_t id)49 EventHandlerFile(uint32_t id) 50 : mBufOffset(0) 51 { 52 #if defined(_WIN32) 53 DWORD pid = GetCurrentProcessId(); 54 TCHAR procname[MAX_PATH]; 55 GetModuleFileName(NULL, procname, MAX_PATH); 56 const char* pBaseName = strrchr(procname, '\\'); 57 std::stringstream outDir; 58 outDir << KNOB_DEBUG_OUTPUT_DIR << pBaseName << "_" << pid << std::ends; 59 CreateDirectory(outDir.str().c_str(), NULL); 60 61 // There could be multiple threads creating thread pools. We 62 // want to make sure they are uniquly identified by adding in 63 // the creator's thread id into the filename. 64 std::stringstream fstr; 65 fstr << outDir.str().c_str() << "\\ar_event" << std::this_thread::get_id(); 66 fstr << "_" << id << ".bin" << std::ends; 67 mFilename = fstr.str(); 68 #else 69 // There could be multiple threads creating thread pools. We 70 // want to make sure they are uniquly identified by adding in 71 // the creator's thread id into the filename. 72 std::stringstream fstr; 73 fstr << "/tmp/ar_event" << std::this_thread::get_id(); 74 fstr << "_" << id << ".bin" << std::ends; 75 mFilename = fstr.str(); 76 #endif 77 } 78 ~EventHandlerFile()79 virtual ~EventHandlerFile() 80 { 81 FlushBuffer(); 82 } 83 84 ////////////////////////////////////////////////////////////////////////// 85 /// @brief Flush buffer to file. FlushBuffer()86 bool FlushBuffer() 87 { 88 if (mBufOffset > 0) 89 { 90 if (mBufOffset == mHeaderBufOffset) 91 { 92 // Nothing to flush. Only header has been generated. 93 return false; 94 } 95 96 std::ofstream file; 97 file.open(mFilename, std::ios::out | std::ios::app | std::ios::binary); 98 99 if (!file.is_open()) 100 { 101 SWR_INVALID("ArchRast: Could not open event file!"); 102 return false; 103 } 104 105 file.write((char*)mBuffer, mBufOffset); 106 file.close(); 107 108 mBufOffset = 0; 109 mHeaderBufOffset = 0; // Reset header offset so its no longer considered. 110 } 111 return true; 112 } 113 114 ////////////////////////////////////////////////////////////////////////// 115 /// @brief Write event and its payload to the memory buffer. Write(uint32_t eventId,const char * pBlock,uint32_t size)116 void Write(uint32_t eventId, const char* pBlock, uint32_t size) 117 { 118 if ((mBufOffset + size + sizeof(eventId)) > mBufferSize) 119 { 120 if (!FlushBuffer()) 121 { 122 // Don't corrupt what's already in the buffer? 123 /// @todo Maybe add corrupt marker to buffer here in case we can open file in future? 124 return; 125 } 126 } 127 128 memcpy(&mBuffer[mBufOffset], (char*)&eventId, sizeof(eventId)); 129 mBufOffset += sizeof(eventId); 130 memcpy(&mBuffer[mBufOffset], pBlock, size); 131 mBufOffset += size; 132 } 133 134 % for name in protos['event_names']: 135 ////////////////////////////////////////////////////////////////////////// 136 /// @brief Handle ${name} event 137 virtual void Handle(const ${name}& event) 138 { 139 % if protos['events'][name]['num_fields'] == 0: 140 Write(${protos['events'][name]['event_id']}, (char*)&event.data, 0); 141 % else: 142 Write(${protos['events'][name]['event_id']}, (char*)&event.data, sizeof(event.data)); 143 %endif 144 } 145 % endfor 146 147 ////////////////////////////////////////////////////////////////////////// 148 /// @brief Everything written to buffer this point is the header. 149 virtual void MarkHeader() 150 { 151 mHeaderBufOffset = mBufOffset; 152 } 153 154 std::string mFilename; 155 156 static const uint32_t mBufferSize = 1024; 157 uint8_t mBuffer[mBufferSize]; 158 uint32_t mBufOffset{0}; 159 uint32_t mHeaderBufOffset{0}; 160 }; 161 } 162