Commit 5eaba882 authored by Jean-Claude BAU's avatar Jean-Claude BAU Committed by Adam Wujek

Timeout management correction.

- The timeout expressed in ms is stored in an integer value. A Log
interval may have a value in the range -128,127. The timeout cannot
covers all this range. A protection as been added to avoid wrong timeout
calculation which might generate a crash of PPSI.
- A new function is also added pp_timeout_log_to_ms() to verify the log
Interval and calculate the timeout.
- Optimize the execution of pp_timeout_set()
parent 6fc858fb
......@@ -577,6 +577,7 @@ extern TimeInterval pp_time_to_interval(struct pp_time *ts);
extern TimeInterval picos_to_interval(int64_t picos);
extern void pp_time_add_interval(struct pp_time *t1, TimeInterval t2);
extern void pp_time_sub_interval(struct pp_time *t1, TimeInterval t2);
extern int pp_timeout_log_to_ms ( Integer8 logValue);
/* Function for time conversion */
extern int64_t pp_time_to_picos(struct pp_time *ts);
......
......@@ -191,6 +191,7 @@ static void l1e_send_sync_msg(struct pp_instance *ppi, Boolean immediatSend) {
int len;
int fmeas, lmeas;
int diff;
int tmo_ms;
fmeas=measure_first_time(ppi);
pp_diag(ppi, ext, 1, "Sending L1SYNC_TLV signaling msg\n");
......@@ -203,8 +204,10 @@ static void l1e_send_sync_msg(struct pp_instance *ppi, Boolean immediatSend) {
* the execution time of this function. With small time-out like 64ms,
* the error become not negligible.
*/
__pp_timeout_set(ppi, L1E_TIMEOUT_TX_SYNC,
(4 << (L1E_DSPOR_BS(ppi)->logL1SyncInterval + 8))-diff); /* loop ever since */
tmo_ms=pp_timeout_log_to_ms(L1E_DSPOR_BS(ppi)->logL1SyncInterval);
if ( tmo_ms >= diff ) /* to be sure to have a positive value */
tmo_ms-=diff;
__pp_timeout_set(ppi, L1E_TIMEOUT_TX_SYNC,tmo_ms); /* loop ever since */
}
}
......
......@@ -32,6 +32,27 @@ static struct timeout_config to_configs[__PP_TO_ARRAY_SIZE] = {
[PP_TO_EXT_1]={"EXT_1", RAND_NONE,}
};
#define TIMEOUT_MAX_LOG_VALUE 21 /* 2^21 * 1000 =2097152000ms is the maximum value that can be stored in an integer */
#define TIMEOUT_MIN_LOG_VALUE -9 /* 2^-9 = 1ms is the minimum value that can be stored in an integer */
int pp_timeout_log_to_ms ( Integer8 logValue) {
/* logValue can be in range -128 , +127
* However we restrict this range to TIMEOUT_MIN_LOG_VALUE, TIMEOUT_MAX_LOG_VALUE
* in order to optimize the calculation
*/
if ( logValue >= 0 ) {
if ( logValue > TIMEOUT_MAX_LOG_VALUE )
logValue=TIMEOUT_MAX_LOG_VALUE;
return (1<< logValue)*1000;
}
else {
if (logValue<TIMEOUT_MIN_LOG_VALUE)
logValue=TIMEOUT_MIN_LOG_VALUE;
return 1000>>-logValue;
}
}
/* Init fills the timeout values */
void pp_timeout_init(struct pp_instance *ppi)
{
......@@ -41,17 +62,15 @@ void pp_timeout_init(struct pp_instance *ppi)
port->logMinPdelayReqInterval : port->logMinDelayReqInterval;
to_configs[PP_TO_REQUEST].which_rand = p2p ? RAND_NONE : RAND_0_200;
to_configs[PP_TO_REQUEST].value= p2p ?
1000*(1<<logDelayRequest) :
logDelayRequest;
to_configs[PP_TO_REQUEST].value= pp_timeout_log_to_ms(logDelayRequest);
/* fault timeout is 4 avg request intervals, not randomized */
to_configs[PP_TO_FAULT].value =
1 << (logDelayRequest + 12); /* 0 -> 4096ms */
to_configs[PP_TO_SYNC_SEND].value = port->logSyncInterval;
to_configs[PP_TO_BMC].value = 1000 * (1 << port->logAnnounceInterval);
pp_timeout_log_to_ms(logDelayRequest + 12); /* 0 -> 4096ms */
to_configs[PP_TO_SYNC_SEND].value = pp_timeout_log_to_ms(port->logSyncInterval);
to_configs[PP_TO_BMC].value = pp_timeout_log_to_ms(port->logAnnounceInterval);
to_configs[PP_TO_ANN_RECEIPT].value = 1000 * (
port->announceReceiptTimeout << port->logAnnounceInterval);
to_configs[PP_TO_ANN_SEND].value = port->logAnnounceInterval;
to_configs[PP_TO_ANN_SEND].value = pp_timeout_log_to_ms(port->logAnnounceInterval);
to_configs[PP_TO_QUALIFICATION].value =
(1000 << port->logAnnounceInterval)*(DSCUR(ppi)->stepsRemoved + 1);
}
......@@ -74,11 +93,9 @@ void pp_timeout_set(struct pp_instance *ppi, int index)
int millisec;
struct timeout_config * to_config=&to_configs[index];
if (to_config->which_rand==RAND_NONE ) {
millisec = to_config->value; /* Just a constant */
} else {
millisec = to_config->value;
if (to_config->which_rand!=RAND_NONE ) {
uint32_t rval;
int logval = to_config->value;
if (!seed) {
uint32_t *p;
......@@ -97,12 +114,6 @@ void pp_timeout_set(struct pp_instance *ppi, int index)
rval <<= 10;
rval ^= (unsigned int) (seed / 65536) % 1024;
/*
* logval is signed. Let's imagine it's no less than -4.
* Here below, 0 gets to 16 * 25 = 400ms, 40% of the nominal value
*/
millisec = (1 << (logval + 4)) * 25;
switch(to_config->which_rand) {
case RAND_70_130:
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment