CSL 的字符串(stack)

本文介绍了一种求解给定字符串条件下字典序最小的新字符串的算法。该算法使用单调栈实现,确保新字符串满足特定条件:包含原字符串所有不同字符且字典序最小。

链接:https://ac.nowcoder.com/acm/contest/551/D
来源:牛客网
 

CSL 以前不会字符串算法,经过一年的训练,他还是不会……于是他打算向你求助。
 

给定一个字符串,只含有可打印字符,通过删除若干字符得到新字符串,新字符串必须满足两个条件:

  • 原字符串中出现的字符,新字符串也必须包含。
  • 新字符串中所有的字符均不相同。
  • 新字符串的字典序是满足上面两个条件的最小的字符串。

 

输入描述:

 

仅一行,有一个只含有可打印字符的字符串 s。

 

|s|≤105|s|≤105

输出描述:

在一行输出字典序最小的新字符串。

示例1

输入

复制

bab

输出

复制

ab

示例2

输入

复制

baca

输出

复制

bac

备注:

ASCII字符集包含 94 个可打印字符(0x21 - 0x7E),不包含空格。

先放出代码:

#include<iostream>
using namespace std;
#include<bits/stdc++.h>
const int maxn=100005;
typedef long long ll;
int vis[maxn];
int used[maxn];

int main()
{
	string s;
	cin>>s;
	stack<char>v;
	
	for(int i=0;i<s.length();i++)
	{
		used[ s[i] ]++;
	}
	 
	vis[ s[0] ]=1;  
	used[ s[0] ]--;
	v.push(s[0]);
	
	for(int i=1;i<s.length();i++)
	{
		used[ s[i] ]--;
		
		if(vis[s[i]]==0)
		{
				while(!v.empty()&&v.top()>s[i]&&used[ v.top() ])
				{
					char c=v.top();
					vis[c]=0;
					v.pop();
				}
				
				v.push( s[i] );
				vis[s[i]]=1;
		}
	}
	
	string ans;
	while(!v.empty())
	{
		ans+=v.top();
		v.pop();
	}
	
	reverse(ans.begin(),ans.end());
	cout<<ans<<endl;
	
	return 0;
}


一开始不知道怎么来模拟这个字符串,需要将多个字符化为删除 成为一个,并且使最后的字典序最小,一开始并不知道怎么来模拟。最后看了大神的代码。思路是 先是将各种字符计数 ,然后用单调有序栈来存字符,字典序最小。1.如果当前栈顶的元素比要加进来的元素字典序小(假定这个栈顶字符出现数大于2,是要删除的字符),我们就不能把这个删除,那么后面的再出现这个字符,我们就得将这个删除掉;2.如果栈顶元素比要加进来的字符字典序大,我们就要将目前栈顶元素pop 掉,使字典序小一些。这样的话,我们在以后继续遇见这个字符,我们还需要 加进来(一种字符只能留一个,不能多,也不能少)。 上面的这两个情况操作我们需要一个标记数组来进行标记,看看是 第几种情况 1 还是 2,我们都需要进行标记,判断如果是第一种情况,我们后面再遇见这个字符,我们这个标记数组就可以 派上用场,就不会存进 stack 中相同的字符了。 

ERROR: device-tree-xilinx-v2020.2+gitAUTOINC+f725aaecff-r0 do_compile: Error executing a python function in exec_python_func() autogenerated: The stack trace of python calls that resulted in this exception/failure was: File: 'exec_python_func() autogenerated', lineno: 2, function: <module> 0001: *** 0002:devicetree_do_compile(d) 0003: File: '/home/ljj/petalinux/csl_zynqsys_1/components/yocto/layers/core/meta/classes/devicetree.bbclass', lineno: 131, function: devicetree_do_compile 0127: if not(os.path.isfile(dtspath)) or not(dts.endswith(".dts") or devicetree_source_is_overlay(dtspath)): 0128: continue # skip non-.dts files and non-overlay files 0129: except: 0130: continue # skip if can't determine if overlay *** 0131: devicetree_compile(dtspath, includes, d) 0132:} 0133: 0134:devicetree_do_install() { 0135: for DTB_FILE in `ls *.dtb *.dtbo`; do File: '/home/ljj/petalinux/csl_zynqsys_1/components/yocto/layers/core/meta/classes/devicetree.bbclass', lineno: 119, function: devicetree_compile 0115: dtcargs += ["-i", i] 0116: dtcargs += ["-o", "{0}.{1}".format(dtname, "dtbo" if isoverlay else "dtb")] 0117: dtcargs += ["-I", "dts", "-O", "dtb", "{0}.pp".format(dts)] 0118: bb.note("Running {0}".format(" ".join(dtcargs))) *** 0119: subprocess.run(dtcargs, check = True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 0120: 0121:python devicetree_do_compile() { 0122: includes = expand_includes("DT_INCLUDE", d) 0123: listpath = d.getVar("DT_FILES_PATH") File: '/opt/pkg/petalinux/2020.2/components/yocto/buildtools/sysroots/x86_64-petalinux-linux/usr/lib/python3.7/subprocess.py', lineno: 512, function: run 0508: raise 0509: retcode = process.poll() 0510: if check and retcode: 0511: raise CalledProcessError(retcode, process.args, *** 0512: output=stdout, stderr=stderr) 0513: return CompletedProcess(process.args, retcode, stdout, stderr) 0514: 0515: 0516:def list2cmdline(seq): Exception: subprocess.CalledProcessError: Command '['dtc', '-@', '-p', '0x1000', '-i', '/home/ljj/petalinux/csl_zynqsys_1/build/tmp/work-shared/zynq-generic/kernel-source/arch/arm/boot/dts', '-i', '/home/ljj/petalinux/csl_zynqsys_1/build/tmp/work-shared/zynq-generic/kernel-source/scripts/dtc/include-prefixes', '-i', '/home/ljj/petalinux/csl_zynqsys_1/project-spec/configs/../../components/plnx_workspace/device-tree/device-tree', '-i', '/home/ljj/petalinux/csl_zynqsys_1/build/tmp/work/zynq_generic-xilinx-linux-gnueabi/device-tree/xilinx-v2020.2+gitAUTOINC+f725aaecff-r0', '-o', 'system-top.dtb', '-I', 'dts', '-O', 'dtb', 'system-top.dts.pp']' returned non-zero exit status 1. Subprocess output: Error: /home/ljj/petalinux/csl_zynqsys_1/build/tmp/work/zynq_generic-xilinx-linux-gnueabi/device-tree/xilinx-v2020.2+gitAUTOINC+f725aaecff-r0/system-user.dtsi:7.2-8 syntax error FATAL ERROR: Unable to parse input tree ERROR: Logfile of failure stored in: /home/ljj/petalinux/csl_zynqsys_1/build/tmp/work/zynq_generic-xilinx-linux-gnueabi/device-tree/xilinx-v2020.2+gitAUTOINC+f725aaecff-r0/temp/log.do_compile.76229 ERROR: Task (/home/ljj/petalinux/csl_zynqsys_1/components/yocto/layers/meta-xilinx/meta-xilinx-bsp/recipes-bsp/device-tree/device-tree.bb:do_compile) failed with exit code '1'
03-22
/* Copyright(c) 2009-2025 Chengdu TP-LINK Technologies Co.Ltd. * * file srvcQos.c * brief * details * * author zhanghaoxuan * version * date 14Aug25 * * history \arg */ /**************************************************************************************************/ /* INCLUDE_FILES */ /**************************************************************************************************/ /* libc header */ #include <stdio.h> /* syscall header */ /* common header */ #include "fepTypes.h" #include "fepDefs.h" /* platform header */ #include "midware/dal.h" /* public application header */ #include "common/applError.h" #include "common/dmpComDef.h" /*private header*/ #include "srvcQos.h" #include "adQos.h" #include "qos/dalQosPub.h" #include "qos/qosPub.h" #include "qos/logQos.h" #include "qos/errQos.h" #include "data/dataQos.h" #include "data/stateQos.h" #include "l2/l2Pub.h" #include "l2/port/cfgPortPub.h" #include "l2/port/portPub.h" #include "l2/port/dalPortPub.h" #include "l2/port/statPortPub.h" #include "l2/lag/statLagPub.h" #include "l2/lag/lagPub.h" #include "tpDbg/tpdebug.h" #include "syslog/syslog.h" #include "libApp/libQos/libQos.h" #include "libDcm/libStack/libStack.h" /**************************************************************************************************/ /* DEFINES */ /**************************************************************************************************/ #define QOS_MAX_PORT_NUM 54 #define QOS_KEY_MAX_LEN 64 #define QOS_IFG_DELAY (10.8) #define QOS_RATE_ADJUST_PAR 1514 #define QOS_RATE_KBPS_THOUSAND 1000 #define QOS_RATE_PERCENT_HUNDRED 100 #define QOS_STORM_EXCEED_LOG_CYCLE 60 // secs #define OMADA_KEY_OSW_STORM "OSW_DET_STORM" #define OMADA_KEY_OSW_PB "OSW_PB" #define QOS_MIB_UPDATE_TIMER_NAME "qos_mib_update_tm" #define AD_QOS_RATE_ADJUST_BY_PACKET_LENGTH(factor, packet_length) \ { \ if(packet_length >= 64 && packet_length < 128) \ { \ factor = 1.04 + (packet_length-64)*0.0022; \ } \ else if(packet_length >= 128 && packet_length < 192) \ { \ factor = 1.18 + (packet_length-128)*0.0009; \ } \ else if(packet_length >= 192 && packet_length < 256) \ { \ factor = 1.24 + (packet_length-192)*0.0004; \ } \ else if(packet_length >= 256 && packet_length < 320) \ { \ factor = 1.27 + (packet_length-256)*0.0003; \ } \ else if(packet_length >= 320 && packet_length < 384) \ { \ factor = 1.29 + (packet_length-320)*0.0002; \ } \ else if(packet_length >= 384 && packet_length < 1536) \ { \ factor = 1.30 + (packet_length-384)*0.00004; \ } \ } #define PORT_UP2STR(up, str)\ if(UP_IS_VALID(up) && (NULL != (str)))\ {\ *(str)='\0';\ usUp2Str((up), (str), UP_STR_BRF_PRFX);\ } typedef struct { int updateFlag; } QOS_MIB_UPDATE_MSG; /**************************************************************************************************/ /* TYPES */ /**************************************************************************************************/ extern int preQueueWeight[QOS_QUEUE_MAX_NUM]; /**************************************************************************************************/ /* EXTERN_PROTOTYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* LOCAL_PROTOTYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* VARIABLES */ /**************************************************************************************************/ static TIMER_ID qosMibUpdateTimer ; static pal_msgq_t qosSrvcMsgQ = PAL_MQ_ERROR; pal_thread_t qosTimerTaskId = PAL_THREAD_ERROR; //static int qosTrapCounter = 0; //static QOS_PORT_RATE_DIFF_STRUCT rateDiff[UP_UNIT_PORT_MAX+1]; static int qosTrapCounter = 0; static BOOL l_ingressLogEnable = FALSE; static BOOL l_egressLogEnable = FALSE; static BOOL l_bcLogEnable = FALSE; static BOOL l_mcLogEnable = FALSE; /**************************************************************************************************/ /* LOCAL_FUNCTIONS */ /**************************************************************************************************/ /* helper routine: transform the ratio rate to kbps rate*/ static void _rateValueTransform(user_port uPort, UINT32 *rateValue) { QOS_PORT_STATUS portStatus = {}; user_port_list lagMemberList = {}; user_port up = {}; int lagId = 0; int index = 0; int portRate = 0; int tmpRate = 0; int speedValue[UP_ABILITY_SPEED_END] = PORT_SPEED_VALUE; APPL_ENSURE_RET_VOID(UP_IS_VALID(uPort)); APPL_ENSURE_RET_VOID(NULL != rateValue); uplist_init(&lagMemberList); APPL_IF_ERR_DONE_VOID(adQosGetPortLinkStatus(uPort, &portStatus)); if (DISABLE == portStatus.status) { if (UP_IS_LAG(uPort)) { UP_TO_LAG(uPort, lagId); dataQosLagMemberListGet(lagId, &lagMemberList); UP_ITER_LIST_SWP(&lagMemberList, index, up) { tmpRate = QOS_PORT_MAX_RATE_KBPS(up) / QOS_RATE_KBPS_THOUSAND; if (0 == portRate || tmpRate < portRate) { portRate = tmpRate; } } } else { portRate = QOS_PORT_MAX_RATE_KBPS(uPort) / QOS_RATE_KBPS_THOUSAND; } } else { portRate = speedValue[portStatus.speedMode]; } *rateValue = (*rateValue) * portRate * (QOS_RATE_KBPS_THOUSAND / QOS_RATE_PERCENT_HUNDRED); //本应为 (rateValue/100) * (portRate*1000),为防止UINT32溢出,需要交换顺序 rateValueAdjust(rateValue); done: uplist_free(&lagMemberList); return; } static void _qosMsgRecover(QOS_AD_MSG_T qosMsg) { user_port physicalPort = {}; user_port logicPort = {}; QOS_PORT_STATUS portStatus = {}; UINT8 linkState = 0; //NTFY_QOS qosNtfy = {}; TIMER_ID recoverTimer = {}; TIMER_ID_INIT(recoverTimer); memcpy(&physicalPort, &qosMsg.qosRcvr.physicalPort, sizeof(user_port)); //物理端口 memcpy(&logicPort, &qosMsg.qosRcvr.logicPort, sizeof(user_port)); //lag端口 if (UP_CMP(physicalPort, logicPort)) /* 获取端口配置的状态 */ dataQosRcvrTimerIdLagSet(physicalPort, recoverTimer); else /*dealing with phy port*/ dataQosRcvrTimerIdPhySet(physicalPort, recoverTimer); /*check port config, if port set to disable ,do not enable this phy port*/ if (UP_CMP(physicalPort, logicPort)) { qosStatePortStatusGet(logicPort, &portStatus); } else { qosStatePortStatusGet(physicalPort, &portStatus); } stateQosPortBlockStatusSet(physicalPort, DISABLE); /* QOS_TODO:堆叠时,向master发送notify更新recovery信息 */ #if 0 if (!DEV_ROLE_LOCAL_IS_MASTER()){ memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.block = DISABLE; unit_list ul={}; UNIT_LIST_ADD(ul, UNIT_MASTER); notify_call_remote(ul, NOTIFY_QOS_STORM_CTRL_BLOCK, &qosNtfy, sizeof(qosNtfy)); } #endif QOS_DEBUG("linkStatus:%d",portStatus.status); if (portStatus.status == ENABLE) { adQosGetPortState(physicalPort, &linkState); if(linkState != ENABLE) { adQosSetPortState(physicalPort, ENABLE); DN("pull up"); } } else { adQosSetPortState(physicalPort, DISABLE); DN("shut down"); } } static void _qosRateRecoverTimerNotify(void *data) { // QOS_AD_MSG_T qosMsg = {}; // user_port *upArr = data; // // APPL_ENSURE_RET_VOID(data != NULL); // // qosMsg.qosRcvr.physicalPort = upArr[0]; // qosMsg.qosRcvr.logicPort = upArr[1]; // qosMsg.type = QOS_MSG_RCVR; DW("_qosRateRecoverTimerNotify executed"); QOS_AD_MSG_T qosMsg = {}; user_port *upArr = (user_port*) data; APPL_ENSURE_RET_VOID(data != NULL); qosMsg.qosRcvr.physicalPort = upArr[0]; qosMsg.qosRcvr.logicPort = upArr[1]; qosMsg.type = QOS_MSG_RCVR; _qosMsgRecover(qosMsg); free(upArr); } static STATUS _qosPortMibUpdateCb() { // DW("_qosPortMibUpdateCb"); int ret = ERR_NO_ERROR; int tmpPort = 0; int tmpKeyNum = 0; char *key = NULL; char tmpKey[QOS_KEY_MAX_LEN] = {0}; void *handler = NULL; user_port logicPort = {}; user_port physicalPort = {}; QOS_PORT_RATE_DIFF_STRUCT rateDiff = {}; UINT64 ingressVal = 0; UINT64 egressVal = 0; UINT64 bcVal = 0; UINT64 mcVal = 0; UINT32 rate = 0; TIMER_ID recoverTimer; TIMER_ID_INIT(recoverTimer); struct timespec timer = {}; char strUp[STR_STRUP_SIZE] = {}; char timerName[STR_TIMER_NAME_SIZE] = {}; APPQOS_ADCFG_OPT optCfg = {}; // QOS_PORT_STATUS portStatus = {}; QOS_PORT_STATUS tmpPortStatus = {}; UINT32 lagId = 0; UINT8 shutdownFlag = 0; NTFY_QOS qosNtfy = {}; MAC_ADDRESS sysMac = {}; char macStr[STR_MAC_SIZE] = {}; char portStr[STR_STRUP_SIZE] = {}; memset(macStr, 0, 20); libStkSysDevMacGet(UNIT_CURRENT, sysMac); ether2str(macStr, sysMac, CSL_UPCASE, STR_TRANS_CLI); qosTrapCounter++; if (qosTrapCounter >= QOS_STORM_EXCEED_LOG_CYCLE) { qosTrapCounter = 0; l_ingressLogEnable = TRUE; l_egressLogEnable = TRUE; l_bcLogEnable = TRUE; l_mcLogEnable = TRUE; } /* 置位flag */ BOOL f_ingressLogEnable = FALSE; BOOL f_egressLogEnable = FALSE; BOOL f_bcLogEnable = FALSE; BOOL f_mcLogEnable = FALSE; dal_ado_t *adoi; adoi = dalAsdoiCreate(DMP_DEV_NAME_SWITCHMAC, DAL_MOD_PORT, DAL_CFG_TYPE_ENTRY); APPL_ENSURE_DONE(ret, adoi, ERR_NO_MEMORY); dalAdoiEntryTableAppend(adoi, DAL_PORT_K_MIB); dalAdoiEntryOperAppend(adoi, DAL_PORT_K_MIB, DAL_OPER_GET); for (tmpPort = 0; tmpPort < QOS_MAX_PORT_NUM; tmpPort++) { int len = snprintf(tmpKey, sizeof(tmpKey), DAL_PORT_K_MIB_IDX, (tmpPort+1)); if (len < 0 || len > sizeof(tmpKey)) { ret = ERR_BAD_PARAM; goto done; } DAL_PORT_KEY_MIB_PARSE_TO_UP(tmpKey, physicalPort); APPL_IF_ERR_DONE_RET(ret, adQosGetPortLinkStatus(physicalPort, &tmpPortStatus), ERR_BAD_PARAM); /* 只添加linkup端口的key */ if (DISABLE != tmpPortStatus.status) { dalAdoiAddEntryKey(adoi, DAL_PORT_K_MIB, tmpKey, UP_INDEX(physicalPort)); tmpKeyNum++; } } if ( !tmpKeyNum ) { goto done; } if (PFM_ERR_C_OK != dalGet(adoi)) { ret = ERR_NOT_FOUND; goto done; } if (NULL != (handler = DAL_ADOI_ENTRY(adoi, DAL_PORT_K_MIB))) { DAL_ADOI_ENTRY_LOOP(handler) { if(NULL == (key = DAL_ADOI_ENTRY_KEY(handler)) || !DAL_ADOI_ENTRY_KEY_MATCH(handler, DAL_PORT_K_MIB_ALL)) { continue; } DAL_PORT_KEY_MIB_PARSE_TO_UP(key, physicalPort); /* QOS_TODO:所有端口启用功能并且link-up时存在性能问题 get交换机的时间戳,通过绝对时间来处理 */ // adQosGetPortLinkStatus(physicalPort, &portStatus); // if (portStatus.status == DISABLE) // { // continue; // } /* KEY inner field&value loop */ if (DAL_ADOI_ENTRY_KEY_EMPTY(handler)) { QOS_DEBUG_COMMON("Invalid operation: deleting Fixed entries!"); } else { DAL_ADOI_ENTRY_FIELD_LOOP(handler, key) { if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_RXBYTEDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.rxbyteDiff); } else if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_TXBYTEDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.txbyteDiff); } else if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_BCNUMDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.bcNumDiff); } else if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_MCNUMDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.mcNumDiff); } } } qosGetLagIdOfPort(physicalPort, &lagId); if (lagId) { UP_FROM_LAG(logicPort, lagId); } else { memcpy(&logicPort, &physicalPort, sizeof(user_port)); } ret = dataQosGetPortConfig(logicPort, &optCfg); if (ret != ERR_NO_ERROR) { continue; } if(optCfg.stormLogging) { QOS_DEBUG("upIdx:%d, rxbyteDiff:%d, txbyteDiff:%d, bcNumDiff:%d, mcNumDiff:%d", UP_INDEX(logicPort), rateDiff.rxbyteDiff, rateDiff.txbyteDiff, rateDiff.bcNumDiff, rateDiff.mcNumDiff); } /* 入口带宽阈值 Byte/s */ ingressVal = (UINT64)(optCfg.ingressRateValue) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; /*1(sec)*1000*/ /* 出口带宽阈值 Byte/s */ egressVal = (UINT64)(optCfg.egressRateValue) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; if (QOS_RATE_MODE_PPS != optCfg.rateMode) //PPS(包速率模式)、KBPS(kbit模式)、RATIO(端口带宽模式) { if (QOS_RATE_MODE_KBPS == optCfg.rateMode) { /* 广播流量阈值 */ bcVal = (UINT64)(optCfg.bcRate) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; /* 组播流量阈值 */ mcVal = (UINT64)(optCfg.mcRate) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; } else if (QOS_RATE_MODE_RATIO == optCfg.rateMode) { rate = optCfg.bcRate; _rateValueTransform(logicPort, &rate); bcVal = (UINT64)(rate)*QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; rate = optCfg.mcRate; _rateValueTransform(logicPort, &rate); mcVal = (UINT64)(rate)*QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; } } else { bcVal = (UINT64)optCfg.bcRate; /*1 sec*/ mcVal = (UINT64)optCfg.mcRate; } /* 入口带宽超限 */ if (optCfg.ingressRateValue && rateDiff.rxbyteDiff > ingressVal) { if (l_ingressLogEnable) { //QOS_TODO: snmp trap、controller log f_ingressLogEnable = TRUE; QDW("ingress exceed:%d", UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.ingressRate = optCfg.ingressRateValue; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_BANDWIDTH_INGRESS, &qosNtfy); //触发告警 PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_PORT_INGRESS_REACH, portStr); //触发日志 } } else { /*bc trap & notify*/ if (optCfg.bcRate && QOS_RATE_MODE_PPS != optCfg.rateMode && (rateDiff.rxbyteDiff > bcVal)&&(QOS_RATE_ADJUST_PAR * rateDiff.bcNumDiff >= bcVal)) { double factor = 1; int packet_length = rateDiff.rxbyteDiff/rateDiff.bcNumDiff; AD_QOS_RATE_ADJUST_BY_PACKET_LENGTH(factor, packet_length); QOS_DEBUG_COMMON("factor %4f, rateValNew.rxbyteDiff %d",factor,rateDiff.rxbyteDiff); if(rateDiff.rxbyteDiff >= factor * bcVal) { shutdownFlag = TRUE; if (l_bcLogEnable) { //QOS_TODO: snmp trap、controller log f_bcLogEnable = TRUE; QDW("bc exceed:%d",UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.bcastRate = optCfg.bcRate; qosNtfy.bcastMode = optCfg.rateMode; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_STORM_CTRL_BCAST, &qosNtfy); stateQosPortStormOccursSet(physicalPort, QOS_RATE_STORM_MODE_BC, TRUE); if (optCfg.stormLogging) { PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_BCSTORM_CONTROL_REACH, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_DETECTED, OMADA_KEY_OSW_STORM, OMD_ALERT_REPORT, portStr, (ULONG)"Broadcast", (ULONG)macStr, (ULONG)portStr, 0, 0, 0); } } } } if (optCfg.bcRate && QOS_RATE_MODE_PPS == optCfg.rateMode && rateDiff.bcNumDiff >= bcVal) { shutdownFlag = TRUE; if (l_bcLogEnable) { //QOS_TODO: snmp trap、controller log f_bcLogEnable = TRUE; QDW("bc exceed:%d",UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.bcastRate = optCfg.bcRate; qosNtfy.bcastMode = optCfg.rateMode; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_STORM_CTRL_BCAST, &qosNtfy); stateQosPortStormOccursSet(physicalPort, QOS_RATE_STORM_MODE_BC, TRUE); if (optCfg.stormLogging) { PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_BCSTORM_CONTROL_REACH, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_DETECTED, OMADA_KEY_OSW_STORM, OMD_ALERT_REPORT, portStr, (ULONG)"Broadcast", (ULONG)macStr, (ULONG)portStr, 0, 0, 0); } } } /*mc trap & notify*/ if (optCfg.mcRate && QOS_RATE_MODE_PPS != optCfg.rateMode && (rateDiff.rxbyteDiff > mcVal) && (QOS_RATE_ADJUST_PAR * rateDiff.mcNumDiff >= mcVal)) { double factor = 1; int packet_length = rateDiff.rxbyteDiff/rateDiff.mcNumDiff; AD_QOS_RATE_ADJUST_BY_PACKET_LENGTH(factor, packet_length); QOS_DEBUG_COMMON("factor %4f, rateValNew.rxbyteDiff %d",factor,rateDiff.rxbyteDiff); if(rateDiff.rxbyteDiff >= factor * mcVal) { shutdownFlag = TRUE; if (l_mcLogEnable) { //QOS_TODO: snmp trap、controller log f_mcLogEnable = TRUE; QDW("mc exceed:%d",UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.mcastRate = optCfg.mcRate; qosNtfy.mcastMode = optCfg.rateMode; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_STORM_CTRL_MCAST, &qosNtfy); stateQosPortStormOccursSet(physicalPort, QOS_RATE_STORM_MODE_MC, TRUE); if (optCfg.stormLogging) { PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_MCSTORM_CONTROL_REACH, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_DETECTED, OMADA_KEY_OSW_STORM, OMD_ALERT_REPORT, portStr, (ULONG)"Multicast", (ULONG)macStr, (ULONG)portStr, 0, 0, 0); } } } } } if (optCfg.egressRateValue && rateDiff.txbyteDiff > egressVal) { if (l_egressLogEnable) { //QOS_TODO: snmp trap、syslog、controller log f_egressLogEnable = TRUE; QDW("egress exceed:%d",UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.egressRate = optCfg.egressRateValue; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_BANDWIDTH_EGRESS, &qosNtfy); PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_PORT_EGRESS_REACH, portStr); } } /*if port belong to a LAG, the optCfg is LAG rate Config*/ if (optCfg.stormOper == QOS_STORM_EXCEED_SHUTDOWN && shutdownFlag /* && portStatus */) { QOS_DEBUG("QOS_STORM_EXCEED_SHUTDOWN"); shutdownFlag = FALSE; adQosSetPortState(physicalPort, DISABLE); stateQosPortBlockStatusSet(physicalPort, ENABLE); PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_PORT_STORM_CONTROL_SHUTDOWN, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_SHUTDOWN, OMADA_KEY_OSW_PB, OMD_ALERT_REPORT, portStr, (ULONG)macStr, (ULONG)portStr, 0, 0, 0, 0); //QOS_TODO:堆叠时,向master发送notify更新block信息 if (optCfg.recoverTime) { if (UP_IS_LAG(logicPort)) dataQosRcvrTimerIdLagGet(physicalPort,&recoverTimer); else dataQosRcvrTimerIdPhyGet(logicPort,&recoverTimer); /*add timer, LAG member set their own logic timer ID: check the timer value, if not 0, LAG has a timer*/ /* controller独有bug,定时器存在,需删除*/ // if (TIMER_ID_IS_VALID(recoverTimer)) // { // DEL_TIMER(recoverTimer); // } DEL_TIMER(recoverTimer); timer.tv_sec = optCfg.recoverTime; timer.tv_nsec = 0; // user_port upArr[2] = {}; // upArr[0] = physicalPort; // upArr[1] = logicPort; user_port *upArr = (user_port *)malloc(2 * sizeof(user_port)); if (!upArr) { QOS_DEBUG("Failed to allocate memory for timer data"); ret = ERR_BAD_PARAM; goto done; } upArr[0] = physicalPort; upArr[1] = logicPort; usUp2Str(upArr[0],strUp,UP_STR_BRF_PRFX); snprintf(timerName, sizeof(timerName), "qosRecoverTime:%s",strUp); // if (UP_IS_LAG(logicPort)) // { // recoverTimer = add_timer(timerName, &timer, _qosRateRecoverTimerNotify, upArr, sizeof(upArr), EXECUTE_SINGLE); // if (TIMER_ID_IS_VALID(recoverTimer)) // dataQosRcvrTimerIdLagSet(physicalPort, recoverTimer); // } // else // { // recoverTimer = add_timer(timerName, &timer, _qosRateRecoverTimerNotify, upArr, sizeof(upArr), EXECUTE_SINGLE); // if (TIMER_ID_IS_VALID(recoverTimer)) // dataQosRcvrTimerIdPhySet(physicalPort, recoverTimer); // } recoverTimer = add_timer(timerName, &timer, _qosRateRecoverTimerNotify, upArr, sizeof(user_port) * 2, EXECUTE_SINGLE); if (TIMER_ID_IS_VALID(recoverTimer)) { DW("recoverTimer add"); if (UP_IS_LAG(logicPort)) { dataQosRcvrTimerIdLagSet(physicalPort, recoverTimer); } else { dataQosRcvrTimerIdPhySet(physicalPort, recoverTimer); } } else { free(upArr); // 定时器创建失败时释放内存 } } } if(f_ingressLogEnable) { l_ingressLogEnable = FALSE; f_ingressLogEnable = FALSE; } if(f_egressLogEnable) { l_egressLogEnable = FALSE; f_egressLogEnable = FALSE; } if(f_bcLogEnable) { l_bcLogEnable = FALSE; f_bcLogEnable = FALSE; } if(f_mcLogEnable) { l_mcLogEnable = FALSE; f_mcLogEnable = FALSE; } }//end loop handler } done: if(adoi) { dalAdoiDestroy(adoi); } return ret; } static void _managerTimerHandleTask() { int status = 0; int pri = 0; QOS_MIB_UPDATE_MSG msg = {}; while (1) { //一直阻塞,usec置为PAL_MQ_WAIT_FOREVER status = pal_msgQ_receive(qosSrvcMsgQ, (char *)(&msg), sizeof(QOS_MIB_UPDATE_MSG), PAL_MQ_WAIT_FOREVER, (UINT *)&pri); if (PAL_MQ_ERROR == status) { continue; } /* 接收到消息则执行 */ _qosPortMibUpdateCb(); } } static void _managerTimerHandle(void *param) { QOS_MIB_UPDATE_MSG msg = {}; msg.updateFlag = true; pal_msgQ_send(qosSrvcMsgQ, (char *)&msg, sizeof(QOS_MIB_UPDATE_MSG), 0, PAL_MQ_WAIT_NOWAIT); } static int _qosMibUpdatePthreadInit() { qosTimerTaskId = pal_thread_create("qosTimerTaskId", 10 * 1024, 0, _managerTimerHandleTask, NULL); if (PAL_THREAD_ERROR == qosTimerTaskId) { DBG("create task fail"); } D("_qosMibUpdatePthreadInit ok"); return ERR_NO_ERROR; } STATUS _qosMibUpdateStartTimerInit() { TIMER_ID_INIT(qosMibUpdateTimer); struct timespec updateTimer = {}; updateTimer.tv_sec = 1; updateTimer.tv_nsec = 0; qosMibUpdateTimer = add_timer("qos_mib_update_timer", &updateTimer, _managerTimerHandle, NULL, 0, EXECUTE_FOREVER); APPL_ENSURE_RET_VAL(TIMER_ID_IS_VALID(qosMibUpdateTimer), ERR_INIT); D("_qosMibUpdateStartTimerInit ok"); return ERR_NO_ERROR; } static int _qosMibUpdateQueueInit() { qosSrvcMsgQ = pal_msgQ_create("/qosMibUpdateTimerQueue", 10, sizeof(QOS_MIB_UPDATE_MSG), PAL_MQ_READ_WRITE); if (PAL_MQ_ERROR == qosSrvcMsgQ) { pal_msgQ_destroy("/qosMibUpdateTimerQueue"); } D("_qosMibUpdateQueueInit ok"); return ERR_NO_ERROR; } /**************************************************************************************************/ /* PUBLIC_FUNCTIONS */ /**************************************************************************************************/ STATUS srvcQosInit() { /* 初始化任务线程 */ APPL_IF_ERR_RET(_qosMibUpdatePthreadInit()); /* 初始化消息队列 */ APPL_IF_ERR_RET(_qosMibUpdateQueueInit()); /* 初始化定时器 */ _qosMibUpdateStartTimerInit(); // PFM_IF_FAIL_RET_VAL(dalStatChgSub(DMP_DEV_NAME_SWITCHMAC, DAL_SWITCHMAC_STAT_MIBUPDATE, _qosPortMibUpdateCb), ERR_QOS_INIT); return ERR_NO_ERROR; } 在此代码中,第二次风暴时,创建了计时器,但_qosRateRecoverTimerNotify函数没有执行,试分析原因
最新发布
11-27
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值