gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] branch master updated: fix scheduler bug with same-priority imm


From: gnunet
Subject: [gnunet] branch master updated: fix scheduler bug with same-priority immediately-ready tasks possibly hogging the scheduler
Date: Tue, 17 May 2022 10:00:50 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 5fcabf87a fix scheduler bug with same-priority immediately-ready tasks 
possibly hogging the scheduler
5fcabf87a is described below

commit 5fcabf87a066a776d40ff52484fa8d54e8302963
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue May 17 10:00:25 2022 +0200

    fix scheduler bug with same-priority immediately-ready tasks possibly 
hogging the scheduler
---
 src/util/scheduler.c | 47 ++++++++++++++++++++++-------------------------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index 03a7c0dfb..7e035ae3d 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      Copyright (C) 2009-2017 GNUnet e.V.
+      Copyright (C) 2009-2017, 2022 GNUnet e.V.
 
       GNUnet is free software: you can redistribute it and/or modify it
       under the terms of the GNU Affero General Public License as published
@@ -516,6 +516,8 @@ queue_ready_task (struct GNUNET_SCHEDULER_Task *task)
   GNUNET_CONTAINER_DLL_insert_tail (ready_head[p],
                                     ready_tail[p],
                                     task);
+  if (p > work_priority)
+    work_priority = p;
   task->in_ready_list = GNUNET_YES;
   ready_count++;
 }
@@ -639,29 +641,11 @@ sighandler_pipe ()
 }
 
 
-///**
-// * Wait for a short time.
-// * Sleeps for @a ms ms (as that should be long enough for virtually all
-// * modern systems to context switch and allow another process to do
-// * some 'real' work).
-// *
-// * @param ms how many ms to wait
-// */
-// static void
-// short_wait (unsigned int ms)
-// {
-//  struct GNUNET_TIME_Relative timeout;
-//
-//  timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 
ms);
-//  (void) GNUNET_NETWORK_socket_select (NULL, NULL, NULL, timeout);
-// }
-
-
 /**
  * Signal handler called for signals that should cause us to shutdown.
  */
 static void
-sighandler_shutdown ()
+sighandler_shutdown (void)
 {
   static char c;
   int old_errno = errno;        /* backup errno */
@@ -669,15 +653,16 @@ sighandler_shutdown ()
   if (getpid () != my_pid)
     _exit (1);                   /* we have fork'ed since the signal handler 
was created,
                                   * ignore the signal, see 
https://gnunet.org/vfork discussion */
-  GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle
-                            (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_WRITE),
+  GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (
+                            shutdown_pipe_handle,
+                            GNUNET_DISK_PIPE_END_WRITE),
                           &c, sizeof(c));
   errno = old_errno;
 }
 
 
 static void
-shutdown_if_no_lifeness ()
+shutdown_if_no_lifeness (void)
 {
   struct GNUNET_SCHEDULER_Task *t;
 
@@ -2072,6 +2057,8 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle 
*sh)
   }
   else
   {
+    struct GNUNET_SCHEDULER_Task *last;
+
     /* find out which task priority level we are going to
        process this time */
     max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP;
@@ -2088,7 +2075,9 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle 
*sh)
     }
     GNUNET_assert (NULL != pos);        /* ready_count wrong? */
 
-    /* process all tasks at this priority level, then yield */
+    /* process all *existing* tasks at this priority
+       level, then yield */
+    last = ready_tail[work_priority];
     while (NULL != (pos = ready_head[work_priority]))
     {
       GNUNET_CONTAINER_DLL_remove (ready_head[work_priority],
@@ -2147,7 +2136,8 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle 
*sh)
       }
       if (NULL != pos->fds)
       {
-        int del_result = scheduler_driver->del (scheduler_driver->cls, pos);
+        int del_result = scheduler_driver->del (scheduler_driver->cls,
+                                                pos);
         if (GNUNET_OK != del_result)
         {
           LOG (GNUNET_ERROR_TYPE_ERROR,
@@ -2158,6 +2148,13 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle 
*sh)
       active_task = NULL;
       dump_backtrace (pos);
       destroy_task (pos);
+      /* pointer 'pos' was free'd, but we can still safely check for
+         pointer equality still. */
+      if (pos == last)
+        break; /* All tasks that _were_ ready when we started were
+                  executed. New tasks may have been added in the
+                  meantime, but we should check with the OS to
+                  be sure no higher-priority actions are pending! */
     }
   }
   shutdown_if_no_lifeness ();

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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