gem5  v20.1.0.0
token_port.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2020 Advanced Micro Devices, Inc.
3  * All rights reserved.
4  *
5  * For use for simulation and test purposes only
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Authors: Matthew Poremba
34  */
35 
36 
37 #include "mem/token_port.hh"
38 
39 #include "base/trace.hh"
40 #include "debug/TokenPort.hh"
41 
42 void
44 {
45  RequestPort::bind(peer);
46 }
47 
48 void
50 {
51  panic_if(!tokenManager, "TokenManager not set for %s.\n", name());
52 
53  tokenManager->recvTokens(num_tokens);
54 }
55 
56 bool
58 {
59  panic_if(!tokenManager, "TokenManager not set for %s.\n", name());
60 
61  return tokenManager->haveTokens(num_tokens);
62 }
63 
64 void
66 {
67  panic_if(!tokenManager, "TokenManager not set for %s.\n", name());
68 
69  tokenManager->acquireTokens(num_tokens);
70 }
71 
72 void
74 {
75  tokenManager = _tokenManager;
76 }
77 
78 void
80 {
81  fatal_if(!tokenRequestPort, "Tried sendTokens to non-token requestor!\n");
82 
83  // Send tokens to a requestor
84  tokenRequestPort->recvTokens(num_tokens);
85 }
86 
87 void
89 {
90  // TokenResponsePort is allowed to bind to either TokenRequestPort or a
91  // RequestPort as fallback. If the type is a RequestPort, tokenRequestPort
92  // is set to nullptr to indicate tokens should not be exchanged.
93  auto *token_request_port = dynamic_cast<TokenRequestPort*>(&peer);
94  auto *request_port = dynamic_cast<RequestPort*>(&peer);
95  if (!token_request_port && !request_port) {
96  fatal("Attempt to bind port %s to unsupported response port %s.",
97  name(), peer.name());
98  } else if (token_request_port) {
99  // response port keeps track of the request port
100  tokenRequestPort = token_request_port;
101 
102  // request port also keeps track of response port
103  tokenRequestPort->bind(*this);
104  } else if (request_port) {
105  tokenRequestPort = nullptr;
106  }
107 }
108 
109 void
111 {
113  tokenRequestPort = nullptr;
114 }
115 
116 void
118 {
119  // fallback to QueuedResponsePort-like impl for now
120  panic_if(respQueue.empty(),
121  "Attempted to retry a response when no retry was queued!\n");
122 
123  PacketPtr pkt = respQueue.front();
124  bool success = ResponsePort::sendTimingResp(pkt);
125 
126  if (success) {
127  respQueue.pop_front();
128  }
129 }
130 
131 bool
133 {
134  bool success = ResponsePort::sendTimingResp(pkt);
135 
136  if (!success) {
137  respQueue.push_back(pkt);
138  }
139 
140  return success;
141 }
142 
144 {
145  availableTokens = init_tokens;
146  maxTokens = init_tokens;
147 }
148 
149 int
151 {
152  return maxTokens;
153 }
154 
155 void
157 {
158  availableTokens += num_tokens;
159 
160  DPRINTF(TokenPort, "Received %d tokens, have %d\n",
161  num_tokens, availableTokens);
162 
164  "More tokens available than the maximum after recvTokens!\n");
165 }
166 
167 bool
169 {
170  return (availableTokens >= num_tokens);
171 }
172 
173 void
175 {
176  panic_if(!haveTokens(num_tokens),
177  "Attempted to acquire more tokens than are available!\n");
178 
179  availableTokens -= num_tokens;
180 
181  DPRINTF(TokenPort, "Acquired %d tokens, have %d\n",
182  num_tokens, availableTokens);
183 }
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
TokenManager::recvTokens
void recvTokens(int num_tokens)
Increment the number of available tokens by num_tokens.
Definition: token_port.cc:156
TokenRequestPort::tokenManager
TokenManager * tokenManager
Definition: token_port.hh:47
TokenManager::acquireTokens
void acquireTokens(int num_tokens)
Decrement the number of available tokens by num_tokens.
Definition: token_port.cc:174
ResponsePort::sendTimingResp
bool sendTimingResp(PacketPtr pkt)
Attempt to send a timing response to the request port by calling its corresponding receive function.
Definition: port.hh:367
TokenManager::availableTokens
int availableTokens
Definition: token_port.hh:136
TokenManager::haveTokens
bool haveTokens(int num_tokens)
Query is num_tokens tokens are available.
Definition: token_port.cc:168
TokenResponsePort::bind
void bind(Port &peer) override
Bind this response port to a request port.
Definition: token_port.cc:88
ResponsePort::responderUnbind
void responderUnbind()
Called by the request port to unbind.
Definition: port.cc:180
TokenManager::getMaxTokenCount
int getMaxTokenCount() const
Return the maximum possible tokens.
Definition: token_port.cc:150
RequestPort::bind
void bind(Port &peer) override
Bind this request port to a response port.
Definition: port.cc:125
TokenRequestPort::recvTokens
void recvTokens(int num_tokens)
Receive tokens returned by the response port.
Definition: token_port.cc:49
TokenManager::maxTokens
int maxTokens
Definition: token_port.hh:133
TokenManager::TokenManager
TokenManager(int init_tokens)
Definition: token_port.cc:143
TokenRequestPort::acquireTokens
void acquireTokens(int num_tokens)
Acquire tokens by decrementing the number of available tokens across the port.
Definition: token_port.cc:65
TokenResponsePort::sendTimingResp
bool sendTimingResp(PacketPtr pkt)
Definition: token_port.cc:132
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
TokenResponsePort::respQueue
std::deque< PacketPtr > respQueue
Definition: token_port.hh:95
Port
Ports are used to interface objects to each other.
Definition: port.hh:56
TokenResponsePort::unbind
void unbind() override
Unbind this response port and associated request port.
Definition: token_port.cc:110
RequestPort
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
Definition: port.hh:74
Port::name
const std::string name() const
Return port name (for DPRINTF).
Definition: port.hh:106
TokenRequestPort::bind
void bind(Port &peer) override
Bind this request port to response port.
Definition: token_port.cc:43
TokenResponsePort::recvRespRetry
void recvRespRetry() override
Called by the peer if sendTimingResp was called on this protocol (causing recvTimingResp to be called...
Definition: token_port.cc:117
TokenResponsePort::tokenRequestPort
TokenRequestPort * tokenRequestPort
Definition: token_port.hh:93
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
TokenRequestPort::haveTokens
bool haveTokens(int num_tokens)
Query if there are at least num_tokens tokens available to acquire.
Definition: token_port.cc:57
TokenRequestPort
Definition: token_port.hh:43
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
token_port.hh
trace.hh
TokenManager
Definition: token_port.hh:129
TokenRequestPort::setTokenManager
void setTokenManager(TokenManager *_tokenManager)
Specify a token manger, which will handle tracking of tokens for a TokenRequestPort/ResponseRequestPo...
Definition: token_port.cc:73
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
TokenResponsePort::sendTokens
void sendTokens(int num_tokens)
Return num_tokens tokens back to the request port.
Definition: token_port.cc:79

Generated on Wed Sep 30 2020 14:02:14 for gem5 by doxygen 1.8.17