lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] tcp_ticks is not include the real tick of system?


From: edgar
Subject: [lwip-devel] tcp_ticks is not include the real tick of system?
Date: Mon, 12 Apr 2010 23:00:03 +0800

Hello All:
 
sys_mbox_fetch is implemented in the latest revision of lwip like this:
 
void
sys_mbox_fetch(sys_mbox_t mbox, void **msg)
{
  u32_t time_needed;
  struct sys_timeouts *timeouts;
  struct sys_timeo *tmptimeout;
  sys_timeout_handler h;
  void *arg;
 again:
  timeouts = sys_arch_timeouts();
  if (!timeouts || !timeouts->next) {
    UNLOCK_TCPIP_CORE();
    time_needed = sys_arch_mbox_fetch(mbox, msg, 0);
    LOCK_TCPIP_CORE();
  } else {
    if (timeouts->next->time > 0) {
      UNLOCK_TCPIP_CORE();
      time_needed = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
      LOCK_TCPIP_CORE();
    } else {
      time_needed = SYS_ARCH_TIMEOUT;
    }
    if (time_needed == SYS_ARCH_TIMEOUT) {
      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
         could be fetched. We should now call the timeout handler and
         deallocate the memory allocated for the timeout. */
      tmptimeout = timeouts->next;
      timeouts->next = tmptimeout->next;
      h   = tmptimeout->h;
      arg = tmptimeout->arg;
      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
      if (h != NULL) {
        LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void*)&h, arg));
        h(arg);
      }
      /* We try again to fetch a message from the mbox. */
      goto again;
    } else {
      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
         occured. The time variable is set to the number of
         milliseconds we waited for the message. */
      if (time_needed < timeouts->next->time) {
        timeouts->next->time -= time_needed;
      } else {
        timeouts->next->time = 0;
    }
  }
}
 
There are two shortcoming:
1. Variable time_needed is only included expired time while invoking sys_arch_mbox_fetch. timeouts->next->time must minus expired time of waiting and process message, such as time of invoking tcp_input.
2. Timer handler is delayed while flow enter the blue branch.
 
Repair method like this:
 
void
sys_mbox_fetch(sys_mbox_t mbox, void **msg)
{
  u32_t time_needed;
  struct sys_timeouts *timeouts;
  struct sys_timeo *tmptimeout;
  sys_timeout_handler h;
  void *arg;
+  u32_t time_expire = 0;
 again:
+  time_expire = sys_arch_expire_msecs();
  timeouts = sys_arch_timeouts();
  if (!timeouts || !timeouts->next) {
    UNLOCK_TCPIP_CORE();
    time_needed = sys_arch_mbox_fetch(mbox, msg, 0);
    LOCK_TCPIP_CORE();
  } else {
+    if(timeouts->next->time > time_expire)
+      timeouts->next->time -= time_expire;
+    else
+      timeouts->next->time = 0;
    if (timeouts->next->time > 0) {
      UNLOCK_TCPIP_CORE();
      time_needed = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
      LOCK_TCPIP_CORE();
    } else {
      time_needed = SYS_ARCH_TIMEOUT;
    }
    if (time_needed == SYS_ARCH_TIMEOUT) {
      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
         could be fetched. We should now call the timeout handler and
         deallocate the memory allocated for the timeout. */
      tmptimeout = timeouts->next;
      timeouts->next = tmptimeout->next;
      h   = tmptimeout->h;
      arg = tmptimeout->arg;
      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
      if (h != NULL) {
        LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void*)&h, arg));
        h(arg);
      }
      /* We try again to fetch a message from the mbox. */
      goto again;
    } else {
+#if 0 /* timeouts->next->time has already been changed. */
      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
         occured. The time variable is set to the number of
         milliseconds we waited for the message. */
      if (time_needed < timeouts->next->time) {
        timeouts->next->time -= time_needed;
      } else {
        timeouts->next->time = 0;
    }
+#endif
  }
}
and example of sys_arch_expire_msecs() like this:
 
u32_t sys_arch_expire_msecs(void)
{
 u32_t jiffies_expire = 0;
 static u32_t jiffies_start = 0;
 static u32_t jiffies_end = 0;
 jiffies_end = OSTicksGet(); /* get  running ticks of system  */
 if(0 == jiffies_start)
  jiffies_start = jiffies_end;
 jiffies_expire = jiffies_end - jiffies_start;
 jiffies_start = jiffies_end;
 return (jiffies_expire * 1000 / OS_TICKS_PER_SEC);
}
sys_arch_expire_msecs must be invoked for setting initial value of jiffies_start before while statement of tcpip_thread like this:
 
static void
tcpip_thread(void *arg)
{
  .....
  sys_arch_expire_msecs();
  LOCK_TCPIP_CORE();
  while (1) {                          /* MAIN Loop */
    sys_mbox_fetch(mbox, (void *)&msg);
    switch (msg->type) {
    ......
  }
}
 
Any suggestion?
 
Liu jianjun from ZTE Co., China. 
 
 
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]