From e7f2da517adbc9ba4ed1b33de102126260a0d587 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Fri, 20 Aug 2010 11:46:14 -0700 Subject: 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 --- src/mem/slicc/symbols/StateMachine.py | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'src/mem/slicc/symbols') 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 m_block_map; +typedef std::vector 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() # @@ -620,6 +633,35 @@ $c_ident::getMachineType() const return MachineType_${ident}; } +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) { @@ -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() -- cgit v1.2.3