event.cc revision 13621
111988Sandreas.sandberg@arm.com/* 211988Sandreas.sandberg@arm.com * Copyright (c) 2017 ARM Limited 311988Sandreas.sandberg@arm.com * All rights reserved 411988Sandreas.sandberg@arm.com * 511988Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 611988Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 711988Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 811988Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 911988Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1011988Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1111988Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1211988Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1311988Sandreas.sandberg@arm.com * 1411988Sandreas.sandberg@arm.com * Copyright (c) 2006 The Regents of The University of Michigan 1511988Sandreas.sandberg@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 1611988Sandreas.sandberg@arm.com * Copyright (c) 2013 Mark D. Hill and David A. Wood 1711988Sandreas.sandberg@arm.com * All rights reserved. 1811988Sandreas.sandberg@arm.com * 1911988Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 2011988Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 2111988Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 2211988Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 2311988Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 2411988Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 2511988Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 2611988Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 2711988Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 2811988Sandreas.sandberg@arm.com * this software without specific prior written permission. 2911988Sandreas.sandberg@arm.com * 3011988Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3111988Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3211988Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3311988Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3411988Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3511988Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3611988Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3711988Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3811988Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3911988Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 4011988Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4111988Sandreas.sandberg@arm.com * 4211988Sandreas.sandberg@arm.com * Authors: Nathan Binkert 4311988Sandreas.sandberg@arm.com * Andreas Sandberg 4411988Sandreas.sandberg@arm.com */ 4511988Sandreas.sandberg@arm.com 4611988Sandreas.sandberg@arm.com#include "pybind11/pybind11.h" 4711988Sandreas.sandberg@arm.com#include "pybind11/stl.h" 4811988Sandreas.sandberg@arm.com 4912334Sgabeblack@google.com#include "base/logging.hh" 5011988Sandreas.sandberg@arm.com#include "sim/eventq.hh" 5111988Sandreas.sandberg@arm.com#include "sim/sim_events.hh" 5211988Sandreas.sandberg@arm.com#include "sim/sim_exit.hh" 5311988Sandreas.sandberg@arm.com#include "sim/simulate.hh" 5411988Sandreas.sandberg@arm.com 5511988Sandreas.sandberg@arm.comnamespace py = pybind11; 5611988Sandreas.sandberg@arm.com 5712041Sandreas.sandberg@arm.com 5811988Sandreas.sandberg@arm.com/** 5911988Sandreas.sandberg@arm.com * PyBind wrapper for Events 6011988Sandreas.sandberg@arm.com * 6111988Sandreas.sandberg@arm.com * We need to wrap the Event class with some Python glue code to 6211988Sandreas.sandberg@arm.com * enable method overrides in Python and memory management. Unlike its 6311988Sandreas.sandberg@arm.com * C++ cousin, PyEvents need to override __call__ instead of 6411988Sandreas.sandberg@arm.com * Event::process(). 6511988Sandreas.sandberg@arm.com * 6612041Sandreas.sandberg@arm.com * Memory management is done using reference counting in Python. 6711988Sandreas.sandberg@arm.com */ 6811988Sandreas.sandberg@arm.comclass PyEvent : public Event 6911988Sandreas.sandberg@arm.com{ 7011988Sandreas.sandberg@arm.com public: 7111988Sandreas.sandberg@arm.com PyEvent(Event::Priority priority) 7212041Sandreas.sandberg@arm.com : Event(priority, Event::Managed) 7312041Sandreas.sandberg@arm.com { 7412041Sandreas.sandberg@arm.com } 7511988Sandreas.sandberg@arm.com 7611988Sandreas.sandberg@arm.com void process() override { 7711988Sandreas.sandberg@arm.com // Call the Python implementation as __call__. This provides a 7811988Sandreas.sandberg@arm.com // slightly more Python-friendly interface. 7911988Sandreas.sandberg@arm.com PYBIND11_OVERLOAD_PURE_NAME(void, PyEvent, "__call__", process); 8011988Sandreas.sandberg@arm.com } 8112041Sandreas.sandberg@arm.com 8212041Sandreas.sandberg@arm.com protected: 8312041Sandreas.sandberg@arm.com void acquireImpl() override { 8412041Sandreas.sandberg@arm.com py::object obj = py::cast(this); 8512041Sandreas.sandberg@arm.com 8612041Sandreas.sandberg@arm.com if (obj) { 8712041Sandreas.sandberg@arm.com obj.inc_ref(); 8812041Sandreas.sandberg@arm.com } else { 8912041Sandreas.sandberg@arm.com panic("Failed to get PyBind object to increase ref count\n"); 9012041Sandreas.sandberg@arm.com } 9112041Sandreas.sandberg@arm.com } 9212041Sandreas.sandberg@arm.com 9312041Sandreas.sandberg@arm.com void releaseImpl() override { 9412041Sandreas.sandberg@arm.com py::object obj = py::cast(this); 9512041Sandreas.sandberg@arm.com 9612041Sandreas.sandberg@arm.com if (obj) { 9712041Sandreas.sandberg@arm.com obj.dec_ref(); 9812041Sandreas.sandberg@arm.com } else { 9912041Sandreas.sandberg@arm.com panic("Failed to get PyBind object to decrease ref count\n"); 10012041Sandreas.sandberg@arm.com } 10112041Sandreas.sandberg@arm.com } 10211988Sandreas.sandberg@arm.com}; 10311988Sandreas.sandberg@arm.com 10411988Sandreas.sandberg@arm.comvoid 10511988Sandreas.sandberg@arm.compybind_init_event(py::module &m_native) 10611988Sandreas.sandberg@arm.com{ 10711988Sandreas.sandberg@arm.com py::module m = m_native.def_submodule("event"); 10811988Sandreas.sandberg@arm.com 10911988Sandreas.sandberg@arm.com m.def("simulate", &simulate, 11011988Sandreas.sandberg@arm.com py::arg("ticks") = MaxTick); 11111988Sandreas.sandberg@arm.com m.def("exitSimLoop", &exitSimLoop); 11211988Sandreas.sandberg@arm.com m.def("getEventQueue", []() { return curEventQueue(); }, 11311988Sandreas.sandberg@arm.com py::return_value_policy::reference); 11411988Sandreas.sandberg@arm.com m.def("setEventQueue", [](EventQueue *q) { return curEventQueue(q); }); 11511988Sandreas.sandberg@arm.com m.def("getEventQueue", &getEventQueue, 11611988Sandreas.sandberg@arm.com py::return_value_policy::reference); 11711988Sandreas.sandberg@arm.com 11811988Sandreas.sandberg@arm.com py::class_<EventQueue>(m, "EventQueue") 11911988Sandreas.sandberg@arm.com .def("name", [](EventQueue *eq) { return eq->name(); }) 12011988Sandreas.sandberg@arm.com .def("dump", &EventQueue::dump) 12111988Sandreas.sandberg@arm.com .def("schedule", [](EventQueue *eq, PyEvent *e, Tick t) { 12211988Sandreas.sandberg@arm.com eq->schedule(e, t); 12311988Sandreas.sandberg@arm.com }, py::arg("event"), py::arg("when")) 12412041Sandreas.sandberg@arm.com .def("deschedule", &EventQueue::deschedule, 12512041Sandreas.sandberg@arm.com py::arg("event")) 12612041Sandreas.sandberg@arm.com .def("reschedule", &EventQueue::reschedule, 12712041Sandreas.sandberg@arm.com py::arg("event"), py::arg("tick"), py::arg("always") = false) 12811988Sandreas.sandberg@arm.com ; 12911988Sandreas.sandberg@arm.com 13011988Sandreas.sandberg@arm.com // TODO: Ownership of global exit events has always been a bit 13111988Sandreas.sandberg@arm.com // questionable. We currently assume they are owned by the C++ 13212041Sandreas.sandberg@arm.com // world. This is what the old SWIG code did, but that will result 13311988Sandreas.sandberg@arm.com // in memory leaks. 13411988Sandreas.sandberg@arm.com py::class_<GlobalSimLoopExitEvent, 13511988Sandreas.sandberg@arm.com std::unique_ptr<GlobalSimLoopExitEvent, py::nodelete>>( 13611988Sandreas.sandberg@arm.com m, "GlobalSimLoopExitEvent") 13711988Sandreas.sandberg@arm.com .def("getCause", &GlobalSimLoopExitEvent::getCause) 13813621Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION >= 3 13913621Sandreas.sandberg@arm.com .def("getCode", &GlobalSimLoopExitEvent::getCode) 14013621Sandreas.sandberg@arm.com#else 14113621Sandreas.sandberg@arm.com // Workaround for an issue where PyBind11 converts the exit 14213621Sandreas.sandberg@arm.com // code to a long. This is normally fine, but sys.exit treats 14313621Sandreas.sandberg@arm.com // any non-int type as an error and exits with status 1 if it 14413621Sandreas.sandberg@arm.com // is passed a long. 14512172Sandreas.sandberg@arm.com .def("getCode", [](GlobalSimLoopExitEvent *e) { 14612172Sandreas.sandberg@arm.com return py::reinterpret_steal<py::object>( 14712172Sandreas.sandberg@arm.com PyInt_FromLong(e->getCode())); 14812172Sandreas.sandberg@arm.com }) 14913621Sandreas.sandberg@arm.com#endif 15011988Sandreas.sandberg@arm.com ; 15111988Sandreas.sandberg@arm.com 15212041Sandreas.sandberg@arm.com // Event base class. These should never be returned directly to 15312041Sandreas.sandberg@arm.com // Python since they don't have a well-defined life cycle. Python 15412041Sandreas.sandberg@arm.com // events should be derived from PyEvent instead. 15512041Sandreas.sandberg@arm.com py::class_<Event> c_event( 15612041Sandreas.sandberg@arm.com m, "Event"); 15711988Sandreas.sandberg@arm.com c_event 15811988Sandreas.sandberg@arm.com .def("name", &Event::name) 15911988Sandreas.sandberg@arm.com .def("dump", &Event::dump) 16011988Sandreas.sandberg@arm.com .def("scheduled", &Event::scheduled) 16111988Sandreas.sandberg@arm.com .def("squash", &Event::squash) 16211988Sandreas.sandberg@arm.com .def("squashed", &Event::squashed) 16311988Sandreas.sandberg@arm.com .def("isExitEvent", &Event::isExitEvent) 16411988Sandreas.sandberg@arm.com .def("when", &Event::when) 16511988Sandreas.sandberg@arm.com .def("priority", &Event::priority) 16611988Sandreas.sandberg@arm.com ; 16711988Sandreas.sandberg@arm.com 16812041Sandreas.sandberg@arm.com py::class_<PyEvent, Event>(m, "PyEvent") 16912041Sandreas.sandberg@arm.com .def(py::init<Event::Priority>(), 17012041Sandreas.sandberg@arm.com py::arg("priority") = (int)Event::Default_Pri) 17112041Sandreas.sandberg@arm.com ; 17212041Sandreas.sandberg@arm.com 17311988Sandreas.sandberg@arm.com#define PRIO(n) c_event.attr(# n) = py::cast((int)Event::n) 17411988Sandreas.sandberg@arm.com PRIO(Minimum_Pri); 17511988Sandreas.sandberg@arm.com PRIO(Minimum_Pri); 17611988Sandreas.sandberg@arm.com PRIO(Debug_Enable_Pri); 17711988Sandreas.sandberg@arm.com PRIO(Debug_Break_Pri); 17811988Sandreas.sandberg@arm.com PRIO(CPU_Switch_Pri); 17911988Sandreas.sandberg@arm.com PRIO(Delayed_Writeback_Pri); 18011988Sandreas.sandberg@arm.com PRIO(Default_Pri); 18111988Sandreas.sandberg@arm.com PRIO(DVFS_Update_Pri); 18211988Sandreas.sandberg@arm.com PRIO(Serialize_Pri); 18311988Sandreas.sandberg@arm.com PRIO(CPU_Tick_Pri); 18411988Sandreas.sandberg@arm.com PRIO(Stat_Event_Pri); 18511988Sandreas.sandberg@arm.com PRIO(Progress_Event_Pri); 18611988Sandreas.sandberg@arm.com PRIO(Sim_Exit_Pri); 18711988Sandreas.sandberg@arm.com PRIO(Maximum_Pri); 18811988Sandreas.sandberg@arm.com} 189