gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] 01/03: UTIL: add test demonstrating scheduler bug, don't run it


From: gnunet
Subject: [gnunet] 01/03: UTIL: add test demonstrating scheduler bug, don't run it by default.
Date: Mon, 06 Feb 2023 16:12:47 +0100

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

grothoff pushed a commit to branch master
in repository gnunet.

commit 3f6f1fb44b6b6aa8f70e71d7a9c73ba623f8c9f7
Author: ulfvonbelow <strilen@tilde.club>
AuthorDate: Sat Jan 28 15:30:54 2023 -0600

    UTIL: add test demonstrating scheduler bug, don't run it by default.
    
    These demonstrate a bug in the scheduler by which a task can prevent any 
other
    task from running for an arbitrarily long time despite regularly yielding to
    the scheduler.  It is caused by a faulty check in GNUNET_SCHEDULER_do_work
    that assumes that the task that was the last in the queue when the pass 
began
    will still be in the same relative position when the pass ends, and uses 
this
    assumption to detect the end of the current pass.  This assumption fails 
when
    the last task of the current pass is canceled after the pass has started.  
It
    also fails when we schedule a higher-priority task to run immediately, 
causing
    work_priority to immediately switch such that we now process a queue that
    doesn't contain the pass-ending task we're looking for.
    
    These tests are built, but not run by 'make check' yet, since they currently
    fail.  You can manually verify that they do currently fail.
    
    Signed-off-by: Christian Grothoff <christian@grothoff.org>
---
 src/util/Makefile.am                       | 12 +++++++
 src/util/test_scheduler_hogging_cancel.c   | 51 +++++++++++++++++++++++++++
 src/util/test_scheduler_hogging_priority.c | 55 ++++++++++++++++++++++++++++++
 3 files changed, 118 insertions(+)

diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index ed01558eb..81b8a93b7 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -174,6 +174,8 @@ endif
 noinst_PROGRAMS = \
  gnunet-config-diff \
  test_common_logging_dummy \
+ test_scheduler_hogging_cancel \
+ test_scheduler_hogging_priority \
  gnunet-crypto-tvg
 
 if ENABLE_TEST_RUN
@@ -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/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]