diff options
author | Brad Beckmann <Brad.Beckmann@amd.com> | 2010-08-20 11:46:14 -0700 |
---|---|---|
committer | Brad Beckmann <Brad.Beckmann@amd.com> | 2010-08-20 11:46:14 -0700 |
commit | e7f2da517adbc9ba4ed1b33de102126260a0d587 (patch) | |
tree | dc45a1acf1843da774f55fb1a5e27333804c4910 /src/mem/slicc/symbols | |
parent | af6b97e3ee2d73fcb2d4bcdbdffc9a6534dfdac8 (diff) | |
download | gem5-e7f2da517adbc9ba4ed1b33de102126260a0d587.tar.xz |
ruby: Stall and wait input messages instead of recycling
This patch allows messages to be stalled in their input buffers and wait
until a corresponding address changes state. In order to make this work,
all in_ports must be ranked in order of dependence and those in_ports that
may unblock an address, must wake up the stalled messages. Alot of this
complexity is handled in slicc and the specification files simply
annotate the in_ports.
--HG--
rename : src/mem/slicc/ast/CheckAllocateStatementAST.py => src/mem/slicc/ast/StallAndWaitStatementAST.py
rename : src/mem/slicc/ast/CheckAllocateStatementAST.py => src/mem/slicc/ast/WakeUpDependentsStatementAST.py
Diffstat (limited to 'src/mem/slicc/symbols')
-rw-r--r-- | src/mem/slicc/symbols/StateMachine.py | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index d5a824905..e57275527 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -238,6 +238,8 @@ public: const std::string toString() const; const std::string getName() const; const MachineType getMachineType() const; + void stallBuffer(MessageBuffer* buf, Address addr); + void wakeUpBuffers(Address addr); void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; } void print(std::ostream& out) const; void printConfig(std::ostream& out) const; @@ -280,6 +282,11 @@ Network* m_net_ptr; MachineID m_machineID; bool m_is_blocking; std::map<Address, MessageBuffer*> m_block_map; +typedef std::vector<MessageBuffer*> MsgVecType; +typedef m5::hash_map< Address, MsgVecType* > WaitingBufType; +WaitingBufType m_waiting_buffers; +int m_max_in_port_rank; +int m_cur_in_port_rank; static ${ident}_ProfileDumper s_profileDumper; ${ident}_Profiler m_profiler; static int m_num_controllers; @@ -378,6 +385,12 @@ $c_ident::$c_ident(const Params *p) m_number_of_TBEs = p->number_of_TBEs; m_is_blocking = false; ''') + # + # max_port_rank is used to size vectors and thus should be one plus the + # largest port rank + # + max_port_rank = self.in_ports[0].pairs["max_port_rank"] + 1 + code(' m_max_in_port_rank = $max_port_rank;') code.indent() # @@ -621,6 +634,35 @@ $c_ident::getMachineType() const } void +$c_ident::stallBuffer(MessageBuffer* buf, Address addr) +{ + if (m_waiting_buffers.count(addr) == 0) { + MsgVecType* msgVec = new MsgVecType; + msgVec->resize(m_max_in_port_rank, NULL); + m_waiting_buffers[addr] = msgVec; + } + (*(m_waiting_buffers[addr]))[m_cur_in_port_rank] = buf; +} + +void +$c_ident::wakeUpBuffers(Address addr) +{ + // + // Wake up all possible lower rank (i.e. lower priority) buffers that could + // be waiting on this message. + // + for (int in_port_rank = m_cur_in_port_rank - 1; + in_port_rank >= 0; + in_port_rank--) { + if ((*(m_waiting_buffers[addr]))[in_port_rank] != NULL) { + (*(m_waiting_buffers[addr]))[in_port_rank]->reanalyzeMessages(addr); + } + } + delete m_waiting_buffers[addr]; + m_waiting_buffers.erase(addr); +} + +void $c_ident::blockOnQueue(Address addr, MessageBuffer* port) { m_is_blocking = true; @@ -757,6 +799,10 @@ ${ident}_Controller::wakeup() for port in self.in_ports: code.indent() code('// ${ident}InPort $port') + if port.pairs.has_key("rank"): + code('m_cur_in_port_rank = ${{port.pairs["rank"]}};') + else: + code('m_cur_in_port_rank = 0;') code('${{port["c_code_in_port"]}}') code.dedent() |