[prev in list] [next in list] [prev in thread] [next in thread] 

List:       zebra
Subject:    [zebra 5903] [PATCH] bug in thread.c ?!
From:       Gleb Natapov <gleb () nbase ! co ! il>
Date:       2000-11-27 16:21:15
[Download RAW message or body]

Hello,

 The ospf code relies on the assumption that if a thread schedules an
event, the event will be executed right after the current thread exits and 
before any other thread will run. If this assumption is not valid
the ospf should be rewritten :) otherwise there is a bug in thread.c since
this assumption doesn't hold with current thread implementation.

 Suppose there are two timers  t1 and t2 that expired simultaneously. 
thread_fetch adds both of them to event list and runs t1. t1 adds event e1
to the end of event list right after t2. Next thread that will be executed
after t1 exits is t2 and not e1 as ospf assumes.

 The attached patch will guaranty that events are always executed before
any other thread.

--
			Gleb.

["patch.thread" (text/plain)]

Index: lib/thread.c
===================================================================
RCS file: /cvsroot/zebra/lib/thread.c,v
retrieving revision 1.16
diff -u -r1.16 thread.c
--- lib/thread.c	2000/08/22 11:39:01	1.16
+++ lib/thread.c	2000/11/27 07:47:15
@@ -36,7 +36,8 @@
 #define THREAD_WRITE 1
 #define THREAD_TIMER 2
 #define THREAD_EVENT 3
-#define THREAD_UNUSED 4
+#define THREAD_READY 4
+#define THREAD_UNUSED 5
 
 /* Make thread master. */
 struct thread_master *
@@ -187,6 +188,19 @@
       thread_add_unuse (m, t);
     }
 
+  thread = m->ready.head;
+  while (thread)
+    {
+      struct thread *t;
+
+      t = thread;
+      thread = t->next;
+
+      thread_list_delete (&m->ready, t);
+      t->type = THREAD_UNUSED;
+      thread_add_unuse (m, t);
+    }
+
   thread_clean_unuse (m);
   XFREE (MTYPE_THREAD_MASTER, m);
 }
@@ -405,6 +419,12 @@
 #endif /* DEBUG */  
       thread_list_delete (&thread->master->event, thread);
       break;
+    case THREAD_READY:
+#ifdef DEBUG
+      printf ("cancel ready\n");
+#endif /* DEBUG */  
+      thread_list_delete (&thread->master->ready, thread);
+      break;
     default:
       break;
     }
@@ -493,6 +513,15 @@
       return fetch;
     }
 
+  /* If there is ready threads process them */
+  while ((thread = thread_trim_head (&m->ready)))
+    {
+      *fetch = *thread;
+      thread->type = THREAD_UNUSED;
+      thread_add_unuse (m, thread);
+      return fetch;
+    }
+
   /* Calculate select wait timer. */
   if (m->timer.head)
     {
@@ -580,8 +609,8 @@
 	  assert (FD_ISSET (t->u.fd, &m->readfd));
 	  FD_CLR(t->u.fd, &m->readfd);
 	  thread_list_delete (&m->read, t);
-	  thread_list_add (&m->event, t);
-	  t->type = THREAD_EVENT;
+	  thread_list_add (&m->ready, t);
+	  t->type = THREAD_READY;
 	}
     }
 #ifdef DEBUG
@@ -609,8 +638,8 @@
 	  assert (FD_ISSET (t->u.fd, &m->writefd));
 	  FD_CLR(t->u.fd, &m->writefd);
 	  thread_list_delete (&m->write, t);
-	  thread_list_add (&m->event, t);
-	  t->type = THREAD_EVENT;
+	  thread_list_add (&m->ready, t);
+	  t->type = THREAD_READY;
 	}
     }
 
@@ -631,15 +660,15 @@
       if (thread_timer_cmp (timer_now, t->u.sands) >= 0)
       {
 	thread_list_delete (&m->timer, t);
-	thread_list_add (&m->event, t);
-	t->type = THREAD_EVENT;
+	thread_list_add (&m->ready, t);
+	t->type = THREAD_READY;
       }
     }
 
   /* Return one event. */
-  thread = thread_trim_head (&m->event);
+  thread = thread_trim_head (&m->ready);
 
-  /* There is no events. */
+  /* There is no ready thread. */
   if (!thread)
     goto retry;
 
Index: lib/thread.h
===================================================================
RCS file: /cvsroot/zebra/lib/thread.h,v
retrieving revision 1.7
diff -u -r1.7 thread.h
--- lib/thread.h	2000/01/11 07:11:48	1.7
+++ lib/thread.h	2000/11/27 07:47:15
@@ -38,6 +38,7 @@
   struct thread_list write;
   struct thread_list timer;
   struct thread_list event;
+  struct thread_list ready;
   struct thread_list unuse;
   fd_set readfd;
   fd_set writefd;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic