• 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******************************************************************************/
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