Index: core/sys.c
===================================================================
RCS file: /sources/lwip/lwip/src/core/sys.c,v
retrieving revision 1.20
diff -u -r1.20 sys.c
--- core/sys.c	11 Oct 2006 12:04:04 -0000	1.20
+++ core/sys.c	1 Mar 2007 13:05:57 -0000
@@ -48,7 +48,6 @@
 void
 sys_mbox_fetch(sys_mbox_t mbox, void **msg)
 {
-  u32_t time;
   struct sys_timeouts *timeouts;
   struct sys_timeo *tmptimeout;
   sys_timeout_handler h;
@@ -61,13 +60,11 @@
   if (!timeouts || !timeouts->next) {
     sys_arch_mbox_fetch(mbox, msg, 0);
   } else {
-    if (timeouts->next->time > 0) {
-      time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
-    } else {
-      time = SYS_ARCH_TIMEOUT;
-    }
-
-    if (time == SYS_ARCH_TIMEOUT) {
+    timestamp_t now = sys_arch_time_now();
+    timediff_t timeout = TIMESTAMP_DIFF(timeouts->next->expires, now);
+    if ((timeout <= 0) ||
+        (sys_arch_mbox_fetch(mbox, msg, timeout) == 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. */
@@ -83,24 +80,14 @@
 
       /* 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 <= timeouts->next->time) {
-  timeouts->next->time -= time;
-      } else {
-  timeouts->next->time = 0;
-      }
     }
-
   }
 }
 
+#if 0
 void
 sys_sem_wait(sys_sem_t sem)
 {
-  u32_t time;
   struct sys_timeouts *timeouts;
   struct sys_timeo *tmptimeout;
   sys_timeout_handler h;
@@ -116,13 +103,12 @@
   if (!timeouts || !timeouts->next) {
     sys_arch_sem_wait(sem, 0);
   } else {
-    if (timeouts->next->time > 0) {
-      time = sys_arch_sem_wait(sem, timeouts->next->time);
-    } else {
-      time = SYS_ARCH_TIMEOUT;
-    }
+    timestamp_t now = sys_arch_time_now();
+    timediff_t timeout = TIMESTAMP_DIFF(timeouts->next->expires, now);
+    if ((timeout <= 0) ||
+        (sys_arch_sem_wait(sem, timeout) == SYS_ARCH_TIMEOUT))
+    {
 
-    if (time == 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. */
@@ -139,25 +125,17 @@
 
       /* 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 <= timeouts->next->time) {
-  timeouts->next->time -= time;
-      } else {
-  timeouts->next->time = 0;
-      }
     }
-
   }
 }
+#endif
 
 void
 sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
 {
   struct sys_timeouts *timeouts;
   struct sys_timeo *timeout, *t;
+  timestamp_t now = sys_arch_time_now();
 
   timeout = memp_malloc(MEMP_SYS_TIMEOUT);
   if (timeout == NULL) {
@@ -166,7 +144,7 @@
   timeout->next = NULL;
   timeout->h = h;
   timeout->arg = arg;
-  timeout->time = msecs;
+  timeout->expires = TIMESTAMP_ADD(now, msecs);
 
   timeouts = sys_arch_timeouts();
 
@@ -180,22 +158,16 @@
     return;
   }
 
-  if (timeouts->next->time > msecs) {
-    timeouts->next->time -= msecs;
+  if (TIMESTAMP_DIFF(timeouts->next->expires,now) > (s32_t)msecs) {
     timeout->next = timeouts->next;
     timeouts->next = timeout;
   } else {
-    for(t = timeouts->next; t != NULL; t = t->next) {
-      timeout->time -= t->time;
-      if (t->next == NULL || t->next->time > timeout->time) {
-        if (t->next != NULL) {
-          t->next->time -= timeout->time;
-        }
-        timeout->next = t->next;
-        t->next = timeout;
+    for(t = timeouts->next; t->next != NULL; t = t->next) {
+      if (TIMESTAMP_DIFF(t->next->expires, now) > (s32_t)msecs)
         break;
-      }
     }
+    timeout->next = t->next;
+    t->next = timeout;
   }
 
 }
@@ -225,9 +197,6 @@
                 timeouts->next = t->next;
             else
                 prev_t->next = t->next;
-            /* If not the last one, add time of this one back to next */
-            if (t->next != NULL)
-                t->next->time += t->time;
             memp_free(MEMP_SYS_TIMEOUT, t);
             return;
         }
@@ -249,6 +218,7 @@
     sys_sem_signal(*(sswt_cb->psem));
 }
 
+#if 0
 /* Wait for a semaphore with timeout (specified in ms) */
 /* timeout = 0: wait forever */
 /* Returns 0 on timeout. 1 otherwise */
@@ -278,6 +248,7 @@
     }
 
 }
+#endif
 
 
 void
Index: include/lwip/sys.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/lwip/sys.h,v
retrieving revision 1.19
diff -u -r1.19 sys.h
--- include/lwip/sys.h	11 Oct 2006 12:04:05 -0000	1.19
+++ include/lwip/sys.h	1 Mar 2007 13:05:58 -0000
@@ -63,6 +63,61 @@
 
 #include "arch/sys_arch.h"
 
+/*
+ * This definition of timestamp relies on the fact that integer
+ * is represented as two's complement, which is true for most
+ * processors. If the processor uses different representation
+ * of integers, it should be defined in a port specific header.
+ *
+ * It is possible 64-bit values for timestamp_t and timediff_t,
+ * as they do not have to deal with overflow, they work regardless
+ * representation of integers, but that will slightly increase
+ * the footprint and slowdown execution on most processors. Also,
+ * compilers for 16-bit platform may not support 64-bit intergers,
+ * so it is not a good solution.
+ */
+#define TIMESTAMP_DEFINED
+#ifdef TIMESTAMP_DEFINED
+typedef u32_t timestamp_t;
+typedef s32_t timediff_t;
+
+/* TIMESTAMP_DIFF returns difference between two timestamps
+ * Examples:
+ *    TIMESTAMP_DIFF(1, 0) = 1
+ *    TIMESTAMP_DIFF(0, 1) = -1
+ *    TIMESTAMP_DIFF(0, MAX_TIMESTAMP) = 1
+ * where MAX_TIMESTAMP = 0xFFFFFFFF
+ */
+#define TIMESTAMP_DIFF(t1, t2) ((timediff_t)((t1) - (t2)))
+/*
+ * TIMESTAMP_ADD adds `timeout' to timestamp and returns
+ * the new value of timestamp
+ *
+ * For any values of timestamp and timeout, the following condition
+ * must be true
+ * TIMESTAMP_DIFF(TIMESTAMP_ADD(timestamp, timeout), timestamp) == timeout
+ */
+#define TIMESTAMP_ADD(timestamp, timeout) ((timestamp_t)((timestamp)+(timeout)))
+
+#endif /* TIMESTAMP_DEFINED */
+
+/* sys_arch_time_now() returns the current time in milliseconds
+ *
+ * if timestamp_t is defined as 32-bit unsigned, then
+ * the value should be taken by module 2^32. So after
+ * 0xFFFFFFFF, the next value should be 0.
+ *
+ * sys_arch_time_now implementation is platfrom specific.
+ *
+ * Because it can be defined as a macro in arch/sys_arch.h
+ * to avoid call overhead, its declaration is placed inside
+ * the ifndef-endif block.
+ */
+#ifndef sys_arch_time_now
+timestamp_t sys_arch_time_now(void);
+#endif
+
+
 /** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */
 #define SYS_ARCH_TIMEOUT 0xffffffff
 
@@ -70,7 +125,7 @@
 
 struct sys_timeo {
   struct sys_timeo *next;
-  u32_t time;
+  timestamp_t expires;
   sys_timeout_handler h;
   void *arg;
 };
@@ -100,8 +155,14 @@
 void sys_sem_signal(sys_sem_t sem);
 u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout);
 void sys_sem_free(sys_sem_t sem);
+#if 0
 void sys_sem_wait(sys_sem_t sem);
 int sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout);
+#else
+#define sys_sem_wait(sem) ((void)sys_arch_sem_wait((sem), 0))
+#define sys_sem_wait_timeout(sem, timeout) \
+	(sys_arch_sem_wait((sem),(timeout))!=SYS_ARCH_TIMEOUT)
+#endif
 
 /* Time functions. */
 #ifndef sys_msleep
