some mods to the rate
authorimarom <[email protected]>
Mon, 22 Feb 2016 16:25:48 +0000 (11:25 -0500)
committerimarom <[email protected]>
Tue, 23 Feb 2016 08:09:25 +0000 (03:09 -0500)
13 files changed:
scripts/automation/trex_control_plane/stl/console/trex_console.py
scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
src/bp_sim.cpp
src/main.cpp
src/msg_manager.cpp
src/rpc-server/commands/trex_rpc_cmd_stream.cpp
src/rpc-server/commands/trex_rpc_cmds.h
src/sim/trex_sim.h
src/sim/trex_sim_stateless.cpp
src/stateless/cp/trex_stateless_port.cpp
src/stateless/cp/trex_stateless_port.h
src/stateless/cp/trex_stream.cpp
src/stateless/cp/trex_stream.h

index 9e9dcf6..0beb10d 100755 (executable)
@@ -532,7 +532,7 @@ class TRexConsole(TRexGeneralCmd):
             info = self.stateless_client.get_connection_info()
 
             exe = './trex-console --top -t -q -s {0} -p {1} --async_port {2}'.format(info['server'], info['sync_port'], info['async_port'])
-            cmd = ['xterm', '-geometry', '111x42', '-sl', '0', '-title', 'trex_tui', '-e', exe]
+            cmd = ['xterm', '-geometry', '111x47', '-sl', '0', '-title', 'trex_tui', '-e', exe]
             self.terminal = subprocess.Popen(cmd)
 
             return
index e557856..34c7a85 100644 (file)
@@ -117,8 +117,10 @@ class CTRexInfoGenerator(object):
         per_field_stats = OrderedDict([("owner", []),
                                        ("state", []),
                                        ("--", []),
-                                       ("Tx bps", []),
+                                       ("Tx bps L2", []),
+                                       ("Tx bps L1", []),
                                        ("Tx pps", []),
+                                       ("Line Util.", []),
 
                                        ("---", []),
                                        ("Rx bps", []),
@@ -313,7 +315,15 @@ class CTRexStats(object):
         # must be implemented by designated classes (such as port/ global stats)
         raise NotImplementedError()
 
+    def generate_extended_values (self, snapshot):
+        raise NotImplementedError()
+
+
     def update(self, snapshot):
+
+        # some extended generated values (from base values)
+        self.generate_extended_values(snapshot)
+
         # update
         self.latest_stats = snapshot
 
@@ -326,6 +336,8 @@ class CTRexStats(object):
         if (not self.reference_stats) or (diff_time > 3):
             self.reference_stats = self.latest_stats
 
+        
+
         self.last_update_ts = time.time()
 
 
@@ -439,6 +451,20 @@ class CGlobalStats(CTRexStats):
         return stats
 
 
+    def generate_extended_values (self, snapshot):
+        # L1 bps
+        bps = snapshot.get("m_tx_bps")
+        pps = snapshot.get("m_tx_pps")
+
+        if pps > 0:
+            avg_pkt_size = bps / (pps * 8.0)
+            bps_L1  = bps * ( (avg_pkt_size + 20.0) / avg_pkt_size )
+        else:
+            bps_L1 = 0.0
+
+        snapshot['m_tx_bps_L1'] = bps_L1
+
+
     def generate_stats(self):
         return OrderedDict([("connection", "{host}, Port {port}".format(host=self.connection_info.get("server"),
                                                                      port=self.connection_info.get("sync_port"))),
@@ -450,8 +476,11 @@ class CGlobalStats(CTRexStats):
 
                              (" ", ""),
 
-                             ("total_tx", u"{0} {1}".format( self.get("m_tx_bps", format=True, suffix="b/sec"),
-                                                              self.get_trend_gui("m_tx_bps"))),
+                             ("total_tx_L2", u"{0} {1}".format( self.get("m_tx_bps", format=True, suffix="b/sec"),
+                                                                self.get_trend_gui("m_tx_bps"))),
+
+                            ("total_tx_L1", u"{0} {1}".format( self.get("m_tx_bps_L1", format=True, suffix="b/sec"),
+                                                                self.get_trend_gui("m_tx_bps_L1"))),
 
                              ("total_rx", u"{0} {1}".format( self.get("m_rx_bps", format=True, suffix="b/sec"),
                                                               self.get_trend_gui("m_rx_bps"))),
@@ -532,6 +561,21 @@ class CPortStats(CTRexStats):
         return stats
 
 
+    def generate_extended_values (self, snapshot):
+        # L1 bps
+        bps = snapshot.get("m_total_tx_bps")
+        pps = snapshot.get("m_total_tx_pps")
+
+        if pps > 0:
+            avg_pkt_size = bps / (pps * 8.0)
+            bps_L1  = bps * ( (avg_pkt_size + 20.0) / avg_pkt_size )
+        else:
+            bps_L1 = 0.0
+
+        snapshot['m_total_tx_bps_L1'] = bps_L1
+        snapshot['m_percentage'] = (bps_L1 / self._port_obj.get_speed_bps()) * 100
+
+
     def generate_stats(self):
 
         state = self._port_obj.get_port_state_name() if self._port_obj else "" 
@@ -542,6 +586,7 @@ class CPortStats(CTRexStats):
         else:
             state = format_text(state, 'bold')
 
+
         return {"owner": self._port_obj.user if self._port_obj else "",
                 "state": "{0}".format(state),
 
@@ -550,8 +595,16 @@ class CPortStats(CTRexStats):
                 "----": " ",
                 "-----": " ",
 
-                "Tx bps": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps", show_value = False),
-                                            self.get("m_total_tx_bps", format = True, suffix = "bps")),
+                "Tx bps L1": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps_L1", show_value = False),
+                                               self.get("m_total_tx_bps_L1", format = True, suffix = "bps")),
+
+                "Tx bps L2": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps", show_value = False),
+                                               self.get("m_total_tx_bps", format = True, suffix = "bps")),
+
+                "Line Util.": u"{0} {1}".format(self.get_trend_gui("m_percentage", show_value = False),
+                                                format_text(
+                                                    self.get("m_percentage", format = True, suffix = "%") if self._port_obj else "",
+                                                    'bold')),
 
                 "Rx bps": u"{0} {1}".format(self.get_trend_gui("m_total_rx_bps", show_value = False),
                                             self.get("m_total_rx_bps", format = True, suffix = "bps")),
index a1851b5..88e2c3a 100755 (executable)
@@ -4137,7 +4137,10 @@ void CFlowGenListPerThread::start_generate_stateful(std::string erf_file_name,
 void CFlowGenList::Delete(){
     clean_p_thread_info();
     Clean();
-    delete  CPluginCallback::callback;
+    if (CPluginCallback::callback) {
+        delete  CPluginCallback::callback;
+        CPluginCallback::callback = NULL;
+    }
 }
 
 
index 6ee3a03..6a6b572 100755 (executable)
@@ -82,6 +82,8 @@ static CSimpleOpt::SOption parser_options[] =
     SO_END_OF_OPTIONS
 };
 
+static TrexStateless *m_sim_statelss_obj;
+
 static int usage(){
 
     printf(" Usage: bp_sim [OPTION] -f cfg.yaml -o outfile.erf   \n");
@@ -247,6 +249,13 @@ void set_default_mac_addr(){
     }
 }
 
+TrexStateless * get_stateless_obj() {
+    return m_sim_statelss_obj;
+}
+
+void set_stateless_obj(TrexStateless *obj) {
+    m_sim_statelss_obj = obj;
+}
 
 int main(int argc , char * argv[]){
 
index 5fe4477..9ade1bf 100755 (executable)
@@ -52,8 +52,6 @@ bool CMessagingManager::Create(uint8_t num_dp_threads,std::string a_name){
 }
 void CMessagingManager::Delete(){
 
-    assert(m_cp_to_dp);
-    assert(m_dp_to_cp);
     int i;
     for (i=0; i<m_num_dp_threads; i++) {
         CNodeRing * lp;
@@ -63,8 +61,16 @@ void CMessagingManager::Delete(){
         lp->Delete();
     }
 
-    delete []m_dp_to_cp;
-    delete []m_cp_to_dp;
+    if (m_dp_to_cp) {
+        delete [] m_dp_to_cp;
+        m_dp_to_cp = NULL;
+    }
+    
+    if (m_cp_to_dp) {
+        delete [] m_cp_to_dp;
+        m_cp_to_dp = NULL;
+    }
+    
 }
 
 CNodeRing * CMessagingManager::getRingCpToDp(uint8_t thread_id){
@@ -83,6 +89,7 @@ void CMsgIns::Free(){
     if (m_ins) {
         m_ins->Delete();
         delete m_ins;
+        m_ins = NULL;
     }
 }
 
index 7498588..0918ff0 100644 (file)
@@ -49,7 +49,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
     string type = parse_string(mode, "type", result);
 
     /* allocate a new stream based on the type */
-    std::unique_ptr<TrexStream> stream( allocate_new_stream(section, port_id, stream_id, result) );
+    std::unique_ptr<TrexStream> stream = allocate_new_stream(section, port_id, stream_id, result);
 
     /* save this for future queries */
     stream->store_stream_json(section);
@@ -98,7 +98,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
 
     /* parse VM */
     const Json::Value &vm =  parse_object(section ,"vm", result);
-    parse_vm(vm, stream.get(), result);
+    parse_vm(vm, stream, result);
 
     /* parse RX info */
     const Json::Value &rx = parse_object(section, "rx_stats", result);
@@ -113,7 +113,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
     }
 
     /* make sure this is a valid stream to add */
-    validate_stream(stream.get(), result);
+    validate_stream(stream, result);
 
     TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(stream->m_port_id);
 
@@ -131,10 +131,10 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
 
 
 
-TrexStream *
+std::unique_ptr<TrexStream>
 TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t port_id, uint32_t stream_id, Json::Value &result) {
 
-    TrexStream *stream = NULL;
+    std::unique_ptr<TrexStream> stream;
 
     const Json::Value &mode = parse_object(section, "mode", result);
     std::string type = parse_string(mode, "type", result);
@@ -142,13 +142,13 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t por
 
     if (type == "continuous") {
 
-        stream = new TrexStream( TrexStream::stCONTINUOUS, port_id, stream_id);
+        stream.reset(new TrexStream( TrexStream::stCONTINUOUS, port_id, stream_id));
 
     } else if (type == "single_burst") {
 
         uint32_t total_pkts      = parse_int(mode, "total_pkts", result);
 
-        stream = new TrexStream(TrexStream::stSINGLE_BURST, port_id, stream_id);
+        stream.reset(new TrexStream(TrexStream::stSINGLE_BURST, port_id, stream_id));
         stream->set_single_burst(total_pkts);
 
 
@@ -158,7 +158,7 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t por
         uint32_t  num_bursts       = parse_int(mode, "count", result);
         uint32_t  pkts_per_burst   = parse_int(mode, "pkts_per_burst", result);
 
-        stream = new TrexStream(TrexStream::stMULTI_BURST,port_id, stream_id );
+        stream.reset(new TrexStream(TrexStream::stMULTI_BURST,port_id, stream_id ));
         stream->set_multi_burst(pkts_per_burst,num_bursts,ibg_usec);
 
 
@@ -175,9 +175,14 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t por
 }
 
 void 
-TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
 
-    double value            = parse_double(rate, "value", result);
+    double value = parse_double(rate, "value", result);
+    if (value <= 0) {
+        std::stringstream ss;
+        ss << "rate value must be a positive number - got: '" << value << "'";
+        generate_parse_err(result, ss.str());
+    }
 
     auto rate_types = {"pps", "bps_L1", "bps_L2", "percentage"};
     std::string rate_type = parse_choice(rate, "type", rate_types, result);
@@ -198,7 +203,7 @@ TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, TrexStream *stream, Jso
 }
 
 void 
-TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
 
     uint16_t pkt_offset = parse_uint16(inst, "pkt_offset", result); 
     stream->m_vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(pkt_offset));
@@ -206,7 +211,7 @@ TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, TrexStream
 
 
 void 
-TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result){
+TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result){
 
     std::string  flow_var_name = parse_string(inst, "name", result);
 
@@ -215,7 +220,7 @@ TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexS
 
 
 void 
-TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result){
+TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result){
 
 
     std::string  flow_var_name = parse_string(inst, "name", result);
@@ -239,7 +244,7 @@ TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, Trex
 
 
 void 
-TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
     std::string  flow_var_name = parse_string(inst, "name", result);
 
     auto sizes = {1, 2, 4, 8};
@@ -326,7 +331,7 @@ TrexRpcCmdAddStream::parse_vm_instr_write_mask_flow_var(const Json::Value &inst,
 
 
 void 
-TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
     std::string  flow_var_name = parse_string(inst, "name", result);
     uint16_t     pkt_offset    = parse_uint16(inst, "pkt_offset", result);
     int          add_value     = parse_int(inst,    "add_value", result);
@@ -339,7 +344,7 @@ TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, Trex
 }
 
 void 
-TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
 
     const Json::Value &instructions =  parse_array(vm ,"instructions", result);
 
@@ -386,7 +391,7 @@ TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::V
 }
 
 void
-TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::validate_stream(const std::unique_ptr<TrexStream> &stream, Json::Value &result) {
 
     /* add the stream to the port's stream table */
     TrexStatelessPort * port = get_stateless_obj()->get_port_by_id(stream->m_port_id);
@@ -395,7 +400,6 @@ TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &resu
     if (port->get_stream_by_id(stream->m_stream_id)) {
         std::stringstream ss;
         ss << "stream " << stream->m_stream_id << " already exists";
-        delete stream;
         generate_execute_err(result, ss.str());
     }
 
index 3da1e4f..d90d880 100644 (file)
@@ -24,6 +24,7 @@ limitations under the License.
 
 #include <trex_rpc_cmd_api.h>
 #include <json/json.h>
+#include <memory>
 
 class TrexStream;
 
@@ -91,16 +92,16 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveStream,       "remove_stream",        2, tru
 TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdAddStream, "add_stream", 3, true, 
 
 /* extended part */
-TrexStream * allocate_new_stream(const Json::Value &section, uint8_t port_id, uint32_t stream_id, Json::Value &result);
-void validate_stream(const TrexStream *stream, Json::Value &result);
-void parse_vm(const Json::Value &vm, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_rate(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_write_mask_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
+std::unique_ptr<TrexStream> allocate_new_stream(const Json::Value &section, uint8_t port_id, uint32_t stream_id, Json::Value &result);
+void validate_stream(const std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm(const Json::Value &vm, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_checksum(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_tuple_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_rate(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_write_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_write_mask_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
 
 );
 
index 8feb7bc..99bfb28 100644 (file)
@@ -25,6 +25,7 @@ limitations under the License.
 #include <os_time.h>
 #include <bp_sim.h>
 #include <json/json.h>
+#include <trex_stateless.h>
 
 int gtest_main(int argc, char **argv);
 
@@ -32,12 +33,49 @@ class TrexStateless;
 class TrexPublisher;
 class DpToCpHandler;
 
+void set_stateless_obj(TrexStateless *obj);
 
 static inline bool 
 in_range(int x, int low, int high) {
     return ( (x >= low) && (x <= high) );
 }
 
+/*************** hook for platform API **************/
+class SimPlatformApi : public TrexPlatformApi {
+public:
+    SimPlatformApi(int dp_core_count) {
+        m_dp_core_count = dp_core_count;
+    }
+
+    virtual uint8_t get_dp_core_count() const {
+        return m_dp_core_count;
+    }
+
+    virtual void get_global_stats(TrexPlatformGlobalStats &stats) const {
+    }
+
+    virtual void get_interface_info(uint8_t interface_id, std::string &driver_name, driver_speed_e &speed) const {
+        driver_name = "TEST";
+        speed = TrexPlatformApi::SPEED_10G;
+    }
+
+    virtual void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const {
+    }
+
+    virtual void port_id_to_cores(uint8_t port_id, std::vector<std::pair<uint8_t, uint8_t>> &cores_id_list) const {
+        for (int i = 0; i < m_dp_core_count; i++) {
+             cores_id_list.push_back(std::make_pair(i, 0));
+        }
+    }
+
+    virtual void publish_async_data_now(uint32_t key) const {
+
+    }
+
+private:
+    int m_dp_core_count;
+};
+
 /**
  * interface for a sim target
  * 
@@ -67,12 +105,27 @@ public:
  * 
  * @author imarom (28-Dec-15)
  */
-class SimGtest : public SimInterface {
+class SimGtest : SimInterface {
 public:
 
     int run(int argc, char **argv) {
+        TrexStatelessCfg cfg;
+    
+        cfg.m_port_count         = 1;
+        cfg.m_rpc_req_resp_cfg   = NULL;
+        cfg.m_rpc_async_cfg      = NULL;
+        cfg.m_rpc_server_verbose = false;
+        cfg.m_platform_api       = new SimPlatformApi(1);;
+        cfg.m_publisher          = NULL;
+
+        set_stateless_obj(new TrexStateless(cfg));
         assert( CMsgIns::Ins()->Create(4) );
-        return gtest_main(argc, argv);
+        int rc = gtest_main(argc, argv);
+
+        delete get_stateless_obj();
+        set_stateless_obj(NULL);
+
+        return rc;
     }
 };
 
@@ -112,9 +165,6 @@ public:
             int limit,
             bool is_dry_run);
 
-    TrexStateless * get_stateless_obj() {
-        return m_trex_stateless;
-    }
 
     void set_verbose(bool enable) {
         m_verbose = enable;
@@ -149,7 +199,6 @@ private:
         return m_verbose;
     }
 
-    TrexStateless   *m_trex_stateless;
     DpToCpHandler   *m_dp_to_cp_handler;
     TrexPublisher   *m_publisher;
     CFlowGenList     m_fl;
index 897d1fe..a831603 100644 (file)
@@ -54,10 +54,6 @@ static string format_num(double num, const string &suffix = "") {
     return "NaN";
 }
 
-TrexStateless * get_stateless_obj() {
-    return SimStateless::get_instance().get_stateless_obj();
-}
-
 
 class SimRunException : public std::runtime_error 
 {
@@ -69,41 +65,6 @@ public:
     }
 };
 
-/*************** hook for platform API **************/
-class SimPlatformApi : public TrexPlatformApi {
-public:
-    SimPlatformApi(int dp_core_count) {
-        m_dp_core_count = dp_core_count;
-    }
-
-    virtual uint8_t get_dp_core_count() const {
-        return m_dp_core_count;
-    }
-
-    virtual void get_global_stats(TrexPlatformGlobalStats &stats) const {
-    }
-
-    virtual void get_interface_info(uint8_t interface_id, std::string &driver_name, driver_speed_e &speed) const {
-        driver_name = "TEST";
-        speed = TrexPlatformApi::SPEED_10G;
-    }
-
-    virtual void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const {
-    }
-
-    virtual void port_id_to_cores(uint8_t port_id, std::vector<std::pair<uint8_t, uint8_t>> &cores_id_list) const {
-        for (int i = 0; i < m_dp_core_count; i++) {
-             cores_id_list.push_back(std::make_pair(i, 0));
-        }
-    }
-
-    virtual void publish_async_data_now(uint32_t key) const {
-
-    }
-
-private:
-    int m_dp_core_count;
-};
 
 /**
  * handler for DP to CP messages
@@ -146,7 +107,6 @@ public:
 ************************/
 
 SimStateless::SimStateless() {
-    m_trex_stateless    = NULL;
     m_publisher         = NULL;
     m_dp_to_cp_handler  = NULL;
     m_verbose           = false;
@@ -198,9 +158,10 @@ SimStateless::run(const string &json_filename,
 
 
 SimStateless::~SimStateless() {
-    if (m_trex_stateless) {
-        delete m_trex_stateless;
-        m_trex_stateless = NULL;
+    
+    if (get_stateless_obj()) {
+        delete get_stateless_obj();
+        set_stateless_obj(NULL);
     }
 
     if (m_publisher) {
@@ -231,11 +192,11 @@ SimStateless::prepare_control_plane() {
     cfg.m_platform_api       = new SimPlatformApi(m_dp_core_count);
     cfg.m_publisher          = m_publisher;
 
-    m_trex_stateless = new TrexStateless(cfg);
+    set_stateless_obj(new TrexStateless(cfg));
 
-    m_trex_stateless->launch_control_plane();
+    get_stateless_obj()->launch_control_plane();
 
-    for (auto &port : m_trex_stateless->get_port_list()) {
+    for (auto &port : get_stateless_obj()->get_port_list()) {
         port->acquire("test", 0, true);
     }
 
@@ -274,7 +235,7 @@ SimStateless::execute_json(const std::string &json_filename) {
     buffer << test.rdbuf();
 
     try {
-        rep = m_trex_stateless->get_rpc_server()->test_inject_request(buffer.str());
+        rep = get_stateless_obj()->get_rpc_server()->test_inject_request(buffer.str());
     } catch (TrexRpcException &e) {
         throw SimRunException(e.what());
     }
@@ -321,8 +282,10 @@ static inline bool is_debug() {
 
 void
 SimStateless::show_intro(const std::string &out_filename) {
-    uint64_t bps = 0;
-    uint64_t pps = 0;
+    double pps;
+    double bps_L1;
+    double bps_L2;
+    double percentage;
 
     std::cout << "\nGeneral info:\n";
     std::cout << "------------\n\n";
@@ -356,10 +319,12 @@ SimStateless::show_intro(const std::string &out_filename) {
 
     std::cout << "stream count:             " << port->get_stream_count() << "\n";
 
-    port->get_port_effective_rate(bps, pps);
+    port->get_port_effective_rate(pps, bps_L1, bps_L2, percentage);
 
-    std::cout << "max BPS:                  " << format_num(bps, "bps") << "\n";
-    std::cout << "max PPS:                  " << format_num(pps, "pps") << "\n";
+    std::cout << "max PPS    :              " << format_num(pps,        "pps") << "\n";
+    std::cout << "max BPS L1 :              " << format_num(bps_L1,     "bps") << "\n";
+    std::cout << "max BPS L2 :              " << format_num(bps_L2,     "bps") << "\n";
+    std::cout << "line util. :              " << format_num(percentage,  "%") << "\n";
 
     std::cout << "\n\nStarting simulation...\n";
 }
index 8ee46d2..75f77cf 100644 (file)
@@ -631,7 +631,10 @@ TrexStatelessPort::validate(void) {
 
 
 void
-TrexStatelessPort::get_port_effective_rate(uint64_t &bps, uint64_t &pps) {
+TrexStatelessPort::get_port_effective_rate(double &pps,
+                                           double &bps_L1,
+                                           double &bps_L2,
+                                           double &percentage) {
 
     if (get_stream_count() == 0) {
         return;
@@ -641,8 +644,11 @@ TrexStatelessPort::get_port_effective_rate(uint64_t &bps, uint64_t &pps) {
         generate_streams_graph();
     }
 
-    bps = m_graph_obj->get_max_bps_l2() * m_factor;
-    pps = m_graph_obj->get_max_pps() * m_factor;
+    pps        = m_graph_obj->get_max_pps()    * m_factor;
+    bps_L1     = m_graph_obj->get_max_bps_l1() * m_factor;
+    bps_L2     = m_graph_obj->get_max_bps_l2() * m_factor;
+    percentage = (bps_L1 / get_port_speed_bps()) * 100.0;
+    
 }
 
 /************* Trex Port Owner **************/
index b0b0ddf..a101cef 100644 (file)
@@ -316,10 +316,11 @@ public:
      * 
      * @author imarom (07-Jan-16)
      * 
-     * @param bps 
-     * @param pps 
      */
-    void get_port_effective_rate(uint64_t &bps, uint64_t &pps);
+    void get_port_effective_rate(double &pps,
+                                 double &bps_L1,
+                                 double &bps_L2,
+                                 double &percentage);
 
 private:
 
index f4a8e80..357a288 100644 (file)
@@ -106,16 +106,16 @@ void TrexStream::Dump(FILE *fd){
 
     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());
+    fprintf(fd," pps         : %f\n", m_rate.get_pps());
+    fprintf(fd," bps L1      : %f\n", m_rate.get_bps_L1());
+    fprintf(fd," bps L2      : %f\n", m_rate.get_bps_L2());
+    fprintf(fd," percentage  : %f\n", m_rate.get_percentage());
 
 }
 
  
 TrexStream::TrexStream(uint8_t type,
-                       uint8_t port_id, uint32_t stream_id) : m_port_id(port_id), m_stream_id(stream_id) {
+                       uint8_t port_id, uint32_t stream_id) : m_port_id(port_id), m_stream_id(stream_id) , m_rate(*this) {
 
     /* default values */
     m_type            = type;
@@ -160,18 +160,6 @@ 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
@@ -253,3 +241,16 @@ int TrexStreamTable::size() {
 }
 
 
+/**************************************
+ * TrexStreamRate
+ *************************************/
+uint64_t
+TrexStreamRate::get_line_speed_bps() {
+    TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(m_stream.m_port_id);
+    return port->get_port_speed_bps();
+}
+
+double
+TrexStreamRate::get_pkt_size() {
+    return m_stream.get_pkt_size();
+}
index f473956..66f05b1 100644 (file)
@@ -103,6 +103,8 @@ public:
         }
 }; 
 
+class TrexStream;
+
 /**
  * describes a stream rate
  * 
@@ -121,9 +123,21 @@ public:
         RATE_PERCENTAGE
     };
 
-    TrexStreamRate() {
-        m_base_rate_type  = RATE_INVALID;
-        m_is_calculated   = false;
+    TrexStreamRate(TrexStream &stream) : m_stream(stream) {
+        m_pps        = 0;
+        m_bps_L1     = 0;
+        m_bps_L2     = 0;
+        m_percentage = 0;
+    }
+
+
+    TrexStreamRate& operator=(const TrexStreamRate& other) {
+        m_pps        = other.m_pps;
+        m_bps_L1     = other.m_bps_L1;
+        m_bps_L2     = other.m_bps_L2;
+        m_percentage = other.m_percentage;
+
+        return (*this);
     }
 
     /**
@@ -132,121 +146,133 @@ public:
      * 
      */
     void set_base_rate(rate_type_e type, double value) {
-        m_base_rate_type = type;
-        m_value          = value;
-        m_is_calculated  = false;
-    }
-
+        m_pps        = 0;
+        m_bps_L1     = 0;
+        m_bps_L2     = 0;
+        m_percentage = 0;
 
-    /**
-     * calculates all the rates from the base rate
-     * 
-     */
-    void calculate(uint16_t pkt_size, uint64_t line_bps) {
+        assert(value > 0);
 
-        switch (m_base_rate_type) {
-       
+        switch (type) {
         case RATE_PPS:
-            calculate_from_pps(m_value, pkt_size, line_bps);
+            m_pps = value;
             break;
-
         case RATE_BPS_L1:
-            calculate_from_bps_L1(m_value, pkt_size, line_bps);
+            m_bps_L1 = value;
             break;
-
         case RATE_BPS_L2:
-            calculate_from_bps_L2(m_value, pkt_size, line_bps);
+            m_bps_L2 = value;
             break;
-
         case RATE_PERCENTAGE:
-            calculate_from_percentage(m_value, pkt_size, line_bps);
+            m_percentage = value;
             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);
+        if (m_pps == 0) {
+            calculate();
+        }
         return (m_pps);
     }
     
     double get_bps_L1() {
-        assert(m_is_calculated);
+        if (m_bps_L1 == 0) {
+            calculate();
+        }
         return (m_bps_L1);
     }
 
     double get_bps_L2() {
-        assert(m_is_calculated);
+        if (m_bps_L2 == 0) {
+            calculate();
+        }
         return m_bps_L2;
     }
 
     double get_percentage() {
-        assert(m_is_calculated);
+        if (m_percentage == 0) {
+            calculate();
+        }
         return m_percentage;
     }
 
+  
+
+    /* update the rate by a factor */
+    void update_factor(double factor) {
+        /* if all are non zero - it works, if only one (base) is also works */
+        m_pps        *= factor;
+        m_bps_L1     *= factor;
+        m_bps_L2     *= factor;
+        m_percentage *= factor;
+    }
+
+   
+
 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;
+    /**
+     * calculates all the rates from the base rate
+     * 
+     */
+    void calculate() {
+
+        if (m_pps != 0) {
+            calculate_from_pps();
+        } else if (m_bps_L1 != 0) {
+            calculate_from_bps_L1();
+        } else if (m_bps_L2 != 0) {
+            calculate_from_bps_L2();
+        } else if (m_percentage != 0) {
+            calculate_from_percentage();
+        } else {
+            assert(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;
+    uint64_t get_line_speed_bps();
+    double get_pkt_size();
+
+    void calculate_from_pps() {
+        m_bps_L1     = m_pps * (get_pkt_size() + 24) * 8;
+        m_bps_L2     = m_pps * (get_pkt_size() + 4) * 8;
+        m_percentage = (m_bps_L1 / get_line_speed_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_bps_L1() {
+        m_bps_L2     = m_bps_L1 * ( (get_pkt_size() + 4.0) / (get_pkt_size() + 24.0) );
+        m_pps        = m_bps_L2 / (8 * (get_pkt_size() + 4));
+        m_percentage = (m_bps_L1 / get_line_speed_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));
 
+    void calculate_from_bps_L2() {
+        m_bps_L1     = m_bps_L2 * ( (get_pkt_size() + 24.0) / (get_pkt_size() + 4.0));
+        m_pps        = m_bps_L2 / (8 * (get_pkt_size() + 4));
+        m_percentage = (m_bps_L1 / get_line_speed_bps()) * 100.0;
     }
 
-    rate_type_e  m_base_rate_type;
-    double       m_value;
+    void calculate_from_percentage() {
+        m_bps_L1     = (m_percentage / 100.0) * get_line_speed_bps();
+        m_bps_L2     = m_bps_L1 * ( (get_pkt_size() + 4.0) / (get_pkt_size() + 24.0) );
+        m_pps        = m_bps_L2 / (8 * (get_pkt_size() + 4));
+
+    }
 
-    bool         m_is_calculated;
     double       m_pps;
     double       m_bps_L1;
     double       m_bps_L2;
     double       m_percentage;
 
+    /* reference to the owner class */
+    TrexStream  &m_stream;
 };
 
 /**
@@ -254,6 +280,7 @@ private:
  * 
  */
 class TrexStream {
+friend class TrexStreamRate;
 
 public:
     enum STREAM_TYPE {
@@ -298,19 +325,19 @@ public:
 
 
     double get_pps() {
-        return get_rate().get_pps();
+        return m_rate.get_pps();
     }
 
     double get_bps_L1() {
-        return get_rate().get_bps_L1();
+        return m_rate.get_bps_L1();
     }
 
     double get_bps_L2() {
-        return get_rate().get_bps_L2();
+        return m_rate.get_bps_L2();
     }
 
     double get_bw_percentage() {
-        return get_rate().get_percentage();
+        return m_rate.get_percentage();
     }
 
     void set_rate(TrexStreamRate::rate_type_e type, double value) {
@@ -318,7 +345,7 @@ public:
     }
 
     void update_rate_factor(double factor) {
-        get_rate().update_factor(factor);
+        m_rate.update_factor(factor);
     }
 
     void set_type(uint8_t type){
@@ -502,9 +529,6 @@ private:
     }
 
   
-    /* 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;
 };