gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] branch master updated (eabc1baaf -> 35ca280a7)


From: gnunet
Subject: [gnunet] branch master updated (eabc1baaf -> 35ca280a7)
Date: Mon, 06 Feb 2023 16:12:46 +0100

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

grothoff pushed a change to branch master
in repository gnunet.

    from eabc1baaf DHT: Fix warnings when freeing allocated strings from 
GNUNET_STRINGS_get_utf8_args
     new 3f6f1fb44 UTIL: add test demonstrating scheduler bug, don't run it by 
default.
     new 763335e08 UTIL: use dedicated marker in ready queue.
     new 35ca280a7 -remove dead variable, obsoleted by patch for #7617

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 contrib/gana                               |  2 +-
 contrib/sphinx                             |  2 +-
 src/util/Makefile.am                       | 12 +++++++
 src/util/scheduler.c                       | 48 +++++++++++++++++++-------
 src/util/test_scheduler_hogging_cancel.c   | 51 +++++++++++++++++++++++++++
 src/util/test_scheduler_hogging_priority.c | 55 ++++++++++++++++++++++++++++++
 6 files changed, 156 insertions(+), 14 deletions(-)
 create mode 100644 src/util/test_scheduler_hogging_cancel.c
 create mode 100644 src/util/test_scheduler_hogging_priority.c

diff --git a/contrib/gana b/contrib/gana
index 79163ab6e..66228b8a4 160000
--- a/contrib/gana
+++ b/contrib/gana
@@ -1 +1 @@
-Subproject commit 79163ab6ea6f6cfe7f4311f91fb45c747b8c33da
+Subproject commit 66228b8a4306f028d843d78fbfcca54260539ff9
diff --git a/contrib/sphinx b/contrib/sphinx
index 4f40b5dec..9c5b9d904 160000
--- a/contrib/sphinx
+++ b/contrib/sphinx
@@ -1 +1 @@
-Subproject commit 4f40b5deca02c8dc64ff6c73e6602e6abdd1bae2
+Subproject commit 9c5b9d9040d21542eff792e26624cf9669b127aa
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index ed01558eb..431bd7d0d 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -321,6 +321,8 @@ check_PROGRAMS = \
  test_resolver_api.nc \
  test_scheduler \
  test_scheduler_delay \
+ test_scheduler_hogging_cancel \
+ test_scheduler_hogging_priority \
  test_service \
  test_strings \
  test_strings_to_data \
@@ -587,6 +589,16 @@ test_scheduler_delay_SOURCES = \
 test_scheduler_delay_LDADD = \
  libgnunetutil.la
 
+test_scheduler_hogging_cancel_SOURCES = \
+ test_scheduler_hogging_cancel.c
+test_scheduler_hogging_cancel_LDADD = \
+ libgnunetutil.la
+
+test_scheduler_hogging_priority_SOURCES = \
+ test_scheduler_hogging_priority.c
+test_scheduler_hogging_priority_LDADD = \
+ libgnunetutil.la
+
 test_service_SOURCES = \
  test_service.c
 test_service_LDADD = \
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index f3b220c4a..70193a0d2 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -248,6 +248,13 @@ struct GNUNET_SCHEDULER_Task
   struct GNUNET_AsyncScopeSave scope;
 };
 
+/**
+ * Placed at the end of a ready queue to indicate where a scheduler run pass
+ * ends. The next, prev, in_ready_list and priority fields are the only ones
+ * that should be used.
+ */
+static struct GNUNET_SCHEDULER_Task pass_end_marker;
+
 
 /**
  * A struct representing an event the select driver is waiting for
@@ -503,6 +510,27 @@ get_timeout ()
   return timeout;
 }
 
+static void remove_pass_end_marker ()
+{
+  if (pass_end_marker.in_ready_list)
+  {
+    GNUNET_CONTAINER_DLL_remove (ready_head[pass_end_marker.priority],
+                                 ready_tail[pass_end_marker.priority],
+                                 &pass_end_marker);
+    pass_end_marker.in_ready_list = GNUNET_NO;
+  }
+}
+
+static void set_work_priority (enum GNUNET_SCHEDULER_Priority p)
+{
+  remove_pass_end_marker ();
+  GNUNET_CONTAINER_DLL_insert_tail (ready_head[p],
+                                    ready_tail[p],
+                                    &pass_end_marker);
+  pass_end_marker.priority = p;
+  pass_end_marker.in_ready_list = GNUNET_YES;
+  work_priority = p;
+}
 
 /**
  * Put a task that is ready for execution into the ready queue.
@@ -518,7 +546,7 @@ queue_ready_task (struct GNUNET_SCHEDULER_Task *task)
                                     ready_tail[p],
                                     task);
   if (p > work_priority)
-    work_priority = p;
+    set_work_priority (p);
   task->in_ready_list = GNUNET_YES;
   ready_count++;
 }
@@ -752,6 +780,9 @@ GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p)
        NULL != pos;
        pos = pos->next)
     ret++;
+  if (pass_end_marker.in_ready_list && pass_end_marker.priority == p)
+    // Don't count the dummy marker
+    ret--;
   return ret;
 }
 
@@ -2030,8 +2061,6 @@ 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;
@@ -2050,8 +2079,9 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle 
*sh)
 
     /* process all *existing* tasks at this priority
        level, then yield */
-    last = ready_tail[work_priority];
-    while (NULL != (pos = ready_head[work_priority]))
+    set_work_priority (work_priority);
+    while (NULL != (pos = ready_head[work_priority])
+           && pos != &pass_end_marker)
     {
       GNUNET_CONTAINER_DLL_remove (ready_head[work_priority],
                                    ready_tail[work_priority],
@@ -2121,14 +2151,8 @@ 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! */
     }
+    remove_pass_end_marker ();
   }
   shutdown_if_no_lifeness ();
   if (0 == ready_count)
diff --git a/src/util/test_scheduler_hogging_cancel.c 
b/src/util/test_scheduler_hogging_cancel.c
new file mode 100644
index 000000000..7611338b3
--- /dev/null
+++ b/src/util/test_scheduler_hogging_cancel.c
@@ -0,0 +1,51 @@
+#include "gnunet_util_lib.h"
+#include <unistd.h>
+
+static int count = 0;
+static int final_count;
+static struct GNUNET_SCHEDULER_Task *t4;
+
+static void end (void *cls)
+{
+  final_count = count;
+  count = 5000;
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+static void self_rescheduling (void *cls)
+{
+  if (0 == count)
+  {
+    GNUNET_SCHEDULER_cancel (t4);
+    GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_UNIT_MILLISECONDS,
+                                                
GNUNET_SCHEDULER_PRIORITY_URGENT,
+                                                &end,
+                                                NULL);
+    sleep (1);
+    /* end should be added to ready queue on next scheduler pass for certain
+       now */
+  }
+  if (++count < 5000)
+    {
+      GNUNET_SCHEDULER_add_now (&self_rescheduling, NULL);
+    }
+}
+
+static void to_be_canceled (void *cls)
+{
+  /* Don't run me! */
+}
+
+
+static void init (void *cls)
+{
+  GNUNET_SCHEDULER_add_now (&self_rescheduling, NULL);
+  t4 = GNUNET_SCHEDULER_add_now (&to_be_canceled, NULL);
+}
+
+
+int main (int argc, char **argv)
+{
+  GNUNET_SCHEDULER_run (&init, NULL);
+  return final_count < 5000 ? 0 : 1;
+}
diff --git a/src/util/test_scheduler_hogging_priority.c 
b/src/util/test_scheduler_hogging_priority.c
new file mode 100644
index 000000000..217a39ce7
--- /dev/null
+++ b/src/util/test_scheduler_hogging_priority.c
@@ -0,0 +1,55 @@
+#include "gnunet_util_lib.h"
+#include <unistd.h>
+
+static int count = 0;
+static int final_count;
+
+static void end (void *cls)
+{
+  final_count = count;
+  count = 5000;
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+static void self_rescheduling (void *cls)
+{
+  if (count == 0)
+  {
+    GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_UNIT_MILLISECONDS,
+                                                
GNUNET_SCHEDULER_PRIORITY_URGENT,
+                                                &end,
+                                                NULL);
+    sleep(1);
+    /* end should be added to ready queue on next scheduler pass for certain
+       now */
+  }
+  if (++count < 5000)
+  {
+    GNUNET_SCHEDULER_add_now (&self_rescheduling, NULL);
+  }
+}
+
+
+static void noop (void *cls)
+{
+}
+
+static void indirection (void *cls)
+{
+  GNUNET_SCHEDULER_add_with_reason_and_priority (&self_rescheduling, NULL,
+                                                 
GNUNET_SCHEDULER_REASON_STARTUP,
+                                                 
GNUNET_SCHEDULER_PRIORITY_HIGH);
+}
+
+static void init (void *cls)
+{
+  GNUNET_SCHEDULER_add_now (&indirection, NULL);
+  GNUNET_SCHEDULER_add_now (&noop, NULL);
+}
+
+
+int main (int argc, char **argv)
+{
+  GNUNET_SCHEDULER_run (&init, NULL);
+  return final_count < 5000 ? 0 : 1;
+}

-- 
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]