2001-02-27
2001-02-27 03:13:37 by Martin Stjernholm <mast@lysator.liu.se>
-
8f63825c99dc7340ebe8b9265561480231500b83
(36 lines)
(+31/-5)
[
Show
| Annotate
]
Branch: 5.2
Don't starve the background tasks when the server is busy. Use a
longer sleep than 0.02, since a sleep that short will cause Pike to
busywait.
Rev: server/base_server/roxen.pike:1.638
4:
// Per Hedbor, Henrik Grubbström, Pontus Hagland, David Hedbor and others.
// ABS and suicide systems contributed freely by Francesco Chemolli
- constant cvs_version="$Id: roxen.pike,v 1.637 2001/02/27 02:54:28 per Exp $";
+ constant cvs_version="$Id: roxen.pike,v 1.638 2001/02/27 03:13:37 mast Exp $";
// Used when running threaded to find out which thread is the backend thread.
Thread.Thread backend_thread;
810: Inside #if defined(THREADS)
static Queue bg_queue = Queue();
static int bg_process_running;
+ // Use a time buffer to strike a balance if the server is busy and
+ // always have at least one busy thread: The maximum waiting time in
+ // that case is somewhere between bg_time_buffer_min and
+ // bg_time_buffer_max. If there are only short periods of time between
+ // the queue runs, the max waiting time will shrink towards the
+ // minimum.
+ static constant bg_time_buffer_max = 30;
+ static constant bg_time_buffer_min = 0.5;
+ static int bg_last_busy = 0;
+
static void bg_process_queue()
{
if (bg_process_running) return;
// Relying on the interpreter lock here.
bg_process_running = 1;
-
+
+ int maxbeats =
+ min (time() - bg_last_busy, bg_time_buffer_max) * (int) (1 / 0.04);
+
if (mixed err = catch {
while (array task = bg_queue->tryread()) {
- // Don't run if something else is already running.
- while (busy_threads > 1) sleep (0.02);
+ // Wait a while if another thread is busy already.
+ if (busy_threads > 1) {
+ for (maxbeats = max (maxbeats, (int) (bg_time_buffer_min / 0.04));
+ busy_threads > 1 && maxbeats > 0;
+ maxbeats--)
+ // Pike implementation note: If 0.02 or smaller, we'll busy wait here.
+ sleep (0.04);
+ bg_last_busy = time();
+ }
+
#if 0
werror ("background run %O (%{%O, %})\n", task[0], task[1] / 1);
#endif
-
+ if (task[0]) // Ignore things that have become destructed.
task[0] (@task[1]);
-
+
+ if (busy_threads > 1) bg_last_busy = time();
}
}) {
bg_process_running = 0;
837:
//! Enqueue a task to run in the background in a way that makes as
//! little impact as possible on the incoming requests. No matter how
//! many tasks are queued to run in the background, only one is run at
- //! a time.
+ //! a time. The tasks won't be starved, though.
//!
//! The function @[func] will be enqueued after approximately @[delay]
//! seconds, to be called with the rest of the arguments as its