Beispiel #1
0
// --------------------------------------------------------------------------
// Checks if the gogoCLIENT has been requested to stop and exit.
//
// Returns 1 if gogoCLIENT is being requested to stop and exit.
// Else, waits 'uiWaitMs' miliseconds and returns 0.
//
// Defined in tsp_client.h
//
int tspCheckForStopOrWait( const unsigned int uiWaitMs )
{
  // Sleep for the amount of time specified, if signal has not been sent.
  if( indSigHUP == 0 )
  {
    pal_sleep( uiWaitMs );
  }

  return indSigHUP;
}
static DIMUTEX_RET_E dimutex_algo_compute_times (
   DIMUTEX_CTXT_X *px_dimutex_ctxt)
{
   DIMUTEX_RET_E e_error = eDIMUTEX_RET_FAILURE;
   DIMUTEX_ALGO_RESOURCES_X *px_resources = NULL;
   PAL_RET_E e_pal_ret = ePAL_RET_FAILURE;
   DIMUTEX_ALGO_STATS_X *px_stats = NULL;
   uint32_t ui_temp = 0;

   if (NULL == px_dimutex_ctxt)
   {
      DMUT_LOG_LOW("Invalid Args");
      e_error = eDIMUTEX_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   px_resources = &(px_dimutex_ctxt->x_algo.x_resources);
   px_stats = &(px_dimutex_ctxt->x_algo.x_algo_stats);
   DMUT_LOG_FULL("[RES]Before pal_mutex_lock");
   e_pal_ret = pal_mutex_lock (px_resources->hl_algo_mutex_hdl);
   if (e_pal_ret != ePAL_RET_SUCCESS)
   {
      DMUT_LOG_LOW("pal_mutex_lock failed: %d", e_pal_ret);
      e_error = eDIMUTEX_RET_RESOURCE_FAILURE;
      goto CLEAN_RETURN;
   }
   DMUT_LOG_FULL("[RES]After pal_mutex_lock");

   if (0 == (px_dimutex_ctxt->x_nodes.ui_this_node_idx % 2))
   {
      if (px_stats->ui_count <= DIMUTEX_ALGO_CS_REQUEST_RATE_CHANGE_AFTER)
      {
         ui_temp = dimutex_algo_get_rand_bw_10_20 ();
         px_resources->ui_next_entry_in_ms = (ui_temp
            * px_stats->ui_unit_time_ms);
         DMUT_LOG_LOW(
            "[RES]Even Node: Count <= %d. Generated Random No: %d, Next entry in %d ms",
            DIMUTEX_ALGO_CS_REQUEST_RATE_CHANGE_AFTER,
            ui_temp, px_resources->ui_next_entry_in_ms);
      }
      else
      {
         ui_temp = dimutex_algo_get_rand_bw_40_50 ();
         px_resources->ui_next_entry_in_ms = (ui_temp
            * px_stats->ui_unit_time_ms);
         DMUT_LOG_LOW(
            "[RES]Even Node: Count > %d & <= %d. Generated Random No: %d, Next entry "
            "in %d ms", DIMUTEX_ALGO_CS_REQUEST_RATE_CHANGE_AFTER,
            DIMUTEX_ALGO_CS_MAX_REQUEST_COUNT,
            ui_temp, px_resources->ui_next_entry_in_ms);
      }
   }
   else
   {
      ui_temp = dimutex_algo_get_rand_bw_10_20 ();
      px_resources->ui_next_entry_in_ms = (ui_temp * px_stats->ui_unit_time_ms);
      DMUT_LOG_LOW(
         "[RES]Odd Node: Count <= %d. Generated Random No: %d, Next entry in %d ms",
         DIMUTEX_ALGO_CS_REQUEST_RATE_CHANGE_AFTER,
         ui_temp, px_resources->ui_next_entry_in_ms);
   }

   e_pal_ret = pal_mutex_unlock (px_resources->hl_algo_mutex_hdl);
   if (e_pal_ret != ePAL_RET_SUCCESS)
   {
      DMUT_LOG_LOW("pal_mutex_unlock failed: %d", e_pal_ret);
      e_error = eDIMUTEX_RET_RESOURCE_FAILURE;
   }
   else
   {
      DMUT_LOG_LOW("[RES]Waiting %d ms till next CS request",
         px_resources->ui_next_entry_in_ms);
      pal_sleep(px_resources->ui_next_entry_in_ms);
      e_error = eDIMUTEX_RET_SUCCESS;
   }
CLEAN_RETURN:
   return e_error;
}
static DIMUTEX_RET_E dimutex_algo_enter_critical_section (
   DIMUTEX_CTXT_X *px_dimutex_ctxt)
{
   DIMUTEX_RET_E e_error = eDIMUTEX_RET_FAILURE;
   PAL_RET_E e_pal_ret = ePAL_RET_FAILURE;
   DIMUTEX_ALGO_RESOURCES_X *px_resources = NULL;
   DIMUTEX_ALGO_STATS_X *px_stats = NULL;
   DIMUTEX_ALGO_CS_ENTRY_STAT_X *px_stat_entry = NULL;

   if (NULL == px_dimutex_ctxt)
   {
      DMUT_LOG_LOW("Invalid Args");
      e_error = eDIMUTEX_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   px_resources = &(px_dimutex_ctxt->x_algo.x_resources);
   px_stats = &(px_dimutex_ctxt->x_algo.x_algo_stats);
   DMUT_LOG_FULL("[RES]Before pal_mutex_lock");
   e_pal_ret = pal_mutex_lock (px_resources->hl_algo_mutex_hdl);
   if (e_pal_ret != ePAL_RET_SUCCESS)
   {
      DMUT_LOG_LOW("pal_mutex_lock failed: %d", e_pal_ret);
      e_error = eDIMUTEX_RET_RESOURCE_FAILURE;
      goto CLEAN_RETURN;
   }
   DMUT_LOG_FULL("[RES]After pal_mutex_lock");

   px_stat_entry = &(px_stats->xa_cs_entry_stat[px_stats->ui_count]);

   printf("[RES]****************************************************************************************************\n");
   printf ("[RES]*CS Entry: Current Count: %d, Req @: %d ms, Granted @: %d ms, "
      "Req Sent: %d, Reply Recvd: %d, Will Hold For %d ms*\n",
      (px_stats->ui_count + 1),
      px_stat_entry->ui_cs_req_time_ms,
      px_stat_entry->ui_cs_grant_time_ms,
      px_stat_entry->ui_no_request_msgs_sent,
      px_stat_entry->ui_no_reply_msgs_received,
      (DIMUTEX_ALGO_CS_EXECUTION_MAX_UNITS * px_stats->ui_unit_time_ms));
   printf("[RES]****************************************************************************************************\n\n");

   DMUT_LOG_LOW("[RES]****************************************************************************************************");
   DMUT_LOG_LOW ("[RES]*CS Entry: Current Count: %d, Req @: %d ms, Granted @: %d ms, "
      "Req Sent: %d, Reply Recvd: %d, Will Hold For %d ms*",
      (px_stats->ui_count + 1),
      px_stat_entry->ui_cs_req_time_ms,
      px_stat_entry->ui_cs_grant_time_ms,
      px_stat_entry->ui_no_request_msgs_sent,
      px_stat_entry->ui_no_reply_msgs_received,
      (DIMUTEX_ALGO_CS_EXECUTION_MAX_UNITS * px_stats->ui_unit_time_ms));
   DMUT_LOG_LOW("[RES]****************************************************************************************************");

   e_pal_ret = pal_mutex_unlock (px_resources->hl_algo_mutex_hdl);
   if (e_pal_ret != ePAL_RET_SUCCESS)
   {
      DMUT_LOG_LOW("pal_mutex_unlock failed: %d", e_pal_ret);
      e_error = eDIMUTEX_RET_RESOURCE_FAILURE;
      goto CLEAN_RETURN;
   }

   pal_sleep((DIMUTEX_ALGO_CS_EXECUTION_MAX_UNITS * px_stats->ui_unit_time_ms));
   DMUT_LOG_FULL("[RES]Before pal_mutex_lock");
   e_pal_ret = pal_mutex_lock (px_resources->hl_algo_mutex_hdl);
   if (e_pal_ret != ePAL_RET_SUCCESS)
   {
      DMUT_LOG_LOW("pal_mutex_lock failed: %d", e_pal_ret);
      e_error = eDIMUTEX_RET_RESOURCE_FAILURE;
      goto CLEAN_RETURN;
   }
   DMUT_LOG_FULL("[RES]After pal_mutex_lock");
   DMUT_LOG_LOW("[RES]Exiting critical section. Held it for %d ms",
      (DIMUTEX_ALGO_CS_EXECUTION_MAX_UNITS * px_stats->ui_unit_time_ms));

   px_stats->ui_count++;

   e_pal_ret = pal_mutex_unlock (px_resources->hl_algo_mutex_hdl);
   if (e_pal_ret != ePAL_RET_SUCCESS)
   {
      DMUT_LOG_LOW("pal_mutex_unlock failed: %d", e_pal_ret);
      e_error = eDIMUTEX_RET_RESOURCE_FAILURE;
   }
   else
   {
      e_error = eDIMUTEX_RET_SUCCESS;
   }

CLEAN_RETURN:
   return e_error;
}
// --------------------------------------------------------------------------
// IEE_process: ICMP Echo Engine main processing routine.
//
// Parameters:
//   p_config: Opaque pointer to a ICMP_ECHO_ENGINE_PARMS structure.
//
// Return values:
//   IEE_SUCCESS on normal execution.
//   IEE_INVALID_PARMS if invalid p_config.
//   IEE_CONNECTIVITY_ASSESSED (ACD only) Received one echo reply on time.
//   IEE_GENERAL_ECHO_TIMEOUT when the maximal number of successive timeouts
//               has been detected.
//   IEE_GENERAL_ECHO_ERROR on a fatal error.
//
iee_ret_t IEE_process( void* p_config )
{
  PICMP_ECHO_ENGINE_PARMS p_engine = (PICMP_ECHO_ENGINE_PARMS)p_config;
  struct timeval tv_reference;
  iee_ret_t retval = IEE_SUCCESS;


  // Verify input parameters.
  if( p_engine == NULL )
  {
    // Error: invalid p_config, or already freed.
    return IEE_INVALID_PARMS;
  }

  if( (iee_mode_t)p_engine->eng_mode == IEE_MODE_KA )
  {
    // When icmp echo engine is is Keepalive(KA) mode, the first sent echo
    // REQUEST is sent after a full interval. => Wait for one interval.
    uint32_t total_sleep_time = p_engine->send_interval;
    uint32_t sleep_time;

    DBG_PRINT("Sleeping %d milliseconds before sending first ECHO REQUEST.\n", total_sleep_time);

    // Break the sleep in several chunks in case we're notified to stop.
    while( p_engine->eng_ongoing == 1  &&  total_sleep_time > 0 )
    {
      sleep_time = (total_sleep_time>1000)?1000:total_sleep_time;
      pal_sleep( sleep_time );
      total_sleep_time -= sleep_time;
    }
  }


  // ------------------------------------------------------------------------
  // Main ICMP echo engine loop. Loop until we're notified to stop, or we've
  //   sent the number of ECHO REQUESTS we had to.
  // ------------------------------------------------------------------------
  while( p_engine->eng_ongoing == 1  &&
        (p_engine->echo_num == 0  ||  p_engine->count_send < p_engine->echo_num) )
  {
    // ------------------------------
    // Time to send an ECHO request.
    // ------------------------------
    retval = _do_send_wrap( p_engine );
    if( retval != IEE_SUCCESS )
    {
      // An error occurred while sending.
      break;
    }

    // Check if we've been notified to stop, or an event has triggered a stop.
    if( p_engine->eng_ongoing == 0 )
    {
      // Stop processing.
      break;
    }

    // Synchronize time reference variable with 'now'.
    pal_gettimeofday( &tv_reference );

    // Add one echo interval to tv_reference.
    _compute_next_send( p_engine, &tv_reference );

    // -------------------------------------------------------------------
    // Wait and read for incoming packets.
    //   Function will return when tv_reference is approximatively 'now'.
    // -------------------------------------------------------------------
    retval = _do_read_wrap( p_engine, &tv_reference );
    if( retval != IEE_SUCCESS )
    {
      // A retval different than IEE_SUCCESS indicates that we should stop
      //   processing. It does not necessarily mean an error occurred.
      break;
    }
    DBG_PRINT("\n");
  }

  DBG_PRINT("Statistics:\n\tSent: %03d\n\tReceived on time: %03d\n\tReceived late: %03d\n",
             p_engine->count_send, p_engine->count_ontime, p_engine->count_late );


  return retval;
}