gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
34 
35 #include "mem/token_port.hh"
36 
37 #include "base/trace.hh"
38 #include "debug/TokenPort.hh"
39 
40 void
42 {
43  RequestPort::bind(peer);
44 }
45 
46 void
48 {
49  panic_if(!tokenManager, "TokenManager not set for %s.\n", name());
50 
51  tokenManager->recvTokens(num_tokens);
52 }
53 
54 bool
56 {
57  panic_if(!tokenManager, "TokenManager not set for %s.\n", name());
58 
59  return tokenManager->haveTokens(num_tokens);
60 }
61 
62 void
64 {
65  panic_if(!tokenManager, "TokenManager not set for %s.\n", name());
66 
67  tokenManager->acquireTokens(num_tokens);
68 }
69 
70 void
72 {
73  tokenManager = _tokenManager;
74 }
75 
76 void
78 {
79  fatal_if(!tokenRequestPort, "Tried sendTokens to non-token requestor!\n");
80 
81  // Send tokens to a requestor
82  tokenRequestPort->recvTokens(num_tokens);
83 }
84 
85 void
87 {
88  // TokenResponsePort is allowed to bind to either TokenRequestPort or a
89  // RequestPort as fallback. If the type is a RequestPort, tokenRequestPort
90  // is set to nullptr to indicate tokens should not be exchanged.
91  auto *token_request_port = dynamic_cast<TokenRequestPort*>(&peer);
92  auto *request_port = dynamic_cast<RequestPort*>(&peer);
93  if (!token_request_port && !request_port) {
94  fatal("Attempt to bind port %s to unsupported response port %s.",
95  name(), peer.name());
96  } else if (token_request_port) {
97  // response port keeps track of the request port
98  tokenRequestPort = token_request_port;
99 
100  // request port also keeps track of response port
101  tokenRequestPort->bind(*this);
102  } else if (request_port) {
103  tokenRequestPort = nullptr;
104  }
105 }
106 
107 void
109 {
111  tokenRequestPort = nullptr;
112 }
113 
114 void
116 {
117  // fallback to QueuedResponsePort-like impl for now
118  panic_if(respQueue.empty(),
119  "Attempted to retry a response when no retry was queued!\n");
120 
121  PacketPtr pkt = respQueue.front();
122  bool success = ResponsePort::sendTimingResp(pkt);
123 
124  if (success) {
125  respQueue.pop_front();
126  }
127 }
128 
129 bool
131 {
132  bool success = ResponsePort::sendTimingResp(pkt);
133 
134  if (!success) {
135  respQueue.push_back(pkt);
136  }
137 
138  return success;
139 }
140 
142 {
143  availableTokens = init_tokens;
144  maxTokens = init_tokens;
145 }
146 
147 int
149 {
150  return maxTokens;
151 }
152 
153 void
155 {
156  availableTokens += num_tokens;
157 
158  DPRINTF(TokenPort, "Received %d tokens, have %d\n",
159  num_tokens, availableTokens);
160 
162  "More tokens available than the maximum after recvTokens!\n");
163 }
164 
165 bool
167 {
168  return (availableTokens >= num_tokens);
169 }
170 
171 void
173 {
174  panic_if(!haveTokens(num_tokens),
175  "Attempted to acquire more tokens than are available!\n");
176 
177  availableTokens -= num_tokens;
178 
179  DPRINTF(TokenPort, "Acquired %d tokens, have %d\n",
180  num_tokens, availableTokens);
181 }
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:154
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:172
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:166
TokenResponsePort::bind
void bind(Port &peer) override
Bind this response port to a request port.
Definition: token_port.cc:86
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:148
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:47
TokenManager::maxTokens
int maxTokens
Definition: token_port.hh:133
TokenManager::TokenManager
TokenManager(int init_tokens)
Definition: token_port.cc:141
TokenRequestPort::acquireTokens
void acquireTokens(int num_tokens)
Acquire tokens by decrementing the number of available tokens across the port.
Definition: token_port.cc:63
TokenResponsePort::sendTimingResp
bool sendTimingResp(PacketPtr pkt)
Definition: token_port.cc:130
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
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:108
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:41
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:115
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:55
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:258
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:71
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:77

Generated on Tue Jun 22 2021 15:28:30 for gem5 by doxygen 1.8.17