diff options
author | Hanoh Haim <hhaim@cisco.com> | 2016-02-16 16:08:23 +0200 |
---|---|---|
committer | Hanoh Haim <hhaim@cisco.com> | 2016-02-16 16:08:23 +0200 |
commit | 47c865838678444c0075aab94267972a3a3cbfff (patch) | |
tree | 3551714c2b6e2f3c71374754732ab0e01c7d83f1 /src | |
parent | 75c84998813a359cb8619e80507e04f21d71de89 (diff) |
step instruction support
Diffstat (limited to 'src')
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 11 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.cpp | 321 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.h | 195 | ||||
-rw-r--r-- | src/stateless/cp/trex_vm_splitter.cpp | 5 |
4 files changed, 452 insertions, 80 deletions
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 0262fd7c..508967b9 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -249,6 +249,7 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream uint64_t init_value = parse_uint64(inst, "init_value", result); uint64_t min_value = parse_uint64(inst, "min_value", result); uint64_t max_value = parse_uint64(inst, "max_value", result); + uint64_t step = parse_uint64(inst, "step", result); if (max_value < min_value ) { std::stringstream ss; @@ -257,7 +258,7 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream } if (flow_var_size == 1 ) { - if ( (init_value > UINT8_MAX) || (min_value > UINT8_MAX) || (max_value > UINT8_MAX)) { + if ( (init_value > UINT8_MAX) || (min_value > UINT8_MAX) || (max_value > UINT8_MAX) || (step >UINT8_MAX) ) { std::stringstream ss; ss << "VM: request val is bigger than " << UINT8_MAX; generate_parse_err(result, ss.str()); @@ -265,7 +266,7 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream } if (flow_var_size == 2 ) { - if ( (init_value > UINT16_MAX) || (min_value > UINT16_MAX) || (max_value > UINT16_MAX)) { + if ( (init_value > UINT16_MAX) || (min_value > UINT16_MAX) || (max_value > UINT16_MAX) || (step > UINT16_MAX) ) { std::stringstream ss; ss << "VM: request val is bigger than " << UINT16_MAX; generate_parse_err(result, ss.str()); @@ -273,7 +274,7 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream } if (flow_var_size == 4 ) { - if ( (init_value > UINT32_MAX) || (min_value > UINT32_MAX) || (max_value > UINT32_MAX)) { + if ( (init_value > UINT32_MAX) || (min_value > UINT32_MAX) || (max_value > UINT32_MAX) || (step > UINT32_MAX) ) { std::stringstream ss; ss << "VM: request val is bigger than " << UINT32_MAX; generate_parse_err(result, ss.str()); @@ -286,7 +287,9 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream op_type, init_value, min_value, - max_value)); + max_value, + step) + ); } void diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp index b91f0fb5..f99c3c9c 100644 --- a/src/stateless/cp/trex_stream_vm.cpp +++ b/src/stateless/cp/trex_stream_vm.cpp @@ -102,7 +102,7 @@ void StreamVmInstructionFlowMan::Dump(FILE *fd){ break; }; - fprintf(fd," (%lu:%lu:%lu) \n",m_init_value,m_min_value,m_max_value); + fprintf(fd," (%lu:%lu:%lu:%lu) \n",m_init_value,m_min_value,m_max_value,m_step); } @@ -412,31 +412,52 @@ void StreamVm::build_program(){ if (lpMan->m_size_bytes == 1 ){ - - uint8_t op=StreamDPVmInstructions::ditINC8; - - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ - op = StreamDPVmInstructions::ditINC8 ; - } - - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ - op = StreamDPVmInstructions::ditDEC8 ; + if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){ + uint8_t op=StreamDPVmInstructions::ditINC8; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC8 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC8 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ + op = StreamDPVmInstructions::ditRANDOM8 ; + } + + StreamDPOpFlowVar8 fv8; + fv8.m_op = op; + fv8.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv8.m_min_val = (uint8_t)lpMan->m_min_value; + fv8.m_max_val = (uint8_t)lpMan->m_max_value; + m_instructions.add_command(&fv8,sizeof(fv8)); + }else{ + uint8_t op=StreamDPVmInstructions::ditINC8_STEP; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC8_STEP ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC8_STEP ; + } + + StreamDPOpFlowVar8Step fv8; + fv8.m_op = op; + fv8.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv8.m_min_val = (uint8_t)lpMan->m_min_value; + fv8.m_max_val = (uint8_t)lpMan->m_max_value; + fv8.m_step = (uint8_t)lpMan->m_step; + m_instructions.add_command(&fv8,sizeof(fv8)); } - - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ - op = StreamDPVmInstructions::ditRANDOM8 ; - } - - StreamDPOpFlowVar8 fv8; - fv8.m_op = op; - fv8.m_flow_offset = get_var_offset(lpMan->m_var_name); - fv8.m_min_val = (uint8_t)lpMan->m_min_value; - fv8.m_max_val = (uint8_t)lpMan->m_max_value; - m_instructions.add_command(&fv8,sizeof(fv8)); } if (lpMan->m_size_bytes == 2 ){ uint8_t op; + if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){ + op = StreamDPVmInstructions::ditINC16; @@ -458,56 +479,119 @@ void StreamVm::build_program(){ fv16.m_min_val = (uint16_t)lpMan->m_min_value; fv16.m_max_val = (uint16_t)lpMan->m_max_value; m_instructions.add_command(&fv16,sizeof(fv16)); - } + }else{ - if (lpMan->m_size_bytes == 4 ){ - uint8_t op; + op = StreamDPVmInstructions::ditINC16_STEP; - op = StreamDPVmInstructions::ditINC32; + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC16_STEP ; + } - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ - op = StreamDPVmInstructions::ditINC32 ; - } + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC16_STEP ; + } - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ - op = StreamDPVmInstructions::ditDEC32 ; - } + StreamDPOpFlowVar16Step fv16; + fv16.m_op = op; + fv16.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv16.m_min_val = (uint16_t)lpMan->m_min_value; + fv16.m_max_val = (uint16_t)lpMan->m_max_value; + fv16.m_step = (uint16_t)lpMan->m_step; - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ - op = StreamDPVmInstructions::ditRANDOM32 ; - } - - StreamDPOpFlowVar32 fv32; - fv32.m_op = op; - fv32.m_flow_offset = get_var_offset(lpMan->m_var_name); - fv32.m_min_val = (uint32_t)lpMan->m_min_value; - fv32.m_max_val = (uint32_t)lpMan->m_max_value; - m_instructions.add_command(&fv32,sizeof(fv32)); + m_instructions.add_command(&fv16,sizeof(fv16)); + } } - if (lpMan->m_size_bytes == 8 ){ + if (lpMan->m_size_bytes == 4 ){ uint8_t op; + if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){ + op = StreamDPVmInstructions::ditINC32; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC32 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC32 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ + op = StreamDPVmInstructions::ditRANDOM32 ; + } + + StreamDPOpFlowVar32 fv32; + fv32.m_op = op; + fv32.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv32.m_min_val = (uint32_t)lpMan->m_min_value; + fv32.m_max_val = (uint32_t)lpMan->m_max_value; + m_instructions.add_command(&fv32,sizeof(fv32)); + }else{ + op = StreamDPVmInstructions::ditINC32_STEP; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC32_STEP ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC32_STEP ; + } + + StreamDPOpFlowVar32Step fv32; + fv32.m_op = op; + fv32.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv32.m_min_val = (uint32_t)lpMan->m_min_value; + fv32.m_max_val = (uint32_t)lpMan->m_max_value; + fv32.m_step = (uint32_t)lpMan->m_step; + m_instructions.add_command(&fv32,sizeof(fv32)); + } + } - op = StreamDPVmInstructions::ditINC64; - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ - op = StreamDPVmInstructions::ditINC64 ; - } + if (lpMan->m_size_bytes == 8 ){ + uint8_t op; - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ - op = StreamDPVmInstructions::ditDEC64 ; - } + if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){ - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ - op = StreamDPVmInstructions::ditRANDOM64 ; + op = StreamDPVmInstructions::ditINC64; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC64 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC64 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ + op = StreamDPVmInstructions::ditRANDOM64 ; + } + + StreamDPOpFlowVar64 fv64; + fv64.m_op = op; + fv64.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv64.m_min_val = (uint64_t)lpMan->m_min_value; + fv64.m_max_val = (uint64_t)lpMan->m_max_value; + m_instructions.add_command(&fv64,sizeof(fv64)); + }else{ + + op = StreamDPVmInstructions::ditINC64_STEP; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC64_STEP ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC64_STEP ; + } + + StreamDPOpFlowVar64Step fv64; + fv64.m_op = op; + fv64.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv64.m_min_val = (uint64_t)lpMan->m_min_value; + fv64.m_max_val = (uint64_t)lpMan->m_max_value; + fv64.m_step = (uint64_t)lpMan->m_step; + m_instructions.add_command(&fv64,sizeof(fv64)); } - - StreamDPOpFlowVar64 fv64; - fv64.m_op = op; - fv64.m_flow_offset = get_var_offset(lpMan->m_var_name); - fv64.m_min_val = (uint64_t)lpMan->m_min_value; - fv64.m_max_val = (uint64_t)lpMan->m_max_value; - m_instructions.add_command(&fv64,sizeof(fv64)); } } @@ -890,6 +974,12 @@ void StreamDPVmInstructions::Dump(FILE *fd){ StreamDPOpFlowVar16 *lpv16; StreamDPOpFlowVar32 *lpv32; StreamDPOpFlowVar64 *lpv64; + + StreamDPOpFlowVar8Step *lpv8s; + StreamDPOpFlowVar16Step *lpv16s; + StreamDPOpFlowVar32Step *lpv32s; + StreamDPOpFlowVar64Step *lpv64s; + StreamDPOpIpv4Fix *lpIpv4Fix; StreamDPOpPktWr8 *lpw8; StreamDPOpPktWr16 *lpw16; @@ -1016,6 +1106,47 @@ void StreamDPVmInstructions::Dump(FILE *fd){ p+=sizeof(StreamDPOpPktSizeChange); break; + case ditINC8_STEP : + lpv8s =(StreamDPOpFlowVar8Step *)p; + lpv8s->dump(fd,"INC8_STEP"); + p+=sizeof(StreamDPOpFlowVar8Step); + break; + case ditINC16_STEP : + lpv16s =(StreamDPOpFlowVar16Step *)p; + lpv16s->dump(fd,"INC16_STEP"); + p+=sizeof(StreamDPOpFlowVar16Step); + break; + case ditINC32_STEP : + lpv32s =(StreamDPOpFlowVar32Step *)p; + lpv32s->dump(fd,"INC32_STEP"); + p+=sizeof(StreamDPOpFlowVar32Step); + break; + case ditINC64_STEP : + lpv64s =(StreamDPOpFlowVar64Step *)p; + lpv64s->dump(fd,"INC64_STEP"); + p+=sizeof(StreamDPOpFlowVar64Step); + break; + + case ditDEC8_STEP : + lpv8s =(StreamDPOpFlowVar8Step *)p; + lpv8s->dump(fd,"DEC8_DEC"); + p+=sizeof(StreamDPOpFlowVar8Step); + break; + case ditDEC16_STEP : + lpv16s =(StreamDPOpFlowVar16Step *)p; + lpv16s->dump(fd,"DEC16_STEP"); + p+=sizeof(StreamDPOpFlowVar16Step); + break; + case ditDEC32_STEP : + lpv32s =(StreamDPOpFlowVar32Step *)p; + lpv32s->dump(fd,"DEC32_STEP"); + p+=sizeof(StreamDPOpFlowVar32Step); + break; + case ditDEC64_STEP : + lpv64s =(StreamDPOpFlowVar64Step *)p; + lpv64s->dump(fd,"DEC64_STEP"); + p+=sizeof(StreamDPOpFlowVar64Step); + break; default: assert(0); @@ -1024,6 +1155,23 @@ void StreamDPVmInstructions::Dump(FILE *fd){ } +void StreamDPOpFlowVar8Step::dump(FILE *fd,std::string opt){ + fprintf(fd," %10s op:%lu, of:%lu, (%lu-%lu-%lu) \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val,(ulong)m_step); +} + +void StreamDPOpFlowVar16Step::dump(FILE *fd,std::string opt){ + fprintf(fd," %10s op:%lu, of:%lu, (%lu-%lu-%lu) \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val,(ulong)m_step); +} + +void StreamDPOpFlowVar32Step::dump(FILE *fd,std::string opt){ + fprintf(fd," %10s op:%lu, of:%lu, (%lu-%lu-%lu) \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val,(ulong)m_step); +} + +void StreamDPOpFlowVar64Step::dump(FILE *fd,std::string opt){ + fprintf(fd," %10s op:%lu, of:%lu, (%lu-%lu-%lu) \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val,(ulong)m_step); +} + + void StreamDPOpFlowVar8::dump(FILE *fd,std::string opt){ fprintf(fd," %10s op:%lu, of:%lu, (%lu- %lu) \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val); } @@ -1074,3 +1222,60 @@ void StreamDPOpPktSizeChange::dump(FILE *fd,std::string opt){ fprintf(fd," %10s op:%lu, flow_offset: %lu \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset); } + + +void StreamDPVmInstructionsRunner::slow_commands(uint8_t op_code, + uint8_t * flow_var, /* flow var */ + uint8_t * pkt, + uint8_t * & p){ + ua_t ua; + + switch (op_code) { + + case StreamDPVmInstructions::ditINC8_STEP : + ua.lpv8s =(StreamDPOpFlowVar8Step *)p; + ua.lpv8s->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar8Step); + break; + + case StreamDPVmInstructions::ditINC16_STEP : + ua.lpv16s =(StreamDPOpFlowVar16Step *)p; + ua.lpv16s->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar16Step); + break; + case StreamDPVmInstructions::ditINC32_STEP : + ua.lpv32s =(StreamDPOpFlowVar32Step *)p; + ua.lpv32s->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar32Step); + break; + case StreamDPVmInstructions::ditINC64_STEP : + ua.lpv64s =(StreamDPOpFlowVar64Step *)p; + ua.lpv64s->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar64Step); + break; + + case StreamDPVmInstructions::ditDEC8_STEP : + ua.lpv8s =(StreamDPOpFlowVar8Step *)p; + ua.lpv8s->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar8Step); + break; + case StreamDPVmInstructions::ditDEC16_STEP : + ua.lpv16s =(StreamDPOpFlowVar16Step *)p; + ua.lpv16s->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar16Step); + break; + case StreamDPVmInstructions::ditDEC32_STEP : + ua.lpv32s =(StreamDPOpFlowVar32Step *)p; + ua.lpv32s->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar32Step); + break; + case StreamDPVmInstructions::ditDEC64_STEP : + ua.lpv64s =(StreamDPOpFlowVar64Step *)p; + ua.lpv64s->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar64Step); + break; + default: + assert(0); + } +} + diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index dabc502c..fd685b24 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -215,6 +215,128 @@ public: } __attribute__((packed)) ; + +struct StreamDPOpFlowVar8Step { + uint8_t m_op; + uint8_t m_flow_offset; + uint8_t m_min_val; + uint8_t m_max_val; + uint8_t m_step; +public: + void dump(FILE *fd,std::string opt); + + inline void run_inc(uint8_t * flow_var) { + uint8_t *p = (flow_var + m_flow_offset); + if (*p >= (m_max_val-m_step)) { + *p = m_min_val; + } else { + *p = *p + m_step; + } + } + + inline void run_dec(uint8_t * flow_var) { + uint8_t *p = (flow_var + m_flow_offset); + if (*p <= (m_min_val+m_step)) { + *p = m_max_val; + } else { + *p = *p - m_step; + } + } + +} __attribute__((packed)) ; + +struct StreamDPOpFlowVar16Step { + uint8_t m_op; + uint8_t m_flow_offset; + uint16_t m_min_val; + uint16_t m_max_val; + uint16_t m_step; + +public: + void dump(FILE *fd,std::string opt); + + inline void run_inc(uint8_t * flow_var) { + uint16_t *p = (uint16_t *)(flow_var + m_flow_offset); + if (*p >= (m_max_val-m_step)) { + *p = m_min_val; + } else { + *p = *p + m_step; + } + } + + inline void run_dec(uint8_t * flow_var) { + uint16_t *p = (uint16_t *)(flow_var + m_flow_offset); + if (*p <= (m_min_val+m_step)) { + *p = m_max_val; + } else { + *p = *p - m_step; + } + } + +} __attribute__((packed)) ; + +struct StreamDPOpFlowVar32Step { + uint8_t m_op; + uint8_t m_flow_offset; + uint32_t m_min_val; + uint32_t m_max_val; + uint32_t m_step; +public: + void dump(FILE *fd,std::string opt); + + inline void run_inc(uint8_t * flow_var) { + uint32_t *p = (uint32_t *)(flow_var + m_flow_offset); + if (*p >= (m_max_val-m_step)) { + *p = m_min_val; + } else { + *p = *p + m_step; + } + } + + inline void run_dec(uint8_t * flow_var) { + uint32_t *p = (uint32_t *)(flow_var + m_flow_offset); + if (*p <= (m_min_val+m_step)) { + *p = m_max_val; + } else { + *p = *p - m_step; + } + } + +} __attribute__((packed)) ; + +struct StreamDPOpFlowVar64Step { + uint8_t m_op; + uint8_t m_flow_offset; + uint64_t m_min_val; + uint64_t m_max_val; + uint64_t m_step; +public: + void dump(FILE *fd,std::string opt); + + inline void run_inc(uint8_t * flow_var) { + uint64_t *p = (uint64_t *)(flow_var + m_flow_offset); + if (*p >= (m_max_val-m_step) ) { + *p = m_min_val; + } else { + *p = *p + m_step; + } + } + + inline void run_dec(uint8_t * flow_var) { + uint64_t *p = (uint64_t *)(flow_var + m_flow_offset); + if (*p <= m_min_val+m_step) { + *p = m_max_val; + } else { + *p = *p - m_step; + } + } + + +} __attribute__((packed)) ; + +/////////////////////////////////////////////////////////////////////// + + struct StreamDPOpPktWrBase { enum { PKT_WR_IS_BIG = 1 @@ -440,6 +562,18 @@ public: itCLIENT_VAR_UNLIMIT , itPKT_SIZE_CHANGE , + /* inc/dec with step*/ + ditINC8_STEP , + ditINC16_STEP , + ditINC32_STEP , + ditINC64_STEP , + + ditDEC8_STEP , + ditDEC16_STEP , + ditDEC32_STEP , + ditDEC64_STEP , + + }; @@ -462,7 +596,14 @@ class StreamDPVmInstructionsRunner { public: StreamDPVmInstructionsRunner(){ m_new_pkt_size=0;; + } + + void slow_commands(uint8_t op_code, + uint8_t * flow_var, /* flow var */ + uint8_t * pkt, + uint8_t * & p); + inline void run(uint32_t * per_thread_random, uint32_t program_size, uint8_t * program, /* program */ @@ -477,19 +618,7 @@ private: }; -inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, - uint32_t program_size, - uint8_t * program, /* program */ - uint8_t * flow_var, /* flow var */ - uint8_t * pkt - ){ - - - uint8_t * p=program; - uint8_t * p_end=p+program_size; - - - union ua_ { +typedef union ua_ { StreamDPOpFlowVar8 *lpv8; StreamDPOpFlowVar16 *lpv16; StreamDPOpFlowVar32 *lpv32; @@ -503,7 +632,26 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, StreamDPOpClientsLimit *lpcl; StreamDPOpClientsUnLimit *lpclu; - } ua ; + + StreamDPOpFlowVar8Step *lpv8s; + StreamDPOpFlowVar16Step *lpv16s; + StreamDPOpFlowVar32Step *lpv32s; + StreamDPOpFlowVar64Step *lpv64s; +} ua_t ; + + + +inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, + uint32_t program_size, + uint8_t * program, /* program */ + uint8_t * flow_var, /* flow var */ + uint8_t * pkt + ){ + + uint8_t * p=program; + uint8_t * p_end=p+program_size; + + ua_t ua; while ( p < p_end) { uint8_t op_code=*p; @@ -620,9 +768,10 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, ua.lpw_pkt_size->run(flow_var,m_new_pkt_size); p+=sizeof(StreamDPOpPktSizeChange); break; - + default: - assert(0); + slow_commands(op_code,flow_var,pkt,p); + break; } }; }; @@ -736,6 +885,11 @@ public: return ( StreamVmInstruction::itFLOW_MAN); } + virtual bool is_valid_for_split() const { + return (m_step==1?true:false); + } + + virtual uint64_t get_splitable_range() const { return (m_max_value - m_min_value + 1); } @@ -777,13 +931,16 @@ public: flow_var_op_e op, uint64_t init_value, uint64_t min_value, - uint64_t max_value) : StreamVmInstructionVar(var_name) { + uint64_t max_value, + uint64_t step=1) : StreamVmInstructionVar(var_name) { m_op = op; m_size_bytes = size; m_init_value = init_value; m_min_value = min_value; m_max_value = max_value; + m_step = step; + } virtual void Dump(FILE *fd); @@ -796,7 +953,8 @@ public: m_op, m_init_value, m_min_value, - m_max_value); + m_max_value, + m_step); } private: @@ -817,6 +975,7 @@ public: uint64_t m_min_value; uint64_t m_max_value; + uint64_t m_step; }; diff --git a/src/stateless/cp/trex_vm_splitter.cpp b/src/stateless/cp/trex_vm_splitter.cpp index 9465718f..5e6d4fbd 100644 --- a/src/stateless/cp/trex_vm_splitter.cpp +++ b/src/stateless/cp/trex_vm_splitter.cpp @@ -101,6 +101,11 @@ TrexVmSplitter::split_by_flow_var(const StreamVmInstructionFlowMan *instr) { return false; } + /* split only step of 1 */ + if (!instr->is_valid_for_split() ){ + return false; + } + /* we need to split - duplicate VM now */ duplicate_vm(); |