| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <meta http-equiv="x-ua-compatible" content="ie=edge"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| |
| <title>gem5</title> |
| |
| <!-- SITE FAVICON --> |
| <link rel="shortcut icon" type="image/gif" href="/assets/img/gem5ColorVert.gif"/> |
| |
| <link rel="canonical" href="http://localhost:4000/events/"> |
| <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,700,800,600' rel='stylesheet' type='text/css'> |
| <link href='https://fonts.googleapis.com/css?family=Muli:400,300' rel='stylesheet' type='text/css'> |
| |
| <!-- FAVICON --> |
| <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> |
| |
| <!-- BOOTSTRAP --> |
| <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> |
| |
| <!-- CUSTOM CSS --> |
| <link rel="stylesheet" href="/css/main.css"> |
| </head> |
| |
| |
| <body> |
| <nav class="navbar navbar-expand-md navbar-light bg-light"> |
| <a class="navbar-brand" href="/"> |
| <img src="/assets/img/gem5ColorLong.gif" alt="gem5" height=45px> |
| </a> |
| <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation"> |
| <span class="navbar-toggler-icon"></span> |
| </button> |
| <div class="collapse navbar-collapse" id="navbarNavDropdown"> |
| <ul class="navbar-nav ml-auto"> |
| <li class="nav-item "> |
| <a class="nav-link" href="/">Home</a> |
| </li> |
| |
| <li class="nav-item dropdown "> |
| <a class="nav-link dropdown-toggle" href="/about" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
| About |
| </a> |
| <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> |
| <a class="dropdown-item" href="/about">About</a> |
| <a class="dropdown-item" href="/publications">Publications</a> |
| <a class="dropdown-item" href="/governance">Governance</a> |
| </div> |
| </li> |
| |
| <li class="nav-item dropdown active"> |
| <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
| Documentation |
| </a> |
| <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> |
| <!-- Pull navigation from _data/documentation.yml --> |
| |
| <a class="dropdown-item" href="/introduction">Introduction</a> |
| |
| <a class="dropdown-item" href="/building">Getting Started</a> |
| |
| <a class="dropdown-item" href="/environment">Modifying/Extending</a> |
| |
| <a class="dropdown-item" href="/MSIintro">Modeling Cache Coherence with Ruby</a> |
| |
| </div> |
| </li> |
| |
| <li class="nav-item "> |
| <a class="nav-link" href="/contributing">Contributing</a> |
| </li> |
| |
| <li class="nav-item "> |
| <a class="nav-link" href="/search">Search</a> |
| </li> |
| </ul> |
| </div> |
| </nav> |
| |
| <main> |
| <div class="sidenav-top"> |
| <img src="/assets/img/gem5ColorLong.gif" height="80"> |
| <div class="search"> |
| <form action="/search" method="get"> |
| <!-- <label for="search-box"><i class="fa fa-search"></i></label> --> |
| <input type="text" name="query"> |
| <button type="submit" name="submit"><i class="fa fa-search"></i></button> |
| </form> |
| </div> |
| </div> |
| <div class="sidenav"> |
| <!-- Pull navigation from _data/documentation.yml --> |
| |
| <a class="item" href="/introduction" role="button" aria-expanded="false" aria-controls="collapseExample"> |
| Introduction |
| </a> |
| <div class="collapse " id="introduction"> |
| |
| </div> |
| |
| <a class="item" data-toggle="collapse" href="#pt1" role="button" aria-expanded="false" aria-controls="collapseExample"> |
| Getting Started |
| </a> |
| <div class="collapse " id="pt1"> |
| |
| <a class="subitem " href="/building">Building gem5</a> |
| |
| <a class="subitem " href="/simple_config">Creating a simple configuration script</a> |
| |
| <a class="subitem " href="/cache_config">Adding cache to configuration script</a> |
| |
| <a class="subitem " href="/gem5_stats">Understanding gem5 statistics and output</a> |
| |
| <a class="subitem " href="/example_configs">Using the default configuration scripts</a> |
| |
| </div> |
| |
| <a class="item" data-toggle="collapse" href="#pt2" role="button" aria-expanded="false" aria-controls="collapseExample"> |
| Modifying/Extending |
| </a> |
| <div class="collapse show" id="pt2"> |
| |
| <a class="subitem " href="/environment">Setting up your development environment</a> |
| |
| <a class="subitem " href="/helloobject">Creating a very simple SimObject</a> |
| |
| <a class="subitem " href="/debugging">Debugging gem5</a> |
| |
| <a class="subitem active" href="/events">Event-driven programming</a> |
| |
| <a class="subitem " href="/parameters">Adding parameters to SimObjects and more events</a> |
| |
| <a class="subitem " href="/memoryobject">Creating SimObjects in the memory system</a> |
| |
| <a class="subitem " href="/simplecache">Creating a simple cache object</a> |
| |
| </div> |
| |
| <a class="item" data-toggle="collapse" href="#pt3" role="button" aria-expanded="false" aria-controls="collapseExample"> |
| Modeling Cache Coherence with Ruby |
| </a> |
| <div class="collapse " id="pt3"> |
| |
| <a class="subitem " href="/MSIintro">Introduction to Ruby</a> |
| |
| <a class="subitem " href="/cache-intro">MSI example cache protocol</a> |
| |
| <a class="subitem " href="/cache-declarations">Declaring a state machine</a> |
| |
| <a class="subitem " href="/cache-in-ports">In port code blocks</a> |
| |
| <a class="subitem " href="/cache-actions">Action code blocks</a> |
| |
| <a class="subitem " href="/cache-transitions">Transition code blocks</a> |
| |
| <a class="subitem " href="/directory">MSI Directory implementation</a> |
| |
| <a class="subitem " href="/MSIbuilding">Compiling a SLICC protocol</a> |
| |
| <a class="subitem " href="/configuration">Configuring a simple Ruby system</a> |
| |
| <a class="subitem " href="/running">Running the simple Ruby system</a> |
| |
| <a class="subitem " href="/MSIdebugging">Debugging SLICC Protocols</a> |
| |
| <a class="subitem " href="/simple-MI_example">Configuring for a standard protocol</a> |
| |
| </div> |
| |
| </div> |
| |
| <div class="container" id="doc-container"> |
| <div class="edit"><a href="https://github.com/new-website/tree/master/_pages/documentation/part2/events.md">Edit this page</a></div> |
| <dl> |
| <dt>authors</dt> |
| <dd>Jason Lowe-Power</dd> |
| </dl> |
| |
| <h1 id="event-driven-programming">Event-driven programming</h1> |
| |
| <p>gem5 is an event-driven simulator. In this chapter, we will explore how |
| to create and schedule events. We will be building from the simple |
| <code class="highlighter-rouge">HelloObject</code> from hello-simobject-chapter.</p> |
| |
| <h2 id="creating-a-simple-event-callback">Creating a simple event callback</h2> |
| |
| <p>In gem5’s event-driven model, each event has a callback function in |
| which the event is <em>processed</em>. Generally, this is a class that inherits |
| from :cppEvent. However, gem5 provides a wrapper function for creating |
| simple events.</p> |
| |
| <p>In the header file for our <code class="highlighter-rouge">HelloObject</code>, we simply need to declare a |
| new function that we want to execute every time the event fires |
| (<code class="highlighter-rouge">processEvent()</code>). This function must take no parameters and return |
| nothing.</p> |
| |
| <p>Next, we add an <code class="highlighter-rouge">Event</code> instance. In this case, we will use an |
| <code class="highlighter-rouge">EventFunctionWrapper</code> which allows us to execute any function.</p> |
| |
| <p>We also add a <code class="highlighter-rouge">startup()</code> function that will be explained below.</p> |
| |
| <p>``` {.sourceCode .c++} |
| class HelloObject : public SimObject |
| { |
| private: |
| void processEvent();</p> |
| |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>EventFunctionWrapper event; |
| </code></pre></div></div> |
| |
| <p>public: |
| HelloObject(HelloObjectParams *p);</p> |
| |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>void startup(); }; ``` |
| </code></pre></div></div> |
| |
| <p>Next, we must construct this event in the constructor of <code class="highlighter-rouge">HelloObject</code>. |
| The <code class="highlighter-rouge">EventFuntionWrapper</code> takes two parameters, a function to execute |
| and a name. The name is usually the name of the SimObject that owns the |
| event. When printing the name, there will be an automatic |
| “.wrapped_function_event” appended to the end of the name.</p> |
| |
| <p>The first parameter is simply a function that takes no parameters and |
| has no return value (<code class="highlighter-rouge">std::function<void(void)></code>). Usually, this is a |
| simple lambda function that calls a member function. However, it can be |
| any function you want. Below, we captute <code class="highlighter-rouge">this</code> in the lambda (<code class="highlighter-rouge">[this]</code>) |
| so we can call member functions of the instance of the class.</p> |
| |
| <p>``` {.sourceCode .c++} |
| HelloObject::HelloObject(HelloObjectParams *params) : |
| SimObject(params), event([this]{processEvent();}, name()) |
| { |
| DPRINTF(Hello, “Created the hello object\n”); |
| }</p> |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> |
| We also must define the implementation of the process function. In this |
| case, we'll simply print something if we are debugging. |
| |
| ``` {.sourceCode .c++} |
| void |
| HelloObject::processEvent() |
| { |
| DPRINTF(Hello, "Hello world! Processing the event!\n"); |
| } |
| </code></pre></div></div> |
| |
| <h2 id="scheduling-events">Scheduling events</h2> |
| |
| <p>Finally, for the event to be processed, we first have to <em>schedule</em> the |
| event. For this we use the :cppschedule function. This function |
| schedules some instance of an <code class="highlighter-rouge">Event</code> for some time in the future |
| (event-driven simulation does not allow events to execute in the past).</p> |
| |
| <p>We will initially schedule the event in the <code class="highlighter-rouge">startup()</code> function we |
| added to the <code class="highlighter-rouge">HelloObject</code> class. The <code class="highlighter-rouge">startup()</code> function is where |
| SimObjects are allowed to schedule internal events. It does not get |
| executed until the simulation begins for the first time (i.e. the |
| <code class="highlighter-rouge">simulate()</code> function is called from a Python config file).</p> |
| |
| <p>``` {.sourceCode .c++} |
| void |
| HelloObject::startup() |
| { |
| schedule(event, 100); |
| }</p> |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> |
| Here, we simply schedule the event to execute at tick 100. Normally, you |
| would use some offset from `curTick()`, but since we know the startup() |
| function is called when the time is currently 0, we can use an explicit |
| tick value. |
| |
| The output when you run gem5 with the "Hello" debug flag is now |
| |
| gem5 Simulator System. http://gem5.org |
| gem5 is copyrighted software; use the --copyright option for details. |
| |
| gem5 compiled Jan 4 2017 11:01:46 |
| gem5 started Jan 4 2017 13:41:38 |
| gem5 executing on chinook, pid 1834 |
| command line: build/X86/gem5.opt --debug-flags=Hello configs/learning_gem5/part2/run_hello.py |
| |
| Global frequency set at 1000000000000 ticks per second |
| 0: hello: Created the hello object |
| Beginning simulation! |
| info: Entering event queue @ 0. Starting simulation... |
| 100: hello: Hello world! Processing the event! |
| Exiting @ tick 18446744073709551615 because simulate() limit reached |
| |
| More event scheduling |
| --------------------- |
| |
| We can also schedule new events within an event process action. For |
| instance, we are going to add a latency parameter to the `HelloObject` |
| and a parameter for how many times to fire the event. In the [next |
| chapter](parameters-chapter) we will make these parameters accessible |
| from the Python config files. |
| |
| To the HelloObject class declaration, add a member variable for the |
| latency and number of times to fire. |
| |
| ``` {.sourceCode .c++} |
| class HelloObject : public SimObject |
| { |
| private: |
| void processEvent(); |
| |
| EventFunctionWrapper event; |
| |
| Tick latency; |
| |
| int timesLeft; |
| |
| public: |
| HelloObject(HelloObjectParams *p); |
| |
| void startup(); |
| }; |
| </code></pre></div></div> |
| |
| <p>Then, in the constructor add default values for the <code class="highlighter-rouge">latency</code> and |
| <code class="highlighter-rouge">timesLeft</code>.</p> |
| |
| <p>``` {.sourceCode .c++} |
| HelloObject::HelloObject(HelloObjectParams *params) : |
| SimObject(params), event([this]{processEvent();}, name()), |
| latency(100), timesLeft(10) |
| { |
| DPRINTF(Hello, “Created the hello object\n”); |
| }</p> |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> |
| Finally, update `startup()` and `processEvent()`. |
| |
| ``` {.sourceCode .c++} |
| void |
| HelloObject::startup() |
| { |
| schedule(event, latency); |
| } |
| |
| void |
| HelloObject::processEvent() |
| { |
| timesLeft--; |
| DPRINTF(Hello, "Hello world! Processing the event! %d left\n", timesLeft); |
| |
| if (timesLeft <= 0) { |
| DPRINTF(Hello, "Done firing!\n"); |
| } else { |
| schedule(event, curTick() + latency); |
| } |
| } |
| </code></pre></div></div> |
| |
| <p>Now, when we run gem5, the event should fire 10 times, and the |
| simulation will end after 1000 ticks. The output should now look like |
| the following.</p> |
| |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem5 Simulator System. http://gem5.org |
| gem5 is copyrighted software; use the --copyright option for details. |
| |
| gem5 compiled Jan 4 2017 13:53:35 |
| gem5 started Jan 4 2017 13:54:11 |
| gem5 executing on chinook, pid 2326 |
| command line: build/X86/gem5.opt --debug-flags=Hello configs/learning_gem5/part2/run_hello.py |
| |
| Global frequency set at 1000000000000 ticks per second |
| 0: hello: Created the hello object |
| Beginning simulation! |
| info: Entering event queue @ 0. Starting simulation... |
| 100: hello: Hello world! Processing the event! 9 left |
| 200: hello: Hello world! Processing the event! 8 left |
| 300: hello: Hello world! Processing the event! 7 left |
| 400: hello: Hello world! Processing the event! 6 left |
| 500: hello: Hello world! Processing the event! 5 left |
| 600: hello: Hello world! Processing the event! 4 left |
| 700: hello: Hello world! Processing the event! 3 left |
| 800: hello: Hello world! Processing the event! 2 left |
| 900: hello: Hello world! Processing the event! 1 left |
| 1000: hello: Hello world! Processing the event! 0 left |
| 1000: hello: Done firing! |
| Exiting @ tick 18446744073709551615 because simulate() limit reached |
| </code></pre></div></div> |
| |
| <p>You can find the updated header file |
| here <../_static/scripts/part2/events/hello_object.hh> and the |
| implementation file |
| here <../_static/scripts/part2/events/hello_object.cc>.</p> |
| |
| <br> |
| |
| <!-- RETRIVE PREVIOUS PAGE LINK --> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <!-- RETRIEVE NEXT PAGE LINK --> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <div class="navbuttons"> |
| |
| <a href="/debugging"><button type="button" class="btn btn-outline-primary">PREVIOUS</button></a> |
| |
| |
| |
| <a href="/parameters"><button type="button" class="btn btn-outline-primary">NEXT</button></a> |
| |
| </div> |
| </div> |
| |
| </main> |
| |
| <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> |
| <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script> |
| |
| <script> |
| // When the user scrolls down 20px from the top of the document, show the button |
| window.onscroll = function() {scrollFunction()}; |
| |
| function scrollFunction() { |
| if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 20) { |
| document.getElementById("myBtn").style.display = "block"; |
| } else { |
| document.getElementById("myBtn").style.display = "none"; |
| } |
| } |
| |
| // When the user clicks on the button, scroll to the top of the document |
| function topFunction() { |
| document.body.scrollTop = 0; |
| document.documentElement.scrollTop = 0; |
| } |
| </script> |
| |
| </body> |
| |
| <footer class="page-footer"> |
| <div class="container"> |
| <div class="row"> |
| |
| <div class="col-12 col-sm-4"> |
| <p><a href="/about">About</a></p> |
| <p><a href="/publications">Publications</a></p> |
| <p><a href="/contributing">Contributing</a></p> |
| <p><a href="/governance">Governance</a></p> |
| </div><br> |
| |
| <div class="col-12 col-sm-4"> |
| <p><a href="/introduction">Documentation</a></p> |
| <p><a href="http://gem5.org/Documentation">Old Documentation</a></p> |
| <p><a href="https://gem5.googlesource.com/public/gem5">Source</a></p> |
| </div><br> |
| |
| <div class="col-12 col-sm-4"> |
| <p><a href="/search">Search</a></p> |
| <p><a href="#">Mailing Lists</a></p> |
| <p><a href="#">Source For This Site</a></p> |
| </div> |
| |
| </div> |
| </div> |
| </footer> |
| |
| |
| </html> |