2008-11-06
【案例描述】:由于C语言中位与比求模效率高,因而系统设计时,对于模128的地方都改为与127,系统定义的宏为#define MOD128 127和#define W_MOD 127(定义的宏的名字易引起误解),但实际程序中还是采取求模,从而引起发送窗口欲重发的和实际重发的不一致,最终导致链路复位此类严重问题,曾在定位此问题时花了不少时间。
【处理过程】:处理过程如下:
#define MOD128 127 //队列长128,当队头到128时,上其返回。
#define W_MOD 127 //发送窗口队列,意义同上。
在函数L2_TO_L1()中,有如下语句:
linkstate_ptr->SendWin.head = (head + 1) % W_MOD ;
这里当head=126时,SendWin.head = 0,这将造成发送窗口指针和队列窗口指针错位,造成链路复位;
另外,在重发函数void INVOKE_RETRANSMISSION(_US logic_link,_US n_r)中,有如下语句:
retran_num = (LinkState[logic_link].Vs + MOD128 - (_UC)n_r) % MOD128 ;
w_head = (LinkState[logic_link].SendWin.head + W_MOD - retran_num) % W_MOD ;
第一个语句求欲重发的消息包个数,第二个语句求重发的起始位置,当Vs小于n_r时,将造成实际重发数小于欲重发数,同时造成实际起始重发位置和欲重发起始位置错开,从而引起链路复位。上面三个语句应该做如下改动:
linkstate_ptr->SendWin.head = (head + 1) & W_MOD ;
retran_num = (LinkState[logic_link].Vs + MOD128 + 1 - (_UC)n_r) & MOD128 ;
w_head = (LinkState[logic_link].SendWin.head + W_MOD + 1 - retran_num) & W_MOD ;
评论1
楼主 2008/11/6 12:54:03
【结 论】:由于链路通信对系统效率要求很高,算法采用效率最高的,但位与(&)和求模(%)这小小的区别,造成的竟是链路复位这种严重的错误。
【思考与启示】:对这类问题,大家在阅读代码或代码审查时一定要注意,仔细一点往往能发现问题,但在测试中来定位这种问题,花费的时间往往更长。