diff options
Diffstat (limited to 'src/stateless')
-rw-r--r-- | src/stateless/cp/trex_stateless_port.cpp | 16 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.h | 7 | ||||
-rw-r--r-- | src/stateless/cp/trex_streams_compiler.cpp | 50 | ||||
-rw-r--r-- | src/stateless/cp/trex_streams_compiler.h | 62 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.h | 11 |
5 files changed, 121 insertions, 25 deletions
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 376453b9..134d4c98 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -241,7 +241,7 @@ TrexStatelessPort::release(void) { * */ void -TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, bool force) { +TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, bool force, uint64_t core_mask) { /* command allowed only on state stream */ verify_state(PORT_STATE_STREAMS); @@ -262,10 +262,12 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, std::string fail_msg; TrexStreamsCompiler compiler; + TrexDPCoreMask mask(get_dp_core_count(), core_mask); + bool rc = compiler.compile(m_port_id, feeder.get_streams(), compiled_objs, - get_dp_core_count(), + mask, factor, &fail_msg); @@ -282,7 +284,7 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, /* update object status */ m_factor = factor; - m_last_all_streams_continues = compiled_objs[0]->get_all_streams_continues(); + m_last_all_streams_continues = compiled_objs[mask.get_active_cores()[0]]->get_all_streams_continues(); m_last_duration = duration; change_state(PORT_STATE_TX); @@ -484,7 +486,7 @@ TrexStatelessPort::update_traffic(const TrexPortMultiplier &mul, bool force) { } TrexStatelessCpToDpMsgBase *update_msg = new TrexStatelessDpUpdate(m_port_id, factor); - send_message_to_all_dp(update_msg); + send_message_to_all_dp(update_msg, true); m_factor *= factor; @@ -820,13 +822,17 @@ TrexStatelessPort::validate(void) { } TrexStreamsCompiler compiler; + + /* TODO: think of this mask...*/ + TrexDPCoreMask core_mask(get_dp_core_count(), TrexDPCoreMask::MASK_ALL); + std::vector<TrexStreamsCompiledObj *> compiled_objs; std::string fail_msg; bool rc = compiler.compile(m_port_id, streams, compiled_objs, - get_dp_core_count(), + core_mask, 1.0, &fail_msg); if (!rc) { diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h index b1f6ddfe..7d976e46 100644 --- a/src/stateless/cp/trex_stateless_port.h +++ b/src/stateless/cp/trex_stateless_port.h @@ -178,7 +178,7 @@ public: * start traffic * throws TrexException in case of an error */ - void start_traffic(const TrexPortMultiplier &mul, double duration, bool force = false); + void start_traffic(const TrexPortMultiplier &mul, double duration, bool force = false, uint64_t core_mask = UINT64_MAX); /** * stop traffic @@ -376,11 +376,12 @@ public: void get_pci_info(std::string &pci_addr, int &numa_node); + private: bool is_core_active(int core_id); - const std::vector<int> get_core_id_list () { + const std::vector<uint8_t> get_core_id_list () { return m_cores_id_list; } @@ -446,7 +447,7 @@ private: uint16_t m_rx_caps; /* holds the DP cores associated with this port */ - std::vector<int> m_cores_id_list; + std::vector<uint8_t> m_cores_id_list; bool m_last_all_streams_continues; double m_last_duration; diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp index e54c5f9c..97f7a250 100644 --- a/src/stateless/cp/trex_streams_compiler.cpp +++ b/src/stateless/cp/trex_streams_compiler.cpp @@ -375,19 +375,29 @@ bool TrexStreamsCompiler::compile(uint8_t port_id, const std::vector<TrexStream *> &streams, std::vector<TrexStreamsCompiledObj *> &objs, - uint8_t dp_core_count, + TrexDPCoreMask &core_mask, double factor, std::string *fail_msg) { - assert(dp_core_count > 0); + assert(core_mask.get_active_count() > 0); + + uint8_t indirect_core_count = core_mask.get_active_count(); + std::vector<TrexStreamsCompiledObj *> indirect_objs(indirect_core_count); + + for (int i = 0; i < indirect_core_count; i++) { + indirect_objs[i] = NULL; + } try { - return compile_internal(port_id, - streams, - objs, - dp_core_count, - factor, - fail_msg); + bool rc = compile_internal(port_id, + streams, + indirect_objs, + indirect_core_count, + factor, + fail_msg); + if (!rc) { + return rc; + } } catch (const TrexException &ex) { if (fail_msg) { @@ -398,6 +408,21 @@ TrexStreamsCompiler::compile(uint8_t port_id, return false; } + /* prepare the result */ + objs.resize(core_mask.get_total_count()); + for (int i = 0; i < core_mask.get_total_count(); i++) { + objs.push_back(NULL); + } + + uint8_t index = 0; + for (uint8_t active_core_id : core_mask.get_active_cores()) { + if (indirect_objs[index] == NULL) { + break; + } + objs[active_core_id] = indirect_objs[index++]; + } + + return true; } bool @@ -471,12 +496,7 @@ TrexStreamsCompiler::compile_on_single_core(uint8_t /* allocate object only for core 0 */ TrexStreamsCompiledObj *obj = new TrexStreamsCompiledObj(port_id); obj->m_all_continues = all_continues; - objs.push_back(obj); - - /* put NULL for the rest */ - for (uint8_t i = 1; i < dp_core_count; i++) { - objs.push_back(NULL); - } + objs[0] = obj; /* compile all the streams */ for (auto const stream : streams) { @@ -508,7 +528,7 @@ TrexStreamsCompiler::compile_on_all_cores(uint8_t for (uint8_t i = 0; i < dp_core_count; i++) { TrexStreamsCompiledObj *obj = new TrexStreamsCompiledObj(port_id); obj->m_all_continues = all_continues; - objs.push_back(obj); + objs[i] = obj; } /* compile all the streams */ diff --git a/src/stateless/cp/trex_streams_compiler.h b/src/stateless/cp/trex_streams_compiler.h index 171e3aff..b95bf176 100644 --- a/src/stateless/cp/trex_streams_compiler.h +++ b/src/stateless/cp/trex_streams_compiler.h @@ -32,6 +32,66 @@ class TrexStreamsCompiler; class TrexStream; class GraphNodeMap; +class TrexDPCoreMask { + +public: + + TrexDPCoreMask(uint8_t dp_core_count, uint64_t dp_core_mask) { + assert(is_valid_mask(dp_core_count, dp_core_mask)); + + m_dp_core_count = dp_core_count; + m_dp_core_mask = dp_core_mask; + + for (int i = 0; i < m_dp_core_count; i++) { + if (is_core_active(i)) { + m_active_cores.push_back(i); + } + } + } + + + uint8_t get_total_count() const { + return m_dp_core_count; + } + + bool is_core_active(uint8_t core_id) const { + assert(core_id < m_dp_core_count); + return ( (1 << core_id) & m_dp_core_mask ); + } + + bool is_core_disabled(uint8_t core_id) const { + return (!is_core_active(core_id)); + } + + uint8_t get_active_count() const { + return m_active_cores.size(); + } + + const std::vector<uint8_t> & get_active_cores() const { + return m_active_cores; + } + + static bool is_valid_mask(uint8_t dp_core_count, uint64_t dp_core_mask) { + if ( (dp_core_count < 1) || (dp_core_count > 64) ) { + return false; + } + /* highest bit pushed to left and then -1 will give all the other bits on */ + return ( (dp_core_mask & ( (1 << dp_core_count) - 1 ) ) != 0); + } +private: + + + uint8_t m_dp_core_count; + uint64_t m_dp_core_mask; + + std::vector<uint8_t> m_active_cores; + +public: + static const uint64_t MASK_ALL = UINT64_MAX; + +}; + + /** * compiled object for a table of streams * @@ -92,7 +152,7 @@ public: bool compile(uint8_t port_id, const std::vector<TrexStream *> &streams, std::vector<TrexStreamsCompiledObj *> &objs, - uint8_t dp_core_count = 1, + TrexDPCoreMask &core_mask, double factor = 1.0, std::string *fail_msg = NULL); diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h index 31cb0be3..9babb172 100644 --- a/src/stateless/dp/trex_stateless_dp_core.h +++ b/src/stateless/dp/trex_stateless_dp_core.h @@ -83,10 +83,14 @@ public: bool update_number_of_active_streams(uint32_t d); - state_e get_state() { + state_e get_state() const { return m_state; } + bool is_active() const { + return (get_state() != ppSTATE_IDLE); + } + void set_event_id(int event_id) { m_event_id = event_id; } @@ -261,6 +265,11 @@ public: /* simply sends a message back (acts as a barrier for previous messages) */ void barrier(uint8_t port_id, int event_id); + bool is_port_active(uint8_t port_id) { + return get_port_db(port_id)->is_active(); + } + + private: void schedule_exit(); |