/*
 * Check if and when lwIP has its next timeout, and set or cancel our timer
 * accordingly.
 */
static void
set_lwip_timer(void)
{
	uint32_t next_timeout;
	clock_t ticks;

	/* Ask lwIP when the next alarm is supposed to go off, if any. */
	next_timeout = sys_timeouts_sleeptime();

	/*
	 * Set or update the lwIP timer.  We rely on set_timer() asking the
	 * kernel for an alarm only if the timeout is different from the one we
	 * gave it last time (if at all).  However, due to conversions between
	 * absolute and relative times, and the fact that we cannot guarantee
	 * that the uptime itself does not change while executing these
	 * routines, set_timer() will sometimes be issuing a kernel call even
	 * if the alarm has not changed.  Not a huge deal, but fixing this will
	 * require a different interface to lwIP and/or the timers library.
	 */
	if (next_timeout != (uint32_t)-1) {
		/*
		 * Round up the next timeout (which is in milliseconds) to the
		 * number of clock ticks to add to the current time.  Avoid any
		 * potential for overflows, no matter how unrealistic..
		 */
		if (next_timeout > TMRDIFF_MAX / sys_hz())
			ticks = TMRDIFF_MAX;
		else
			ticks = (next_timeout * sys_hz() + 999) / 1000;

		set_timer(&lwip_timer, ticks, expire_lwip_timer, 0 /*unused*/);
	} else
		cancel_timer(&lwip_timer);	/* not really needed.. */
}
Esempio n. 2
0
/**
 * Wait (forever) for a message to arrive in an mbox.
 * While waiting, timeouts are processed.
 *
 * @param mbox the mbox to fetch the message from
 * @param msg the place to store the message
 */
void
sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
{
  u32_t sleeptime;

again:
  if (!next_timeout) {
    sys_arch_mbox_fetch(mbox, msg, 0);
    return;
  }

  sleeptime = sys_timeouts_sleeptime();
  if (sleeptime == 0 || sys_arch_mbox_fetch(mbox, msg, sleeptime) == SYS_ARCH_TIMEOUT) {
    /* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurred
       before a message could be fetched. */
    sys_check_timeouts();
    /* We try again to fetch a message from the mbox. */
    goto again;
  }
}