event.cc revision 11988
17860SN/A/* 27860SN/A * Copyright (c) 2017 ARM Limited 37860SN/A * All rights reserved 48835SAli.Saidi@ARM.com * 57935SN/A * The license below extends only to copyright in the software and shall 67935SN/A * not be construed as granting a license to any other intellectual 77935SN/A * property including but not limited to intellectual property relating 87860SN/A * to a hardware implementation of the functionality of the software 97860SN/A * licensed hereunder. You may use the software subject to the license 107860SN/A * terms below provided that you ensure that this notice is replicated 117860SN/A * unmodified and in its entirety in all distributions of the software, 128835SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form. 139265SAli.Saidi@ARM.com * 148835SAli.Saidi@ARM.com * Copyright (c) 2006 The Regents of The University of Michigan 158835SAli.Saidi@ARM.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 168835SAli.Saidi@ARM.com * Copyright (c) 2013 Mark D. Hill and David A. Wood 177860SN/A * All rights reserved. 188721SN/A * 198721SN/A * Redistribution and use in source and binary forms, with or without 208835SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 218835SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 227935SN/A * notice, this list of conditions and the following disclaimer; 237935SN/A * redistributions in binary form must reproduce the above copyright 247935SN/A * notice, this list of conditions and the following disclaimer in the 257935SN/A * documentation and/or other materials provided with the distribution; 267935SN/A * neither the name of the copyright holders nor the names of its 277935SN/A * contributors may be used to endorse or promote products derived from 287935SN/A * this software without specific prior written permission. 298893Ssaidi@eecs.umich.edu * 307860SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 317860SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 327860SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 338835SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 347860SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 357860SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 367860SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 377860SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 387860SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 398835SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 407860SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 417860SN/A * 427860SN/A * Authors: Nathan Binkert 437860SN/A * Andreas Sandberg 448835SAli.Saidi@ARM.com */ 457860SN/A 467860SN/A#include "pybind11/pybind11.h" 477860SN/A#include "pybind11/stl.h" 487860SN/A 497860SN/A#include "sim/eventq.hh" 507860SN/A#include "sim/sim_events.hh" 518835SAli.Saidi@ARM.com#include "sim/sim_exit.hh" 527860SN/A#include "sim/simulate.hh" 537860SN/A 547860SN/Anamespace py = pybind11; 557860SN/A 567860SN/A/** 577860SN/A * PyBind wrapper for Events 587860SN/A * 597860SN/A * We need to wrap the Event class with some Python glue code to 607860SN/A * enable method overrides in Python and memory management. Unlike its 618893Ssaidi@eecs.umich.edu * C++ cousin, PyEvents need to override __call__ instead of 627860SN/A * Event::process(). 637860SN/A * 649265SAli.Saidi@ARM.com * Memory management is mostly done using reference counting in 657860SN/A * Python. However, PyBind can't keep track of the reference the event 667860SN/A * queue holds to a scheduled event. We therefore need to inhibit 679265SAli.Saidi@ARM.com * deletion and hand over ownership to the event queue in case a 688150SN/A * scheduled event loses all of its Python references. 697860SN/A */ 707860SN/Aclass PyEvent : public Event 717860SN/A{ 728835SAli.Saidi@ARM.com public: 737860SN/A struct Deleter { 747860SN/A void operator()(PyEvent *ev) { 759265SAli.Saidi@ARM.com assert(!ev->isAutoDelete()); 767860SN/A if (ev->scheduled()) { 777860SN/A // The event is scheduled, give ownership to the event 788835SAli.Saidi@ARM.com // queue. 797860SN/A ev->setFlags(Event::AutoDelete); 807860SN/A } else { 817860SN/A // The event isn't scheduled, hence Python owns it and 827860SN/A // we need to free it here. 837860SN/A delete ev; 848893Ssaidi@eecs.umich.edu } 857860SN/A } 867860SN/A }; 877860SN/A 888835SAli.Saidi@ARM.com PyEvent(Event::Priority priority) 897860SN/A : Event(priority) 908835SAli.Saidi@ARM.com { } 918835SAli.Saidi@ARM.com 928835SAli.Saidi@ARM.com void process() override { 938835SAli.Saidi@ARM.com if (isAutoDelete()) { 949265SAli.Saidi@ARM.com // Ownership of the event was handed over to the event queue 959265SAli.Saidi@ARM.com // because the last revference in Python land was GCed. We 968835SAli.Saidi@ARM.com // need to claim the object again since we're creating a new 978893Ssaidi@eecs.umich.edu // Python reference. 987860SN/A clearFlags(AutoDelete); 997860SN/A } 1007860SN/A 1018893Ssaidi@eecs.umich.edu // Call the Python implementation as __call__. This provides a 1027860SN/A // slightly more Python-friendly interface. 1037860SN/A PYBIND11_OVERLOAD_PURE_NAME(void, PyEvent, "__call__", process); 1049265SAli.Saidi@ARM.com } 1057860SN/A}; 1067860SN/A 1079265SAli.Saidi@ARM.comvoid 1088150SN/Apybind_init_event(py::module &m_native) 1097860SN/A{ 1107860SN/A py::module m = m_native.def_submodule("event"); 1117860SN/A 1128835SAli.Saidi@ARM.com m.def("simulate", &simulate, 1137860SN/A py::arg("ticks") = MaxTick); 1147860SN/A m.def("exitSimLoop", &exitSimLoop); 1159265SAli.Saidi@ARM.com m.def("getEventQueue", []() { return curEventQueue(); }, 1167860SN/A py::return_value_policy::reference); 1177860SN/A m.def("setEventQueue", [](EventQueue *q) { return curEventQueue(q); }); 1188835SAli.Saidi@ARM.com m.def("getEventQueue", &getEventQueue, 1197860SN/A py::return_value_policy::reference); 1207860SN/A 1217860SN/A py::class_<EventQueue>(m, "EventQueue") 1227860SN/A .def("name", [](EventQueue *eq) { return eq->name(); }) 1237860SN/A .def("dump", &EventQueue::dump) 1248893Ssaidi@eecs.umich.edu .def("schedule", [](EventQueue *eq, PyEvent *e, Tick t) { 1257860SN/A eq->schedule(e, t); 1268835SAli.Saidi@ARM.com }, py::arg("event"), py::arg("when")) 1278835SAli.Saidi@ARM.com .def("deschedule", [](EventQueue *eq, PyEvent *e) { 1288835SAli.Saidi@ARM.com eq->deschedule(e); 1297860SN/A }, py::arg("event")) 1307860SN/A .def("reschedule", [](EventQueue *eq, PyEvent *e, Tick t, bool alw) { 1318835SAli.Saidi@ARM.com eq->reschedule(e, t, alw); 1327860SN/A }, py::arg("event"), py::arg("tick"), py::arg("always") = false) 1338835SAli.Saidi@ARM.com ; 1348835SAli.Saidi@ARM.com 1358835SAli.Saidi@ARM.com // TODO: Ownership of global exit events has always been a bit 1368835SAli.Saidi@ARM.com // questionable. We currently assume they are owned by the C++ 1379265SAli.Saidi@ARM.com // word. This is what the old SWIG code did, but that will result 1389265SAli.Saidi@ARM.com // in memory leaks. 1398835SAli.Saidi@ARM.com py::class_<GlobalSimLoopExitEvent, 1408893Ssaidi@eecs.umich.edu std::unique_ptr<GlobalSimLoopExitEvent, py::nodelete>>( 1417860SN/A m, "GlobalSimLoopExitEvent") 1427860SN/A .def("getCause", &GlobalSimLoopExitEvent::getCause) 1437860SN/A .def("getCode", &GlobalSimLoopExitEvent::getCode) 1448893Ssaidi@eecs.umich.edu ; 1457860SN/A 1467860SN/A // TODO: We currently export a wrapper class and not the Event 1479265SAli.Saidi@ARM.com // base class. This wil be problematic if we ever return an event 1487860SN/A // from C++. 1497860SN/A py::class_<PyEvent, std::unique_ptr<PyEvent, PyEvent::Deleter>> 1509265SAli.Saidi@ARM.com c_event(m, "Event"); 1518150SN/A c_event 1527860SN/A .def(py::init<Event::Priority>(), 1537860SN/A py::arg("priority") = (int)Event::Default_Pri) 1547860SN/A .def("name", &Event::name) 1558835SAli.Saidi@ARM.com .def("dump", &Event::dump) 1567860SN/A .def("scheduled", &Event::scheduled) 1577860SN/A .def("squash", &Event::squash) 1589265SAli.Saidi@ARM.com .def("squashed", &Event::squashed) 1597860SN/A .def("isExitEvent", &Event::isExitEvent) 1607860SN/A .def("isAutoDelete", &Event::isAutoDelete) 1618835SAli.Saidi@ARM.com .def("when", &Event::when) 1627860SN/A .def("priority", &Event::priority) 1637860SN/A ; 1647860SN/A 1657860SN/A#define PRIO(n) c_event.attr(# n) = py::cast((int)Event::n) 1668893Ssaidi@eecs.umich.edu PRIO(Minimum_Pri); 1678893Ssaidi@eecs.umich.edu PRIO(Minimum_Pri); 1687860SN/A PRIO(Debug_Enable_Pri); 1697860SN/A PRIO(Debug_Break_Pri); 1709055Ssaidi@eecs.umich.edu PRIO(CPU_Switch_Pri); 1717860SN/A PRIO(Delayed_Writeback_Pri); 1727860SN/A PRIO(Default_Pri); 1737860SN/A PRIO(DVFS_Update_Pri); 1747860SN/A PRIO(Serialize_Pri); 1759096Sandreas.hansson@arm.com PRIO(CPU_Tick_Pri); 1768893Ssaidi@eecs.umich.edu PRIO(Stat_Event_Pri); 1778893Ssaidi@eecs.umich.edu PRIO(Progress_Event_Pri); 1787860SN/A PRIO(Sim_Exit_Pri); 1797860SN/A PRIO(Maximum_Pri); 1807860SN/A} 1817860SN/A