[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: fix scheduler bug with same-priority immediately-ready tasks possibly hogging the scheduler,
gnunet <=