* @author Christian Grothoff
*/
#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_os_lib.h"
-#include "gnunet_scheduler_lib.h"
-#include "gnunet_signal_lib.h"
-#include "gnunet_time_lib.h"
+#include "gnunet_util_lib.h"
#include "disk.h"
#define LOG(kind,...) GNUNET_log_from (kind, "util-scheduler", __VA_ARGS__)
/**
* Function to use as a select() in the scheduler.
- * If NULL, we use GNUNET_NETWORK_socket_select ().
+ * If NULL, we use GNUNET_NETWORK_socket_select().
*/
static GNUNET_SCHEDULER_select scheduler_select;
* Sets the select function to use in the scheduler (scheduler_select).
*
* @param new_select new select function to use
- * @param new_select_cls closure for 'new_select'
+ * @param new_select_cls closure for @a new_select
* @return previously used select function, NULL for default
*/
void
* @param now the current time
* @param rs set of FDs ready for reading
* @param ws set of FDs ready for writing
- * @return GNUNET_YES if we can run it, GNUNET_NO if not.
+ * @return #GNUNET_YES if we can run it, #GNUNET_NO if not.
*/
static int
is_ready (struct Task *task, struct GNUNET_TIME_Absolute now,
reason |= GNUNET_SCHEDULER_REASON_WRITE_READY;
if (reason == 0)
return GNUNET_NO; /* not ready */
- reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
+ reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
task->reason = reason;
return GNUNET_YES;
}
pos = pending;
while (pos != NULL)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Checking readiness of task: %llu / %p\n",
pos->id, pos->callback_cls);
next = pos->next;
if (GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value_us >
DELAY_THRESHOLD.rel_value_us)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Task %llu took %s to be scheduled\n",
(unsigned long long) pos->id,
GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (pos->start_time), GNUNET_YES));
(pos->write_fd != -1) &&
(!GNUNET_NETWORK_fdset_test_native (ws, pos->write_fd)))
GNUNET_abort (); // added to ready in previous select loop!
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Running task: %llu / %p\n", pos->id,
pos->callback_cls);
pos->callback (pos->callback_cls, &tc);
return;
}
#endif
+
+
+/**
+ * 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.
*/
* Check if the system is still life. Trigger shutdown if we
* have tasks, but none of them give us lifeness.
*
- * @return GNUNET_OK to continue the main loop,
- * GNUNET_NO to exit
+ * @return #GNUNET_OK to continue the main loop,
+ * #GNUNET_NO to exit
*/
static int
check_lifeness ()
if ((0 == ret) && (0 == timeout.rel_value_us) && (busy_wait_warning > 16))
{
LOG (GNUNET_ERROR_TYPE_WARNING, _("Looks like we're busy waiting...\n"));
- sleep (1); /* mitigate */
+ short_wait (100); /* mitigate */
}
check_ready (rs, ws);
run_ready (rs, ws);
}
if (last_tr == tasks_run)
{
+ short_wait (1);
busy_wait_warning++;
}
else
GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio,
GNUNET_SCHEDULER_Task task, void *task_cls)
{
- return GNUNET_SCHEDULER_add_select (prio,
+ return GNUNET_SCHEDULER_add_select (prio,
GNUNET_TIME_UNIT_ZERO, NULL, NULL, task,
task_cls);
}
* to run) might get to run first. Just as with delays, clients must
* not rely on any particular order of execution between tasks
* scheduled concurrently.
- *
+ *
* The task will be run with the DEFAULT priority.
*
* @param task main function of the task
*/
#ifndef MINGW
static GNUNET_SCHEDULER_TaskIdentifier
-add_without_sets (struct GNUNET_TIME_Relative delay,
+add_without_sets (struct GNUNET_TIME_Relative delay,
enum GNUNET_SCHEDULER_Priority priority,
int rfd, int wfd,
GNUNET_SCHEDULER_Task task, void *task_cls)
GNUNET_NETWORK_fdset_destroy (rs);
return ret;
#else
- return add_without_sets (delay,
+ return add_without_sets (delay,
priority,
GNUNET_NETWORK_get_fd (rfd), -1, task,
task_cls);
return ret;
#else
GNUNET_assert (GNUNET_NETWORK_get_fd (wfd) >= 0);
- return add_without_sets (delay,
+ return add_without_sets (delay,
GNUNET_SCHEDULER_PRIORITY_DEFAULT,
-1, GNUNET_NETWORK_get_fd (wfd), task,
task_cls);
int fd;
GNUNET_DISK_internal_file_handle_ (rfd, &fd, sizeof (int));
- return add_without_sets (delay,
+ return add_without_sets (delay,
GNUNET_SCHEDULER_PRIORITY_DEFAULT,
fd, -1, task, task_cls);
GNUNET_DISK_internal_file_handle_ (wfd, &fd, sizeof (int));
GNUNET_assert (fd >= 0);
- return add_without_sets (delay,
+ return add_without_sets (delay,
GNUNET_SCHEDULER_PRIORITY_DEFAULT,
-1, fd, task, task_cls);