summaryrefslogtreecommitdiffstats
path: root/src/stateless/cp
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-02-21 08:34:28 -0500
committerimarom <imarom@cisco.com>2016-02-23 03:08:00 -0500
commitbc7f0b85b85a8deb6bc58bcca32ff11d9289cd92 (patch)
treec6a12c9f126f6b74acb6ce740e134dd00e746679 /src/stateless/cp
parenta88db6885843221757f3cfb4bb3b2e74f57395bb (diff)
rate per stream
Diffstat (limited to 'src/stateless/cp')
-rw-r--r--src/stateless/cp/trex_stream.cpp25
-rw-r--r--src/stateless/cp/trex_stream.h209
-rw-r--r--src/stateless/cp/trex_streams_compiler.cpp36
-rw-r--r--src/stateless/cp/trex_streams_compiler.h16
4 files changed, 227 insertions, 59 deletions
diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp
index fb0b35d5..f4a8e800 100644
--- a/src/stateless/cp/trex_stream.cpp
+++ b/src/stateless/cp/trex_stream.cpp
@@ -22,6 +22,7 @@ limitations under the License.
#include <cstddef>
#include <string.h>
#include <assert.h>
+#include <trex_stateless.h>
/**************************************
* stream
@@ -91,20 +92,25 @@ void TrexStream::Dump(FILE *fd){
fprintf(fd," type : %s \n",get_stream_type_str(m_type).c_str());
if ( m_type == TrexStream::stCONTINUOUS ) {
- fprintf(fd," pps : %f \n",m_pps);
}
if (m_type == TrexStream::stSINGLE_BURST) {
- fprintf(fd," pps : %f \n",m_pps);
fprintf(fd," burst : %lu \n",(ulong)m_burst_total_pkts);
}
if (m_type == TrexStream::stMULTI_BURST) {
- fprintf(fd," pps : %f \n",m_pps);
fprintf(fd," burst : %lu \n",(ulong)m_burst_total_pkts);
fprintf(fd," mburst : %lu \n",(ulong)m_num_bursts);
if (m_ibg_usec>0.0) {
fprintf(fd," m_ibg_usec : %f \n",m_ibg_usec);
}
}
+
+ fprintf(fd," rate :\n\n");
+
+ fprintf(fd," pps : %f\n", get_rate().get_pps());
+ fprintf(fd," bps L1 : %f\n", get_rate().get_bps_L1());
+ fprintf(fd," bps L2 : %f\n", get_rate().get_bps_L2());
+ fprintf(fd," percentage : %f\n", get_rate().get_percentage());
+
}
@@ -125,7 +131,6 @@ TrexStream::TrexStream(uint8_t type,
m_rx_check.m_enable = false;
- m_pps=-1.0;
m_burst_total_pkts=0;
m_num_bursts=1;
m_ibg_usec=0.0;
@@ -155,6 +160,18 @@ TrexStream::get_stream_json() {
return m_stream_json;
}
+TrexStreamRate &
+TrexStream::get_rate() {
+
+ /* lazy calculation of the rate */
+ if (!m_rate.is_calculated()) {
+ TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(m_port_id);
+ double pkt_size = get_pkt_size();
+ m_rate.calculate(pkt_size, port->get_port_speed_bps());
+ }
+
+ return m_rate;
+}
/**************************************
* stream table
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h
index 2ab90c99..f4739569 100644
--- a/src/stateless/cp/trex_stream.h
+++ b/src/stateless/cp/trex_stream.h
@@ -103,6 +103,151 @@ public:
}
};
+/**
+ * describes a stream rate
+ *
+ * @author imarom (18-Feb-16)
+ */
+class TrexStreamRate {
+
+
+public:
+
+ enum rate_type_e {
+ RATE_INVALID,
+ RATE_PPS,
+ RATE_BPS_L1,
+ RATE_BPS_L2,
+ RATE_PERCENTAGE
+ };
+
+ TrexStreamRate() {
+ m_base_rate_type = RATE_INVALID;
+ m_is_calculated = false;
+ }
+
+ /**
+ * set the base rate
+ * other values will be dervied from this value
+ *
+ */
+ void set_base_rate(rate_type_e type, double value) {
+ m_base_rate_type = type;
+ m_value = value;
+ m_is_calculated = false;
+ }
+
+
+ /**
+ * calculates all the rates from the base rate
+ *
+ */
+ void calculate(uint16_t pkt_size, uint64_t line_bps) {
+
+ switch (m_base_rate_type) {
+
+ case RATE_PPS:
+ calculate_from_pps(m_value, pkt_size, line_bps);
+ break;
+
+ case RATE_BPS_L1:
+ calculate_from_bps_L1(m_value, pkt_size, line_bps);
+ break;
+
+ case RATE_BPS_L2:
+ calculate_from_bps_L2(m_value, pkt_size, line_bps);
+ break;
+
+ case RATE_PERCENTAGE:
+ calculate_from_percentage(m_value, pkt_size, line_bps);
+ break;
+
+ default:
+ assert(0);
+ }
+
+ m_is_calculated = true;
+ }
+
+
+ bool is_calculated() const {
+ return m_is_calculated;
+ }
+
+
+ /* update the rate by a factor */
+ void update_factor(double factor) {
+ assert(m_is_calculated);
+
+ m_pps *= factor;
+ m_bps_L1 *= factor;
+ m_bps_L2 *= factor;
+ m_percentage *= factor;
+ }
+
+ double get_pps() {
+ assert(m_is_calculated);
+ return (m_pps);
+ }
+
+ double get_bps_L1() {
+ assert(m_is_calculated);
+ return (m_bps_L1);
+ }
+
+ double get_bps_L2() {
+ assert(m_is_calculated);
+ return m_bps_L2;
+ }
+
+ double get_percentage() {
+ assert(m_is_calculated);
+ return m_percentage;
+ }
+
+private:
+
+ void calculate_from_pps(double pps, uint16_t pkt_size, uint64_t line_bps) {
+ m_pps = pps;
+ m_bps_L1 = m_pps * (pkt_size + 24) * 8;
+ m_bps_L2 = m_pps * (pkt_size + 4) * 8;
+ m_percentage = (m_bps_L1 / line_bps) * 100.0;
+ }
+
+
+ void calculate_from_bps_L1(double bps_L1, uint16_t pkt_size, uint64_t line_bps) {
+ m_bps_L1 = bps_L1;
+ m_bps_L2 = m_bps_L1 * ( (pkt_size + 4.0) / (pkt_size + 24.0) );
+ m_pps = m_bps_L2 / (8 * (pkt_size + 4));
+ m_percentage = (m_bps_L1 / line_bps) * 100.0;
+ }
+
+
+ void calculate_from_bps_L2(double bps_L2, uint16_t pkt_size, uint64_t line_bps) {
+ m_bps_L2 = bps_L2;
+ m_bps_L1 = m_bps_L2 * ( (pkt_size + 24.0) / (pkt_size + 4.0));
+ m_pps = m_bps_L2 / (8 * (pkt_size + 4));
+ m_percentage = (m_bps_L1 / line_bps) * 100.0;
+ }
+
+ void calculate_from_percentage(double percentage, uint16_t pkt_size, uint64_t line_bps) {
+ m_percentage = percentage;
+ m_bps_L1 = (m_percentage / 100.0) * line_bps;
+ m_bps_L2 = m_bps_L1 * ( (pkt_size + 4.0) / (pkt_size + 24.0) );
+ m_pps = m_bps_L2 / (8 * (pkt_size + 4));
+
+ }
+
+ rate_type_e m_base_rate_type;
+ double m_value;
+
+ bool m_is_calculated;
+ double m_pps;
+ double m_bps_L1;
+ double m_bps_L2;
+ double m_percentage;
+
+};
/**
* Stateless Stream
@@ -151,12 +296,29 @@ public:
m_next_stream_id = next_stream_id;
}
- double get_pps() const {
- return m_pps;
+
+ double get_pps() {
+ return get_rate().get_pps();
+ }
+
+ double get_bps_L1() {
+ return get_rate().get_bps_L1();
+ }
+
+ double get_bps_L2() {
+ return get_rate().get_bps_L2();
+ }
+
+ double get_bw_percentage() {
+ return get_rate().get_percentage();
+ }
+
+ void set_rate(TrexStreamRate::rate_type_e type, double value) {
+ m_rate.set_base_rate(type, value);
}
- void set_pps(double pps){
- m_pps = pps;
+ void update_rate_factor(double factor) {
+ get_rate().update_factor(factor);
}
void set_type(uint8_t type){
@@ -223,13 +385,14 @@ public:
dp->m_expected_pkt_len = m_expected_pkt_len;
dp->m_rx_check = m_rx_check;
- dp->m_pps = m_pps;
dp->m_burst_total_pkts = m_burst_total_pkts;
dp->m_num_bursts = m_num_bursts;
dp->m_ibg_usec = m_ibg_usec;
dp->m_flags = m_flags;
dp->m_action_count = m_action_count;
+ dp->m_rate = m_rate;
+
return(dp);
}
@@ -241,19 +404,11 @@ public:
}
}
- double get_burst_length_usec() const {
- return ( (m_burst_total_pkts / m_pps) * 1000 * 1000);
- }
-
- double get_bps_l2() {
- return get_bps(false);
- }
-
- double get_bps_l1() {
- return get_bps(true);
+ double get_burst_length_usec() {
+ return ( (m_burst_total_pkts / get_pps()) * 1000 * 1000);
}
-
+
void Dump(FILE *fd);
StreamVmDp * getDpVm(){
@@ -321,8 +476,6 @@ public:
} m_rx_check;
- double m_pps;
-
uint32_t m_burst_total_pkts; /* valid in case of burst stSINGLE_BURST,stMULTI_BURST*/
uint32_t m_num_bursts; /* valid in case of stMULTI_BURST */
@@ -334,8 +487,7 @@ public:
private:
- double get_bps(bool layer1) {
-
+ double get_pkt_size() {
/* lazy calculate the expected packet length */
if (m_expected_pkt_len == 0) {
/* if we have a VM - it might have changed the packet (even random) */
@@ -345,17 +497,16 @@ private:
m_expected_pkt_len = m_vm.calc_expected_pkt_size(m_pkt.len);
}
}
-
- /* packet length + 4 CRC bytes to bits and multiplied by PPS */
-
- if (layer1) {
- /* layer one includes preamble, frame delimiter and interpacket gap */
- return (m_pps * (m_expected_pkt_len + 4 + 8 + 12) * 8);
- } else {
- return (m_pps * (m_expected_pkt_len + 4) * 8);
- }
+ return m_expected_pkt_len;
}
+
+
+ /* get (and calculate if need) the rate of the stream */
+ TrexStreamRate & get_rate();
+
+ /* no access to this without a lazy build method */
+ TrexStreamRate m_rate;
};
diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp
index 9d048dbd..aca74498 100644
--- a/src/stateless/cp/trex_streams_compiler.cpp
+++ b/src/stateless/cp/trex_streams_compiler.cpp
@@ -459,7 +459,7 @@ TrexStreamsCompiler::compile_internal(uint8_t por
*
*/
void
-TrexStreamsCompiler::compile_stream(const TrexStream *stream,
+TrexStreamsCompiler::compile_stream(TrexStream *stream,
double factor,
uint8_t dp_core_count,
std::vector<TrexStreamsCompiledObj *> &objs,
@@ -500,7 +500,7 @@ TrexStreamsCompiler::compile_stream(const TrexStream *stream,
*
*/
void
-TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream,
+TrexStreamsCompiler::compile_stream_on_all_cores(TrexStream *stream,
double factor,
uint8_t dp_core_count,
std::vector<TrexStreamsCompiledObj *> &objs,
@@ -509,7 +509,7 @@ TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream,
std::vector<TrexStream *> core_streams(dp_core_count);
- double per_core_rate = (stream->m_pps * (factor / dp_core_count));
+ double per_core_factor = (factor / dp_core_count);
int per_core_burst_total_pkts = (stream->m_burst_total_pkts / dp_core_count);
/* for each core - creates its own version of the stream */
@@ -521,7 +521,7 @@ TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream,
/* adjust rate and packets count */
- dp_stream->m_pps = per_core_rate;
+ dp_stream->update_rate_factor(per_core_factor);
dp_stream->m_burst_total_pkts = per_core_burst_total_pkts;
core_streams[i] = dp_stream;
@@ -547,7 +547,7 @@ TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream,
*
*/
void
-TrexStreamsCompiler::compile_stream_on_single_core(const TrexStream *stream,
+TrexStreamsCompiler::compile_stream_on_single_core(TrexStream *stream,
double factor,
TrexStreamsCompiledObj *obj,
int new_id,
@@ -560,7 +560,7 @@ TrexStreamsCompiler::compile_stream_on_single_core(const TrexStream *stream,
/* compile the VM if exists */
if (!stream->m_vm.is_vm_empty()) {
- ((TrexStream *)stream)->vm_compile();
+ stream->vm_compile();
dp_stream->m_vm_dp = stream->m_vm_dp->clone();
}
@@ -581,7 +581,7 @@ TrexStreamsCompiler::compile_stream_on_single_core(const TrexStream *stream,
* @param stream
*/
void
-TrexStreamsGraph::add_rate_events_for_stream(double &offset_usec, const TrexStream *stream) {
+TrexStreamsGraph::add_rate_events_for_stream(double &offset_usec, TrexStream *stream) {
switch (stream->get_type()) {
@@ -604,7 +604,7 @@ TrexStreamsGraph::add_rate_events_for_stream(double &offset_usec, const TrexStre
*
*/
void
-TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, const TrexStream *stream) {
+TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, TrexStream *stream) {
TrexStreamsGraphObj::rate_event_st start_event;
@@ -613,8 +613,8 @@ TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, const Tre
start_event.time = offset_usec + stream->m_isg_usec;
start_event.diff_pps = stream->get_pps();
- start_event.diff_bps_l2 = ((TrexStream *)stream)->get_bps_l2();
- start_event.diff_bps_l1 = ((TrexStream *)stream)->get_bps_l1();
+ start_event.diff_bps_l2 = stream->get_bps_L2();
+ start_event.diff_bps_l1 = stream->get_bps_L1();
m_graph_obj->add_rate_event(start_event);
/* no more events after this stream */
@@ -629,7 +629,7 @@ TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, const Tre
*
*/
void
-TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, const TrexStream *stream) {
+TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, TrexStream *stream) {
TrexStreamsGraphObj::rate_event_st start_event;
TrexStreamsGraphObj::rate_event_st stop_event;
@@ -640,9 +640,9 @@ TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, c
/* start event */
start_event.time = offset_usec + stream->m_isg_usec;
- start_event.diff_pps = stream->get_pps();
- start_event.diff_bps_l2 = ((TrexStream *)stream)->get_bps_l2();
- start_event.diff_bps_l1 = ((TrexStream *)stream)->get_bps_l1();
+ start_event.diff_pps = stream->get_pps();
+ start_event.diff_bps_l2 = stream->get_bps_L2();
+ start_event.diff_bps_l1 = stream->get_bps_L1();
m_graph_obj->add_rate_event(start_event);
/* stop event */
@@ -662,7 +662,7 @@ TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, c
*
*/
void
-TrexStreamsGraph::add_rate_events_for_stream_multi_burst(double &offset_usec, const TrexStream *stream) {
+TrexStreamsGraph::add_rate_events_for_stream_multi_burst(double &offset_usec, TrexStream *stream) {
TrexStreamsGraphObj::rate_event_st start_event;
TrexStreamsGraphObj::rate_event_st stop_event;
@@ -672,8 +672,8 @@ TrexStreamsGraph::add_rate_events_for_stream_multi_burst(double &offset_usec, co
/* for debug purposes */
start_event.diff_pps = stream->get_pps();
- start_event.diff_bps_l2 = ((TrexStream *)stream)->get_bps_l2();
- start_event.diff_bps_l1 = ((TrexStream *)stream)->get_bps_l1();
+ start_event.diff_bps_l2 = stream->get_bps_L2();
+ start_event.diff_bps_l1 = stream->get_bps_L1();
start_event.stream_id = stream->m_stream_id;
stop_event.diff_pps = -(start_event.diff_pps);
@@ -714,7 +714,7 @@ TrexStreamsGraph::generate_graph_for_one_root(uint32_t root_stream_id) {
double offset = 0;
while (true) {
- const TrexStream *stream;
+ TrexStream *stream;
/* fetch the stream from the hash - if it is not present, report an error */
try {
diff --git a/src/stateless/cp/trex_streams_compiler.h b/src/stateless/cp/trex_streams_compiler.h
index a3a1f8f7..b8b0be37 100644
--- a/src/stateless/cp/trex_streams_compiler.h
+++ b/src/stateless/cp/trex_streams_compiler.h
@@ -123,19 +123,19 @@ private:
void add_warning(const std::string &warning);
void err(const std::string &err);
- void compile_stream(const TrexStream *stream,
+ void compile_stream(TrexStream *stream,
double factor,
uint8_t dp_core_count,
std::vector<TrexStreamsCompiledObj *> &objs,
GraphNodeMap &nodes);
- void compile_stream_on_single_core(const TrexStream *stream,
+ void compile_stream_on_single_core(TrexStream *stream,
double factor,
TrexStreamsCompiledObj *obj,
int new_id,
int new_next_id);
- void compile_stream_on_all_cores(const TrexStream *stream,
+ void compile_stream_on_all_cores(TrexStream *stream,
double factor,
uint8_t dp_core_count,
std::vector<TrexStreamsCompiledObj *> &objs,
@@ -245,13 +245,13 @@ private:
void generate_graph_for_one_root(uint32_t root_stream_id);
- void add_rate_events_for_stream(double &offset, const TrexStream *stream);
- void add_rate_events_for_stream_cont(double &offset_usec, const TrexStream *stream);
- void add_rate_events_for_stream_single_burst(double &offset_usec, const TrexStream *stream);
- void add_rate_events_for_stream_multi_burst(double &offset_usec, const TrexStream *stream);
+ void add_rate_events_for_stream(double &offset, TrexStream *stream);
+ void add_rate_events_for_stream_cont(double &offset_usec, TrexStream *stream);
+ void add_rate_events_for_stream_single_burst(double &offset_usec, TrexStream *stream);
+ void add_rate_events_for_stream_multi_burst(double &offset_usec, TrexStream *stream);
/* for fast processing of streams */
- std::unordered_map<uint32_t, const TrexStream *> m_streams_hash;
+ std::unordered_map<uint32_t, TrexStream *> m_streams_hash;
/* main object to hold the graph - returned to the user */
TrexStreamsGraphObj *m_graph_obj;