event.cc revision 12334
112855Sgabeblack@google.com/* 212855Sgabeblack@google.com * Copyright (c) 2017 ARM Limited 312855Sgabeblack@google.com * All rights reserved 412855Sgabeblack@google.com * 512855Sgabeblack@google.com * The license below extends only to copyright in the software and shall 612855Sgabeblack@google.com * not be construed as granting a license to any other intellectual 712855Sgabeblack@google.com * property including but not limited to intellectual property relating 812855Sgabeblack@google.com * to a hardware implementation of the functionality of the software 912855Sgabeblack@google.com * licensed hereunder. You may use the software subject to the license 1012855Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated 1112855Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software, 1212855Sgabeblack@google.com * modified or unmodified, in source code or in binary form. 1312855Sgabeblack@google.com * 1412855Sgabeblack@google.com * Copyright (c) 2006 The Regents of The University of Michigan 1512855Sgabeblack@google.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 1612855Sgabeblack@google.com * Copyright (c) 2013 Mark D. Hill and David A. Wood 1712855Sgabeblack@google.com * All rights reserved. 1812855Sgabeblack@google.com * 1912855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 2012855Sgabeblack@google.com * modification, are permitted provided that the following conditions are 2112855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 2212855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 2312855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 2412855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 2512855Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 2612855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 2712855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 2812855Sgabeblack@google.com * this software without specific prior written permission. 2912855Sgabeblack@google.com * 3012855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3112855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3212855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3312855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3412855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3512855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3612855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3712855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3812855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3912855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 4012855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4112855Sgabeblack@google.com * 4212855Sgabeblack@google.com * Authors: Nathan Binkert 4312855Sgabeblack@google.com * Andreas Sandberg 4412855Sgabeblack@google.com */ 4512855Sgabeblack@google.com 4612855Sgabeblack@google.com#include "pybind11/pybind11.h" 4712855Sgabeblack@google.com#include "pybind11/stl.h" 4812855Sgabeblack@google.com 4912855Sgabeblack@google.com#include "base/logging.hh" 5012855Sgabeblack@google.com#include "sim/eventq.hh" 5112855Sgabeblack@google.com#include "sim/sim_events.hh" 5212855Sgabeblack@google.com#include "sim/sim_exit.hh" 5312855Sgabeblack@google.com#include "sim/simulate.hh" 5412855Sgabeblack@google.com 5512855Sgabeblack@google.comnamespace py = pybind11; 5612855Sgabeblack@google.com 5712855Sgabeblack@google.com 5812855Sgabeblack@google.com/** 5912855Sgabeblack@google.com * PyBind wrapper for Events 6012855Sgabeblack@google.com * 6112855Sgabeblack@google.com * We need to wrap the Event class with some Python glue code to 6212855Sgabeblack@google.com * enable method overrides in Python and memory management. Unlike its 6312855Sgabeblack@google.com * C++ cousin, PyEvents need to override __call__ instead of 6412855Sgabeblack@google.com * Event::process(). 6512855Sgabeblack@google.com * 6612855Sgabeblack@google.com * Memory management is done using reference counting in Python. 6712855Sgabeblack@google.com */ 6812855Sgabeblack@google.comclass PyEvent : public Event 6912855Sgabeblack@google.com{ 7012855Sgabeblack@google.com public: 7112855Sgabeblack@google.com PyEvent(Event::Priority priority) 7212855Sgabeblack@google.com : Event(priority, Event::Managed) 7312855Sgabeblack@google.com { 7412855Sgabeblack@google.com } 7512855Sgabeblack@google.com 7612855Sgabeblack@google.com void process() override { 7712855Sgabeblack@google.com // Call the Python implementation as __call__. This provides a 7812855Sgabeblack@google.com // slightly more Python-friendly interface. 7912855Sgabeblack@google.com PYBIND11_OVERLOAD_PURE_NAME(void, PyEvent, "__call__", process); 8012855Sgabeblack@google.com } 8112855Sgabeblack@google.com 8212855Sgabeblack@google.com protected: 8312855Sgabeblack@google.com void acquireImpl() override { 8412855Sgabeblack@google.com py::object obj = py::cast(this); 8512855Sgabeblack@google.com 8612855Sgabeblack@google.com if (obj) { 8712855Sgabeblack@google.com obj.inc_ref(); 8812855Sgabeblack@google.com } else { 8912855Sgabeblack@google.com panic("Failed to get PyBind object to increase ref count\n"); 9012855Sgabeblack@google.com } 9112855Sgabeblack@google.com } 9212855Sgabeblack@google.com 9312855Sgabeblack@google.com void releaseImpl() override { 9412855Sgabeblack@google.com py::object obj = py::cast(this); 9512855Sgabeblack@google.com 9612855Sgabeblack@google.com if (obj) { 9712855Sgabeblack@google.com obj.dec_ref(); 9812855Sgabeblack@google.com } else { 9912855Sgabeblack@google.com panic("Failed to get PyBind object to decrease ref count\n"); 10012855Sgabeblack@google.com } 10112855Sgabeblack@google.com } 10212855Sgabeblack@google.com}; 10312855Sgabeblack@google.com 10412855Sgabeblack@google.comvoid 10512855Sgabeblack@google.compybind_init_event(py::module &m_native) 10612855Sgabeblack@google.com{ 10712855Sgabeblack@google.com py::module m = m_native.def_submodule("event"); 10812855Sgabeblack@google.com 10912855Sgabeblack@google.com m.def("simulate", &simulate, 11012855Sgabeblack@google.com py::arg("ticks") = MaxTick); 11112855Sgabeblack@google.com m.def("exitSimLoop", &exitSimLoop); 11212855Sgabeblack@google.com m.def("getEventQueue", []() { return curEventQueue(); }, 11312855Sgabeblack@google.com py::return_value_policy::reference); 11412855Sgabeblack@google.com m.def("setEventQueue", [](EventQueue *q) { return curEventQueue(q); }); 11512855Sgabeblack@google.com m.def("getEventQueue", &getEventQueue, 11612855Sgabeblack@google.com py::return_value_policy::reference); 11712855Sgabeblack@google.com 11812855Sgabeblack@google.com py::class_<EventQueue>(m, "EventQueue") 11912855Sgabeblack@google.com .def("name", [](EventQueue *eq) { return eq->name(); }) 12012855Sgabeblack@google.com .def("dump", &EventQueue::dump) 12112855Sgabeblack@google.com .def("schedule", [](EventQueue *eq, PyEvent *e, Tick t) { 12212855Sgabeblack@google.com eq->schedule(e, t); 12312855Sgabeblack@google.com }, py::arg("event"), py::arg("when")) 12412855Sgabeblack@google.com .def("deschedule", &EventQueue::deschedule, 12512855Sgabeblack@google.com py::arg("event")) 12612855Sgabeblack@google.com .def("reschedule", &EventQueue::reschedule, 12712855Sgabeblack@google.com py::arg("event"), py::arg("tick"), py::arg("always") = false) 12812855Sgabeblack@google.com ; 12912855Sgabeblack@google.com 13012855Sgabeblack@google.com // TODO: Ownership of global exit events has always been a bit 13112855Sgabeblack@google.com // questionable. We currently assume they are owned by the C++ 13212855Sgabeblack@google.com // world. This is what the old SWIG code did, but that will result 13312855Sgabeblack@google.com // in memory leaks. 13412855Sgabeblack@google.com py::class_<GlobalSimLoopExitEvent, 13512855Sgabeblack@google.com std::unique_ptr<GlobalSimLoopExitEvent, py::nodelete>>( 13612855Sgabeblack@google.com m, "GlobalSimLoopExitEvent") 13712855Sgabeblack@google.com .def("getCause", &GlobalSimLoopExitEvent::getCause) 13812855Sgabeblack@google.com .def("getCode", [](GlobalSimLoopExitEvent *e) { 13912855Sgabeblack@google.com return py::reinterpret_steal<py::object>( 14012855Sgabeblack@google.com PyInt_FromLong(e->getCode())); 14112855Sgabeblack@google.com }) 14212855Sgabeblack@google.com ; 14312855Sgabeblack@google.com 14412855Sgabeblack@google.com // Event base class. These should never be returned directly to 14512855Sgabeblack@google.com // Python since they don't have a well-defined life cycle. Python 14612855Sgabeblack@google.com // events should be derived from PyEvent instead. 14712855Sgabeblack@google.com py::class_<Event> c_event( 148 m, "Event"); 149 c_event 150 .def("name", &Event::name) 151 .def("dump", &Event::dump) 152 .def("scheduled", &Event::scheduled) 153 .def("squash", &Event::squash) 154 .def("squashed", &Event::squashed) 155 .def("isExitEvent", &Event::isExitEvent) 156 .def("when", &Event::when) 157 .def("priority", &Event::priority) 158 ; 159 160 py::class_<PyEvent, Event>(m, "PyEvent") 161 .def(py::init<Event::Priority>(), 162 py::arg("priority") = (int)Event::Default_Pri) 163 ; 164 165#define PRIO(n) c_event.attr(# n) = py::cast((int)Event::n) 166 PRIO(Minimum_Pri); 167 PRIO(Minimum_Pri); 168 PRIO(Debug_Enable_Pri); 169 PRIO(Debug_Break_Pri); 170 PRIO(CPU_Switch_Pri); 171 PRIO(Delayed_Writeback_Pri); 172 PRIO(Default_Pri); 173 PRIO(DVFS_Update_Pri); 174 PRIO(Serialize_Pri); 175 PRIO(CPU_Tick_Pri); 176 PRIO(Stat_Event_Pri); 177 PRIO(Progress_Event_Pri); 178 PRIO(Sim_Exit_Pri); 179 PRIO(Maximum_Pri); 180} 181