diff options
5 files changed, 91 insertions, 23 deletions
diff --git a/scripts/automation/trex_control_plane/common/text_opts.py b/scripts/automation/trex_control_plane/common/text_opts.py index 78a0ab1f..ab0fd2f2 100755 --- a/scripts/automation/trex_control_plane/common/text_opts.py +++ b/scripts/automation/trex_control_plane/common/text_opts.py @@ -61,6 +61,9 @@ def format_time (t_sec): if t_sec < 0: return "infinite" + if t_sec == 0: + return "zero" + if t_sec < 1: # low numbers for unit in ['ms', 'usec', 'ns']: diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py index 7e0bf9e4..26e64dae 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py @@ -61,6 +61,9 @@ def format_time (t_sec): if t_sec < 0: return "infinite" + if t_sec == 0: + return "zero" + if t_sec < 1: # low numbers for unit in ['ms', 'usec', 'ns']: diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 4dc3e449..d736d09e 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -87,6 +87,68 @@ protected: } }; +/************************************* + * Streams Feeder + * A class that holds a temporary + * clone of streams that can be + * manipulated + * + * this is a RAII object meant for + * graceful cleanup + ************************************/ +class StreamsFeeder { +public: + StreamsFeeder(TrexStatelessPort *port) { + + /* start pesimistic */ + m_success = false; + + /* fetch the original streams */ + port->get_object_list(m_in_streams); + + for (const TrexStream *in_stream : m_in_streams) { + TrexStream *out_stream = in_stream->clone(true); + + get_stateless_obj()->m_rx_flow_stat.start_stream(out_stream); + + m_out_streams.push_back(out_stream); + } + } + + void set_status(bool status) { + m_success = status; + } + + vector<TrexStream *> &get_streams() { + return m_out_streams; + } + + /** + * RAII + */ + ~StreamsFeeder() { + for (int i = 0; i < m_out_streams.size(); i++) { + TrexStream *out_stream = m_out_streams[i]; + TrexStream *in_stream = m_in_streams[i]; + + if (m_success) { + /* success path */ + get_stateless_obj()->m_rx_flow_stat.copy_state(out_stream, in_stream); + } else { + /* fail path */ + get_stateless_obj()->m_rx_flow_stat.stop_stream(out_stream); + } + delete out_stream; + } + } + +private: + vector<TrexStream *> m_in_streams; + vector<TrexStream *> m_out_streams; + bool m_success; +}; + + /*************************** * trex stateless port * @@ -193,10 +255,7 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, /* caclulate the effective factor for DP */ double factor = calculate_effective_factor(mul, force); - /* fetch all the streams from the table */ - vector<TrexStream *> streams; - get_object_list(streams); - + StreamsFeeder feeder(this); /* compiler it */ std::vector<TrexStreamsCompiledObj *> compiled_objs; @@ -204,15 +263,19 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, TrexStreamsCompiler compiler; bool rc = compiler.compile(m_port_id, - streams, + feeder.get_streams(), compiled_objs, get_dp_core_count(), factor, &fail_msg); + if (!rc) { + feeder.set_status(false); throw TrexException(fail_msg); } + feeder.set_status(true); + /* generate a message to all the relevant DP cores to start transmitting */ assert(m_pending_async_stop_event == TrexDpPortEvents::INVALID_ID); m_pending_async_stop_event = m_dp_events.create_event(new AsyncStopEvent()); diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp index d2fe416a..e54c5f9c 100644 --- a/src/stateless/cp/trex_streams_compiler.cpp +++ b/src/stateless/cp/trex_streams_compiler.cpp @@ -382,7 +382,13 @@ TrexStreamsCompiler::compile(uint8_t port_id, assert(dp_core_count > 0); try { - return compile_internal(port_id,streams,objs,dp_core_count,factor,fail_msg); + return compile_internal(port_id, + streams, + objs, + dp_core_count, + factor, + fail_msg); + } catch (const TrexException &ex) { if (fail_msg) { *fail_msg = ex.what(); @@ -411,7 +417,6 @@ TrexStreamsCompiler::compile_internal(uint8_t por GraphNodeMap nodes; - /* compile checks */ pre_compile_check(streams, nodes); @@ -474,7 +479,7 @@ TrexStreamsCompiler::compile_on_single_core(uint8_t } /* compile all the streams */ - for (auto stream : streams) { + for (auto const stream : streams) { /* skip non-enabled streams */ if (!stream->m_enabled) { @@ -507,7 +512,7 @@ TrexStreamsCompiler::compile_on_all_cores(uint8_t } /* compile all the streams */ - for (auto stream : streams) { + for (auto const stream : streams) { /* skip non-enabled streams */ if (!stream->m_enabled) { @@ -527,7 +532,7 @@ TrexStreamsCompiler::compile_on_all_cores(uint8_t * */ void -TrexStreamsCompiler::compile_stream(TrexStream *stream, +TrexStreamsCompiler::compile_stream(const TrexStream *stream, double factor, uint8_t dp_core_count, std::vector<TrexStreamsCompiledObj *> &objs, @@ -543,31 +548,25 @@ TrexStreamsCompiler::compile_stream(TrexStream *stream, new_next_id = nodes.get(stream->m_next_stream_id)->m_compressed_stream_id; } - TrexStream *fixed_rx_flow_stat_stream = stream->clone(true); - - get_stateless_obj()->m_rx_flow_stat.start_stream(fixed_rx_flow_stat_stream); - // CFlowStatRuleMgr keeps state of the stream object. We duplicated the stream here (in order not - // change the packet kept in the stream). We want the state to be saved in the original stream. - get_stateless_obj()->m_rx_flow_stat.copy_state(fixed_rx_flow_stat_stream, stream); - - fixed_rx_flow_stat_stream->update_rate_factor(factor); + /* we clone because we alter the stream now */ + std::unique_ptr<TrexStream> tmp_stream(stream->clone(true)); + tmp_stream->update_rate_factor(factor); /* can this stream be split to many cores ? */ if ( (dp_core_count == 1) || (!stream->is_splitable(dp_core_count)) ) { - compile_stream_on_single_core(fixed_rx_flow_stat_stream, + compile_stream_on_single_core(tmp_stream.get(), dp_core_count, objs, new_id, new_next_id); } else { - compile_stream_on_all_cores(fixed_rx_flow_stat_stream, + compile_stream_on_all_cores(tmp_stream.get(), dp_core_count, objs, new_id, new_next_id); } - delete fixed_rx_flow_stat_stream; } /** diff --git a/src/stateless/cp/trex_streams_compiler.h b/src/stateless/cp/trex_streams_compiler.h index 0ce71b49..7e674364 100644 --- a/src/stateless/cp/trex_streams_compiler.h +++ b/src/stateless/cp/trex_streams_compiler.h @@ -141,7 +141,7 @@ private: bool all_continues); - void compile_stream(TrexStream *stream, + void compile_stream(const TrexStream *stream, double factor, uint8_t dp_core_count, std::vector<TrexStreamsCompiledObj *> &objs, @@ -244,7 +244,7 @@ public: } double get_factor_pps(double req_pps) const { - if ( (req_pps - m_fixed.m_pps) <= 0 ) { + if ( (req_pps - m_fixed.m_pps) < 0 ) { std::stringstream ss; ss << "current stream configuration enforces a minimum rate of '" << m_fixed.m_pps << "' pps"; throw TrexException(ss.str()); |