• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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