diff options
author | 2015-10-22 05:31:22 +0300 | |
---|---|---|
committer | 2015-10-22 05:31:22 +0300 | |
commit | f5c4a8051d697c086eb0d1c8ce3ac90ab245d249 (patch) | |
tree | fb0d379947c4b1984b77f6594d27f96d72c3cba0 /src/stateless/cp/trex_stateless.cpp | |
parent | 508703e11a3fad3e44535c5433f803d77f28e245 (diff) | |
parent | 876c76572fdb2fb8f0e8db21bc420d284dc05950 (diff) |
Merge branch 'master' into dan_stateless
Diffstat (limited to 'src/stateless/cp/trex_stateless.cpp')
-rw-r--r-- | src/stateless/cp/trex_stateless.cpp | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/stateless/cp/trex_stateless.cpp b/src/stateless/cp/trex_stateless.cpp new file mode 100644 index 00000000..72762e26 --- /dev/null +++ b/src/stateless/cp/trex_stateless.cpp @@ -0,0 +1,212 @@ +/* + Itay Marom + Cisco Systems, Inc. +*/ + +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include <trex_stateless.h> +#include <trex_stateless_port.h> + +#include <sched.h> +#include <iostream> +#include <unistd.h> + +using namespace std; + +/*********************************************************** + * Trex stateless object + * + **********************************************************/ +TrexStateless::TrexStateless() { + m_is_configured = false; +} + + +/** + * configure the singleton stateless object + * + */ +void TrexStateless::configure(const TrexStatelessCfg &cfg) { + + TrexStateless& instance = get_instance_internal(); + + /* check status */ + if (instance.m_is_configured) { + throw TrexException("re-configuration of stateless object is not allowed"); + } + + /* create RPC servers */ + + /* set both servers to mutex each other */ + instance.m_rpc_server = new TrexRpcServer(cfg.m_rpc_req_resp_cfg, cfg.m_rpc_async_cfg, &instance.m_global_cp_lock); + instance.m_rpc_server->set_verbose(cfg.m_rpc_server_verbose); + + /* configure ports */ + + instance.m_port_count = cfg.m_port_count; + + for (int i = 0; i < instance.m_port_count; i++) { + instance.m_ports.push_back(new TrexStatelessPort(i)); + } + + /* cores */ + instance.m_dp_core_count = cfg.m_dp_core_count; + for (int i = 0; i < instance.m_dp_core_count; i++) { + instance.m_dp_cores.push_back(new TrexStatelessDpCore(i)); + } + + /* done */ + instance.m_is_configured = true; +} + +/** + * starts the control plane side + * + */ +void +TrexStateless::launch_control_plane() { + //std::cout << "\n on control/master core \n"; + + /* pin this process to the current running CPU + any new thread will be called on the same CPU + (control plane restriction) + */ + cpu_set_t mask; + CPU_ZERO(&mask); + CPU_SET(sched_getcpu(), &mask); + sched_setaffinity(0, sizeof(mask), &mask); + + /* start RPC server */ + m_rpc_server->start(); +} + +void +TrexStateless::launch_on_dp_core(uint8_t core_id) { + m_dp_cores[core_id - 1]->run(); +} + +/** + * destroy the singleton and release all memory + * + * @author imarom (08-Oct-15) + */ +void +TrexStateless::destroy() { + TrexStateless& instance = get_instance_internal(); + + if (!instance.m_is_configured) { + return; + } + + /* release memory for ports */ + for (auto port : instance.m_ports) { + delete port; + } + instance.m_ports.clear(); + + /* stops the RPC server */ + instance.m_rpc_server->stop(); + delete instance.m_rpc_server; + + instance.m_rpc_server = NULL; + + /* done */ + instance.m_is_configured = false; +} + +/** + * fetch a port by ID + * + */ +TrexStatelessPort * TrexStateless::get_port_by_id(uint8_t port_id) { + if (port_id >= m_port_count) { + throw TrexException("index out of range"); + } + + return m_ports[port_id]; + +} + +uint8_t +TrexStateless::get_port_count() { + return m_port_count; +} + +uint8_t +TrexStateless::get_dp_core_count() { + return m_dp_core_count; +} + +void +TrexStateless::update_stats() { + + /* update CPU util. + TODO + */ + m_stats.m_stats.m_cpu_util = 0; + + /* for every port update and accumulate */ + for (uint8_t i = 0; i < m_port_count; i++) { + m_ports[i]->update_stats(); + + const TrexPortStats & port_stats = m_ports[i]->get_stats(); + + m_stats.m_stats.m_tx_bps += port_stats.m_stats.m_tx_bps; + m_stats.m_stats.m_rx_bps += port_stats.m_stats.m_rx_bps; + + m_stats.m_stats.m_tx_pps += port_stats.m_stats.m_tx_pps; + m_stats.m_stats.m_rx_pps += port_stats.m_stats.m_rx_pps; + + m_stats.m_stats.m_total_tx_pkts += port_stats.m_stats.m_total_tx_pkts; + m_stats.m_stats.m_total_rx_pkts += port_stats.m_stats.m_total_rx_pkts; + + m_stats.m_stats.m_total_tx_bytes += port_stats.m_stats.m_total_tx_bytes; + m_stats.m_stats.m_total_rx_bytes += port_stats.m_stats.m_total_rx_bytes; + + m_stats.m_stats.m_tx_rx_errors += port_stats.m_stats.m_tx_rx_errors; + } +} + +void +TrexStateless::encode_stats(Json::Value &global) { + + global["cpu_util"] = m_stats.m_stats.m_cpu_util; + + global["tx_bps"] = m_stats.m_stats.m_tx_bps; + global["rx_bps"] = m_stats.m_stats.m_rx_bps; + + global["tx_pps"] = m_stats.m_stats.m_tx_pps; + global["rx_pps"] = m_stats.m_stats.m_rx_pps; + + global["total_tx_pkts"] = Json::Value::UInt64(m_stats.m_stats.m_total_tx_pkts); + global["total_rx_pkts"] = Json::Value::UInt64(m_stats.m_stats.m_total_rx_pkts); + + global["total_tx_bytes"] = Json::Value::UInt64(m_stats.m_stats.m_total_tx_bytes); + global["total_rx_bytes"] = Json::Value::UInt64(m_stats.m_stats.m_total_rx_bytes); + + global["tx_rx_errors"] = Json::Value::UInt64(m_stats.m_stats.m_tx_rx_errors); + + for (uint8_t i = 0; i < m_port_count; i++) { + std::stringstream ss; + + ss << "port " << i; + Json::Value &port_section = global[ss.str()]; + + m_ports[i]->encode_stats(port_section); + } +} + |