root/trunk/varnish-cache/bin/varnishd/mgt_pool.c @ 4599

Revision 4599, 7.9 KB (checked in by phk, 6 months ago)

Try again, this time with the right property: svn:keywordS

  • Property svn:keywords set to Id
Line 
1/*-
2 * Copyright (c) 2006 Verdens Gang AS
3 * Copyright (c) 2006-2009 Linpro AS
4 * All rights reserved.
5 *
6 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * We maintain a number of worker thread pools, to spread lock contention.
30 *
31 * Pools can be added on the fly, as a means to mitigate lock contention,
32 * but can only be removed again by a restart. (XXX: we could fix that)
33 *
34 * Two threads herd the pools, one eliminates idle threads and aggregates
35 * statistics for all the pools, the other thread creates new threads
36 * on demand, subject to various numerical constraints.
37 *
38 * The algorithm for when to create threads needs to be reactive enough
39 * to handle startup spikes, but sufficiently attenuated to not cause
40 * thread pileups.  This remains subject for improvement.
41 */
42
43#include "config.h"
44
45#include "svnid.h"
46SVNID("$Id$")
47#include <stdio.h>
48#include <string.h>
49#include <limits.h>
50#include <unistd.h>
51#include <sys/types.h>
52
53#include "cli_priv.h"
54#include "mgt.h"
55
56#include "vparam.h"
57#include "heritage.h"
58
59/*--------------------------------------------------------------------*/
60
61static void
62tweak_thread_pool_min(struct cli *cli, const struct parspec *par,
63    const char *arg)
64{
65
66        tweak_generic_uint(cli, &master.wthread_min, arg,
67            (unsigned)par->min, master.wthread_max);
68}
69
70/*--------------------------------------------------------------------
71 * This is utterly ridiculous:  POSIX does not guarantee that the
72 * minimum thread stack size is a compile time constant.
73 * XXX: "32" is a magic marker for 32bit systems.
74 */
75
76static void
77tweak_stack_size(struct cli *cli, const struct parspec *par,
78    const char *arg)
79{
80        unsigned low, u;
81        char buf[12];
82
83        low = sysconf(_SC_THREAD_STACK_MIN);
84
85        if (arg != NULL && !strcmp(arg, "32")) {
86                u = 65536;
87                if (u < low)
88                        u = low;
89                sprintf(buf, "%u", u);
90                arg = buf;
91        }
92
93        tweak_generic_uint(cli, &master.wthread_stacksize, arg,
94            low, (uint)par->max);
95}
96
97/*--------------------------------------------------------------------*/
98
99static void
100tweak_thread_pool_max(struct cli *cli, const struct parspec *par,
101    const char *arg)
102{
103
104        (void)par;
105        tweak_generic_uint(cli, &master.wthread_max, arg,
106            master.wthread_min, UINT_MAX);
107}
108
109/*--------------------------------------------------------------------*/
110
111const struct parspec WRK_parspec[] = {
112        { "thread_pools", tweak_uint, &master.wthread_pools, 1, UINT_MAX,
113                "Number of worker thread pools.\n"
114                "\n"
115                "Increasing number of worker pools decreases lock "
116                "contention.\n"
117                "\n"
118                "Too many pools waste CPU and RAM resources, and more than "
119                "one pool for each CPU is probably detrimal to performance.\n"
120                "\n"
121                "Can be increased on the fly, but decreases require a "
122                "restart to take effect.",
123                EXPERIMENTAL | DELAYED_EFFECT,
124                "2", "pools" },
125        { "thread_pool_max", tweak_thread_pool_max, NULL, 1, 0,
126                "The maximum number of worker threads in all pools combined.\n"
127                "\n"
128                "Do not set this higher than you have to, since excess "
129                "worker threads soak up RAM and CPU and generally just get "
130                "in the way of getting work done.\n",
131                EXPERIMENTAL | DELAYED_EFFECT,
132                "500", "threads" },
133        { "thread_pool_min", tweak_thread_pool_min, NULL, 2, 0,
134                "The minimum number of threads in each worker pool.\n"
135                "\n"
136                "Increasing this may help ramp up faster from low load "
137                "situations where threads have expired.\n"
138                "\n"
139                "Minimum is 2 threads.",
140                EXPERIMENTAL | DELAYED_EFFECT,
141                "5", "threads" },
142        { "thread_pool_timeout", tweak_timeout, &master.wthread_timeout, 1, 0,
143                "Thread idle threshold.\n"
144                "\n"
145                "Threads in excess of thread_pool_min, which have been idle "
146                "for at least this long are candidates for purging.\n"
147                "\n"
148                "Minimum is 1 second.",
149                EXPERIMENTAL | DELAYED_EFFECT,
150                "300", "seconds" },
151        { "thread_pool_purge_delay",
152                tweak_timeout, &master.wthread_purge_delay, 100, 0,
153                "Wait this long between purging threads.\n"
154                "\n"
155                "This controls the decay of thread pools when idle(-ish).\n"
156                "\n"
157                "Minimum is 100 milliseconds.",
158                EXPERIMENTAL | DELAYED_EFFECT,
159                "1000", "milliseconds" },
160        { "thread_pool_add_threshold",
161                tweak_uint, &master.wthread_add_threshold, 0, UINT_MAX,
162                "Overflow threshold for worker thread creation.\n"
163                "\n"
164                "Setting this too low, will result in excess worker threads, "
165                "which is generally a bad idea.\n"
166                "\n"
167                "Setting it too high results in insuffient worker threads.\n",
168                EXPERIMENTAL,
169                "2", "requests" },
170        { "thread_pool_add_delay",
171                tweak_timeout, &master.wthread_add_delay, 0, UINT_MAX,
172                "Wait at least this long between creating threads.\n"
173                "\n"
174                "Setting this too long results in insuffient worker threads.\n"
175                "\n"
176                "Setting this too short increases the risk of worker "
177                "thread pile-up.\n",
178                EXPERIMENTAL,
179                "20", "milliseconds" },
180        { "thread_pool_fail_delay",
181                tweak_timeout, &master.wthread_fail_delay, 100, UINT_MAX,
182                "Wait at least this long after a failed thread creation "
183                "before trying to create another thread.\n"
184                "\n"
185                "Failure to create a worker thread is often a sign that "
186                " the end is near, because the process is running out of "
187                "RAM resources for thread stacks.\n"
188                "This delay tries to not rush it on needlessly.\n"
189                "\n"
190                "If thread creation failures are a problem, check that "
191                "thread_pool_max is not too high.\n"
192                "\n"
193                "It may also help to increase thread_pool_timeout and "
194                "thread_pool_min, to reduce the rate at which treads are "
195                "destroyed and later recreated.\n",
196                EXPERIMENTAL,
197                "200", "milliseconds" },
198        { "thread_stats_rate",
199                tweak_uint, &master.wthread_stats_rate, 0, UINT_MAX,
200                "Worker threads accumulate statistics, and dump these into "
201                "the global stats counters if the lock is free when they "
202                "finish a request.\n"
203                "This parameters defines the maximum number of requests "
204                "a worker thread may handle, before it is forced to dump "
205                "its accumulated stats into the global counters.\n",
206                EXPERIMENTAL,
207                "10", "requests" },
208        { "overflow_max", tweak_uint, &master.overflow_max, 0, UINT_MAX,
209                "Percentage permitted overflow queue length.\n"
210                "\n"
211                "This sets the ratio of queued requests to worker threads, "
212                "above which sessions will be dropped instead of queued.\n",
213                EXPERIMENTAL,
214                "100", "%" },
215        { "rush_exponent", tweak_uint, &master.rush_exponent, 2, UINT_MAX,
216                "How many parked request we start for each completed "
217                "request on the object.\n"
218                "NB: Even with the implict delay of delivery, "
219                "this parameter controls an exponential increase in "
220                "number of worker threads.  ",
221                EXPERIMENTAL,
222                "3", "requests per request" },
223        { "thread_pool_stack",
224                tweak_stack_size, &master.wthread_stacksize, 0, UINT_MAX,
225                "Worker thread stack size.\n"
226                "On 32bit systems you may need to tweak this down to fit "
227                "many threads into the limited address space.\n",
228                EXPERIMENTAL,
229                "-1", "bytes" },
230        { NULL, NULL, NULL }
231};
Note: See TracBrowser for help on using the browser.