diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-02-04 19:38:38 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-02-04 19:38:38 +0100 |
commit | 3039adb9578b01b3649c5c8ae5f4d6d8f8a7d51d (patch) | |
tree | 3e2db2300f3f613115c8c346e9503c6c28bedf8d /src/util/scheduler.c | |
parent | 1ca80565458244e9a9622d65bd3953fa3478372a (diff) | |
download | gnunet-3039adb9578b01b3649c5c8ae5f4d6d8f8a7d51d.tar.gz gnunet-3039adb9578b01b3649c5c8ae5f4d6d8f8a7d51d.zip |
fix task prioritization with recent hack
Diffstat (limited to 'src/util/scheduler.c')
-rw-r--r-- | src/util/scheduler.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c index 4be690d44..3d3e5216d 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c | |||
@@ -407,6 +407,11 @@ static enum GNUNET_SCHEDULER_Priority max_priority_added; | |||
407 | static int current_lifeness; | 407 | static int current_lifeness; |
408 | 408 | ||
409 | /** | 409 | /** |
410 | * Priority used currently in #GNUNET_SCHEDULER_do_work(). | ||
411 | */ | ||
412 | static enum GNUNET_SCHEDULER_Priority work_priority; | ||
413 | |||
414 | /** | ||
410 | * Function to use as a select() in the scheduler. | 415 | * Function to use as a select() in the scheduler. |
411 | * If NULL, we use GNUNET_NETWORK_socket_select(). | 416 | * If NULL, we use GNUNET_NETWORK_socket_select(). |
412 | */ | 417 | */ |
@@ -765,7 +770,6 @@ GNUNET_SCHEDULER_get_task_context () | |||
765 | unsigned int | 770 | unsigned int |
766 | GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p) | 771 | GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p) |
767 | { | 772 | { |
768 | struct GNUNET_SCHEDULER_Task *pos; | ||
769 | unsigned int ret; | 773 | unsigned int ret; |
770 | 774 | ||
771 | GNUNET_assert (NULL != active_task); | 775 | GNUNET_assert (NULL != active_task); |
@@ -774,7 +778,9 @@ GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p) | |||
774 | if (p == GNUNET_SCHEDULER_PRIORITY_KEEP) | 778 | if (p == GNUNET_SCHEDULER_PRIORITY_KEEP) |
775 | p = current_priority; | 779 | p = current_priority; |
776 | ret = 0; | 780 | ret = 0; |
777 | for (pos = ready_head[check_priority (p)]; NULL != pos; pos = pos->next) | 781 | for (struct GNUNET_SCHEDULER_Task *pos = ready_head[check_priority (p)]; |
782 | NULL != pos; | ||
783 | pos = pos->next) | ||
778 | ret++; | 784 | ret++; |
779 | return ret; | 785 | return ret; |
780 | } | 786 | } |
@@ -1111,6 +1117,7 @@ GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at, | |||
1111 | struct GNUNET_SCHEDULER_Task *t; | 1117 | struct GNUNET_SCHEDULER_Task *t; |
1112 | struct GNUNET_SCHEDULER_Task *pos; | 1118 | struct GNUNET_SCHEDULER_Task *pos; |
1113 | struct GNUNET_SCHEDULER_Task *prev; | 1119 | struct GNUNET_SCHEDULER_Task *prev; |
1120 | struct GNUNET_TIME_Relative left; | ||
1114 | 1121 | ||
1115 | /* scheduler must be running */ | 1122 | /* scheduler must be running */ |
1116 | GNUNET_assert (NULL != scheduler_driver); | 1123 | GNUNET_assert (NULL != scheduler_driver); |
@@ -1127,6 +1134,17 @@ GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at, | |||
1127 | t->timeout = at; | 1134 | t->timeout = at; |
1128 | t->priority = check_priority (priority); | 1135 | t->priority = check_priority (priority); |
1129 | t->lifeness = current_lifeness; | 1136 | t->lifeness = current_lifeness; |
1137 | init_backtrace (t); | ||
1138 | |||
1139 | left = GNUNET_TIME_absolute_get_remaining (at); | ||
1140 | if (0 == left.rel_value_us) | ||
1141 | { | ||
1142 | queue_ready_task (t); | ||
1143 | if (priority > work_priority) | ||
1144 | work_priority = priority; | ||
1145 | return t; | ||
1146 | } | ||
1147 | |||
1130 | /* try tail first (optimization in case we are | 1148 | /* try tail first (optimization in case we are |
1131 | * appending to a long list of tasks with timeouts) */ | 1149 | * appending to a long list of tasks with timeouts) */ |
1132 | if ((NULL == pending_timeout_head) || | 1150 | if ((NULL == pending_timeout_head) || |
@@ -1161,11 +1179,9 @@ GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at, | |||
1161 | } | 1179 | } |
1162 | /* finally, update heuristic insertion point to last insertion... */ | 1180 | /* finally, update heuristic insertion point to last insertion... */ |
1163 | pending_timeout_last = t; | 1181 | pending_timeout_last = t; |
1164 | |||
1165 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1182 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1166 | "Adding task %p\n", | 1183 | "Adding task %p\n", |
1167 | t); | 1184 | t); |
1168 | init_backtrace (t); | ||
1169 | return t; | 1185 | return t; |
1170 | } | 1186 | } |
1171 | 1187 | ||
@@ -1988,7 +2004,6 @@ GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task, | |||
1988 | int | 2004 | int |
1989 | GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) | 2005 | GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) |
1990 | { | 2006 | { |
1991 | enum GNUNET_SCHEDULER_Priority p; | ||
1992 | struct GNUNET_SCHEDULER_Task *pos; | 2007 | struct GNUNET_SCHEDULER_Task *pos; |
1993 | struct GNUNET_TIME_Absolute now; | 2008 | struct GNUNET_TIME_Absolute now; |
1994 | 2009 | ||
@@ -2064,19 +2079,21 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) | |||
2064 | GNUNET_assert (NULL == ready_head[GNUNET_SCHEDULER_PRIORITY_KEEP]); | 2079 | GNUNET_assert (NULL == ready_head[GNUNET_SCHEDULER_PRIORITY_KEEP]); |
2065 | /* yes, p>0 is correct, 0 is "KEEP" which should | 2080 | /* yes, p>0 is correct, 0 is "KEEP" which should |
2066 | * always be an empty queue (see assertion)! */ | 2081 | * always be an empty queue (see assertion)! */ |
2067 | for (p = GNUNET_SCHEDULER_PRIORITY_COUNT - 1; p > 0; p--) | 2082 | for (work_priority = GNUNET_SCHEDULER_PRIORITY_COUNT - 1; |
2083 | work_priority > 0; | ||
2084 | work_priority--) | ||
2068 | { | 2085 | { |
2069 | pos = ready_head[p]; | 2086 | pos = ready_head[work_priority]; |
2070 | if (NULL != pos) | 2087 | if (NULL != pos) |
2071 | break; | 2088 | break; |
2072 | } | 2089 | } |
2073 | GNUNET_assert (NULL != pos); /* ready_count wrong? */ | 2090 | GNUNET_assert (NULL != pos); /* ready_count wrong? */ |
2074 | 2091 | ||
2075 | /* process all tasks at this priority level, then yield */ | 2092 | /* process all tasks at this priority level, then yield */ |
2076 | while (NULL != (pos = ready_head[p])) | 2093 | while (NULL != (pos = ready_head[work_priority])) |
2077 | { | 2094 | { |
2078 | GNUNET_CONTAINER_DLL_remove (ready_head[p], | 2095 | GNUNET_CONTAINER_DLL_remove (ready_head[work_priority], |
2079 | ready_tail[p], | 2096 | ready_tail[work_priority], |
2080 | pos); | 2097 | pos); |
2081 | ready_count--; | 2098 | ready_count--; |
2082 | current_priority = pos->priority; | 2099 | current_priority = pos->priority; |
@@ -2230,9 +2247,12 @@ GNUNET_SCHEDULER_driver_init (const struct GNUNET_SCHEDULER_Driver *driver) | |||
2230 | /* Setup initial tasks */ | 2247 | /* Setup initial tasks */ |
2231 | current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; | 2248 | current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; |
2232 | current_lifeness = GNUNET_NO; | 2249 | current_lifeness = GNUNET_NO; |
2250 | /* ensure this task runs first, by using a priority level reserved for | ||
2251 | the scheduler (not really shutdown, but start-up ;-) */ | ||
2233 | install_parent_control_task = | 2252 | install_parent_control_task = |
2234 | GNUNET_SCHEDULER_add_now (&install_parent_control_handler, | 2253 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_SHUTDOWN, |
2235 | NULL); | 2254 | &install_parent_control_handler, |
2255 | NULL); | ||
2236 | shutdown_pipe_task = | 2256 | shutdown_pipe_task = |
2237 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 2257 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, |
2238 | pr, | 2258 | pr, |