Is is intentional that tummy_task is not initialized?
Ok, it won't crash because the current __run_task_queue() implementation
doesn't call tq->routine if it's NULL, but IMHO it's ugly.
Additionally I don't like the loop in flush_scheduled_tasks(), what
about replacing it with a locked semaphore (same idea as vfork)?
I've attched an untested patch.
--
Manfred
--- context.c.orig Sun Jan 28 17:02:35 2001
+++ context.c Sun Jan 28 17:09:24 2001
@@ -22,7 +22,6 @@
static DECLARE_TASK_QUEUE(tq_context);
static DECLARE_WAIT_QUEUE_HEAD(context_task_wq);
-static DECLARE_WAIT_QUEUE_HEAD(context_task_done);
static int keventd_running;
static struct task_struct *keventd_task;
@@ -97,7 +96,6 @@
schedule();
remove_wait_queue(&context_task_wq, &wait);
run_task_queue(&tq_context);
- wake_up(&context_task_done);
if (signal_pending(curtask)) {
while (waitpid(-1, (unsigned int *)0, __WALL|WNOHANG) > 0)
;
@@ -119,31 +117,24 @@
* The caller should hold no spinlocks and should hold no semaphores which could
* cause the scheduled tasks to block.
*/
-static struct tq_struct dummy_task;
-void flush_scheduled_tasks(void)
+static void up_semaphore(void* sem)
{
- int count;
- DECLARE_WAITQUEUE(wait, current);
+ up((struct semaphore*)sem);
+}
- /*
- * Do it twice. It's possible, albeit highly unlikely, that
- * the caller queued a task immediately before calling us,
- * and that the eventd thread was already past the run_task_queue()
- * but not yet into wake_up(), so it woke us up before completing
- * the caller's queued task or our new dummy task.
- */
- add_wait_queue(&context_task_done, &wait);
- for (count = 0; count < 2; count++) {
- set_current_state(TASK_UNINTERRUPTIBLE);
+void flush_scheduled_tasks(void)
+{
+ DECLARE_MUTEX_LOCKED(sem);
+ struct tq_struct wakeup_task;
- /* Queue a dummy task to make sure we get kicked */
- schedule_task(&dummy_task);
+ wakeup_task.routine = up_semaphore;
+ wakeup_task.data = &sem;
+ /* Queue a dummy task to make sure we get kicked */
+ schedule_task(&dummy_task);
- /* Wait for it to complete */
- schedule();
- }
- remove_wait_queue(&context_task_done, &wait);
+ /* Wait for it to complete */
+ down(&sem);
}
int start_context_thread(void)