[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.