aboutsummaryrefslogtreecommitdiff
path: root/src/util/scheduler.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-02-04 19:38:38 +0100
committerChristian Grothoff <christian@grothoff.org>2020-02-04 19:38:38 +0100
commit3039adb9578b01b3649c5c8ae5f4d6d8f8a7d51d (patch)
tree3e2db2300f3f613115c8c346e9503c6c28bedf8d /src/util/scheduler.c
parent1ca80565458244e9a9622d65bd3953fa3478372a (diff)
downloadgnunet-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.c44
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;
407static int current_lifeness; 407static int current_lifeness;
408 408
409/** 409/**
410 * Priority used currently in #GNUNET_SCHEDULER_do_work().
411 */
412static 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 ()
765unsigned int 770unsigned int
766GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p) 771GNUNET_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,
1988int 2004int
1989GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) 2005GNUNET_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,