aboutsummaryrefslogtreecommitdiff
path: root/src/util
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
parent1ca80565458244e9a9622d65bd3953fa3478372a (diff)
downloadgnunet-3039adb9578b01b3649c5c8ae5f4d6d8f8a7d51d.tar.gz
gnunet-3039adb9578b01b3649c5c8ae5f4d6d8f8a7d51d.zip
fix task prioritization with recent hack
Diffstat (limited to 'src/util')
-rw-r--r--src/util/.gitignore2
-rw-r--r--src/util/client.c11
-rw-r--r--src/util/scheduler.c44
-rw-r--r--src/util/service.c13
4 files changed, 43 insertions, 27 deletions
diff --git a/src/util/.gitignore b/src/util/.gitignore
index 84c13708e..05f187869 100644
--- a/src/util/.gitignore
+++ b/src/util/.gitignore
@@ -77,3 +77,5 @@ test_tun
77gnunet-timeout 77gnunet-timeout
78python27_location 78python27_location
79perf_malloc 79perf_malloc
80perf_mq
81perf_scheduler
diff --git a/src/util/client.c b/src/util/client.c
index 93442f0c6..a7b1a2a0f 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -271,14 +271,11 @@ RETRY:
271 &pos[cstate->msg_off], 271 &pos[cstate->msg_off],
272 len - cstate->msg_off); 272 len - cstate->msg_off);
273 if ( (-1 == ret) && 273 if ( (-1 == ret) &&
274 (EAGAIN == errno) ) 274 ( (EAGAIN == errno) ||
275 (EINTR == errno) ) )
275 { 276 {
276 cstate->send_task 277 /* ignore */
277 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 278 ret = 0;
278 cstate->sock,
279 &transmit_ready,
280 cstate);
281 return;
282 } 279 }
283 if (-1 == ret) 280 if (-1 == ret)
284 { 281 {
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,
diff --git a/src/util/service.c b/src/util/service.c
index 21b99547c..999a9e017 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -506,12 +506,12 @@ do_send (void *cls)
506 LOG (GNUNET_ERROR_TYPE_DEBUG, 506 LOG (GNUNET_ERROR_TYPE_DEBUG,
507 "service: sending message with type %u\n", 507 "service: sending message with type %u\n",
508 ntohs (client->msg->type)); 508 ntohs (client->msg->type));
509
510
511 client->send_task = NULL; 509 client->send_task = NULL;
512 buf = (const char *) client->msg; 510 buf = (const char *) client->msg;
513 left = ntohs (client->msg->size) - client->msg_pos; 511 left = ntohs (client->msg->size) - client->msg_pos;
514 ret = GNUNET_NETWORK_socket_send (client->sock, &buf[client->msg_pos], left); 512 ret = GNUNET_NETWORK_socket_send (client->sock,
513 &buf[client->msg_pos],
514 left);
515 GNUNET_assert (ret <= (ssize_t) left); 515 GNUNET_assert (ret <= (ssize_t) left);
516 if (0 == ret) 516 if (0 == ret)
517 { 517 {
@@ -581,11 +581,8 @@ service_mq_send (struct GNUNET_MQ_Handle *mq,
581 ntohs (msg->size)); 581 ntohs (msg->size));
582 client->msg = msg; 582 client->msg = msg;
583 client->msg_pos = 0; 583 client->msg_pos = 0;
584 client->send_task = 584 client->send_task = GNUNET_SCHEDULER_add_now (&do_send,
585 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 585 client);
586 client->sock,
587 &do_send,
588 client);
589} 586}
590 587
591 588