finally:
self.c.set_port_attr(ports = [self.tx_port, self.rx_port], promiscuous = False)
+
+
+ # see https://trex-tgn.cisco.com/youtrack/issue/trex-226
+ def test_latency_pause_resume (self):
+
+ try:
+
+ s1 = STLStream(name = 'latency',
+ packet = self.pkt,
+ mode = STLTXCont(percentage = self.percentage),
+ flow_stats = STLFlowLatencyStats(pg_id = 1))
+
+ self.c.add_streams([s1], ports = self.tx_port)
+
+ self.c.clear_stats()
+
+ # mult has no meaning on latency - just messing around with the test
+ self.c.start(ports = self.tx_port, mult = "10mpps")
+
+ for i in range(100):
+ self.c.pause()
+ self.c.resume()
+
+ self.c.stop()
+
+ except STLError as e:
+ assert False , '{0}'.format(e)
}
+/**
+ * return true if a core is still pending on an event
+ */
+bool
+TrexDpPortEvents::is_core_pending_on_event(int event_id, int thread_id) {
+ TrexDpPortEvent *event = lookup(event_id);
+ /* event might have been deleted */
+ if (!event) {
+ return false;
+ }
+
+ return event->is_core_pending_on_event(thread_id);
+}
+
/***************************
* event
*
}
}
-
+bool
+TrexDpPortEvent::is_core_pending_on_event(int thread_id) {
+ /* if the core has yet to mark its 'done' bit - it is still pending */
+ return !m_signal.at(thread_id);
+}
private:
void init(TrexStatelessPort *port, int event_id, int timeout_ms);
bool on_core_reporting_in(int thread_id, bool status = true);
+ bool is_core_pending_on_event(int thread_id);
std::unordered_map<int, bool> m_signal;
int m_pending_cnt;
*/
void on_core_reporting_in(int event_id, int thread_id, bool status = true);
+ /**
+ * return true if core has yet to respond
+ * to the event
+ *
+ */
+ bool is_core_pending_on_event(int event_id, int thread_id);
+
private:
TrexDpPortEvent *lookup(int event_id);
}
+/**
+ * core is considered active if it has a pending for async stop
+ *
+ */
+bool
+TrexStatelessPort::is_core_active(int core_id) {
+ return ( (m_pending_async_stop_event != TrexDpPortEvents::INVALID_ID) &&
+ (m_dp_events.is_core_pending_on_event(m_pending_async_stop_event, core_id))
+ );
+}
+
void
TrexStatelessPort::pause_traffic(void) {
/* send a pause message */
TrexStatelessCpToDpMsgBase *pause_msg = new TrexStatelessDpPause(m_port_id);
- send_message_to_all_dp(pause_msg);
+
+ /* send message to all cores */
+ send_message_to_all_dp(pause_msg, true);
/* make sure all DP cores paused */
m_dp_events.barrier();
/* generate a message to all the relevant DP cores to start transmitting */
TrexStatelessCpToDpMsgBase *resume_msg = new TrexStatelessDpResume(m_port_id);
- send_message_to_all_dp(resume_msg);
+ send_message_to_all_dp(resume_msg, true);
change_state(PORT_STATE_TX);
-
Json::Value data;
data["port_id"] = m_port_id;
get_stateless_obj()->get_publisher()->publish_event(TrexPublisher::EVENT_PORT_RESUMED, data);
}
void
-TrexStatelessPort::send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg) {
+TrexStatelessPort::send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg, bool send_to_active_only) {
for (auto core_id : m_cores_id_list) {
+
+ /* skip non active cores if requested */
+ if ( (send_to_active_only) && (!is_core_active(core_id)) ) {
+ continue;
+ }
+
send_message_to_dp(core_id, msg->clone());
}
private:
+ bool is_core_active(int core_id);
const std::vector<int> get_core_id_list () {
return m_cores_id_list;
* send message to all cores using duplicate
*
*/
- void send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg);
+ void send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg, bool send_to_active_only = false);
/**
* send message to specific DP core