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

Generated on Wed Dec 21 2022 10:22:39 for gem5 by doxygen 1.9.1