2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 23:25:38 +00:00

3131. [func] Improve scalability by allocating one zone task

per 100 zones at startup time, rather than using a
			fixed-size task table. [RT #24406]
This commit is contained in:
Evan Hunt
2011-07-06 01:36:32 +00:00
parent 007eafcd07
commit 42cf2ff7ba
17 changed files with 799 additions and 415 deletions

View File

@@ -1,3 +1,7 @@
3131. [func] Improve scalability by allocating one zone task
per 100 zones at startup time, rather than using a
fixed-size task table. [RT #24406]
3130. [func] Support alternate methods for managing a dynamic 3130. [func] Support alternate methods for managing a dynamic
zone's serial number. Two methods are currently zone's serial number. Two methods are currently
defined using serial-update-method, "increment" defined using serial-update-method, "increment"

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: server.c,v 1.612 2011/06/17 07:05:01 each Exp $ */ /* $Id: server.c,v 1.613 2011/07/06 01:36:31 each Exp $ */
/*! \file */ /*! \file */
@@ -204,12 +204,14 @@ struct zonelistentry {
/*% /*%
* Configuration context to retain for each view that allows * Configuration context to retain for each view that allows
* new zones to be added at runtime * new zones to be added at runtime.
*/ */
struct cfg_context { struct cfg_context {
isc_mem_t * mctx; isc_mem_t * mctx;
cfg_obj_t * config;
cfg_parser_t * parser; cfg_parser_t * parser;
cfg_obj_t * config;
cfg_parser_t * nzparser;
cfg_obj_t * nzconfig;
cfg_aclconfctx_t * actx; cfg_aclconfctx_t * actx;
}; };
@@ -1545,8 +1547,7 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
* global defaults in 'config' used exclusively. * global defaults in 'config' used exclusively.
*/ */
static isc_result_t static isc_result_t
configure_view(dns_view_t *view, cfg_parser_t* parser, configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
cfg_obj_t *config, cfg_obj_t *vconfig,
ns_cachelist_t *cachelist, const cfg_obj_t *bindkeys, ns_cachelist_t *cachelist, const cfg_obj_t *bindkeys,
isc_mem_t *mctx, cfg_aclconfctx_t *actx, isc_mem_t *mctx, cfg_aclconfctx_t *actx,
isc_boolean_t need_hints) isc_boolean_t need_hints)
@@ -1601,10 +1602,9 @@ configure_view(dns_view_t *view, cfg_parser_t* parser,
isc_boolean_t auto_root = ISC_FALSE; isc_boolean_t auto_root = ISC_FALSE;
ns_cache_t *nsc; ns_cache_t *nsc;
isc_boolean_t zero_no_soattl; isc_boolean_t zero_no_soattl;
cfg_parser_t *newzones_parser = NULL;
cfg_obj_t *nzfconf = NULL;
dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL; dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL;
unsigned int query_timeout; unsigned int query_timeout;
struct cfg_context *nzctx;
REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(DNS_VIEW_VALID(view));
@@ -1710,6 +1710,10 @@ configure_view(dns_view_t *view, cfg_parser_t* parser,
(void)cfg_map_get(voptions, "zone", &zonelist); (void)cfg_map_get(voptions, "zone", &zonelist);
else else
(void)cfg_map_get(config, "zone", &zonelist); (void)cfg_map_get(config, "zone", &zonelist);
/*
* Load zone configuration
*/
for (element = cfg_list_first(zonelist); for (element = cfg_list_first(zonelist);
element != NULL; element != NULL;
element = cfg_list_next(element)) element = cfg_list_next(element))
@@ -1719,58 +1723,29 @@ configure_view(dns_view_t *view, cfg_parser_t* parser,
actx, ISC_FALSE)); actx, ISC_FALSE));
} }
/*
* Are we allowing zones to be added and deleted dynamically?
*/
obj = NULL;
result = ns_config_get(maps, "allow-new-zones", &obj);
if (result == ISC_R_SUCCESS) {
isc_boolean_t allow = cfg_obj_asboolean(obj);
struct cfg_context *cfg = NULL;
if (allow) {
cfg = isc_mem_get(view->mctx, sizeof(*cfg));
if (cfg == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
memset(cfg, 0, sizeof(*cfg));
isc_mem_attach(view->mctx, &cfg->mctx);
if (config != NULL)
cfg_obj_attach(config, &cfg->config);
cfg_parser_attach(parser, &cfg->parser);
cfg_aclconfctx_attach(actx, &cfg->actx);
}
dns_view_setnewzones(view, allow, cfg, newzone_cfgctx_destroy);
}
/* /*
* If we're allowing added zones, then load zone configuration * If we're allowing added zones, then load zone configuration
* from the newzone file for zones that were added during previous * from the newzone file for zones that were added during previous
* runs. * runs.
*/ */
if (view->new_zone_file != NULL) { nzctx = view->new_zone_config;
if (nzctx != NULL && nzctx->nzconfig != NULL) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO, NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"loading additional zones for view '%s'", "loading additional zones for view '%s'",
view->name); view->name);
CHECK(cfg_parser_create(view->mctx, ns_g_lctx, zonelist = NULL;
&newzones_parser)); cfg_map_get(nzctx->nzconfig, "zone", &zonelist);
result = cfg_parse_file(newzones_parser, view->new_zone_file,
&cfg_type_newzones, &nzfconf); for (element = cfg_list_first(zonelist);
if (result == ISC_R_SUCCESS) { element != NULL;
zonelist = NULL; element = cfg_list_next(element))
cfg_map_get(nzfconf, "zone", &zonelist); {
for (element = cfg_list_first(zonelist); const cfg_obj_t *zconfig = cfg_listelt_value(element);
element != NULL; CHECK(configure_zone(config, zconfig, vconfig,
element = cfg_list_next(element)) mctx, view, actx,
{ ISC_TRUE));
const cfg_obj_t *zconfig =
cfg_listelt_value(element);
CHECK(configure_zone(config, zconfig, vconfig,
mctx, view, actx,
ISC_TRUE));
}
} }
} }
@@ -2904,8 +2879,8 @@ configure_view(dns_view_t *view, cfg_parser_t* parser,
if (result == ISC_R_SUCCESS) if (result == ISC_R_SUCCESS)
cfg_map_get(obj, "zone", &zonelist); cfg_map_get(obj, "zone", &zonelist);
} }
if (zonelist != NULL) {
if (zonelist != NULL) {
for (element = cfg_list_first(zonelist); for (element = cfg_list_first(zonelist);
element != NULL; element != NULL;
element = cfg_list_next(element)) { element = cfg_list_next(element)) {
@@ -2947,12 +2922,6 @@ configure_view(dns_view_t *view, cfg_parser_t* parser,
if (cache != NULL) if (cache != NULL)
dns_cache_detach(&cache); dns_cache_detach(&cache);
if (newzones_parser != NULL) {
if (nzfconf != NULL)
cfg_obj_destroy(newzones_parser, &nzfconf);
cfg_parser_destroy(&newzones_parser);
}
return (result); return (result);
} }
@@ -3157,6 +3126,61 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin,
return (result); return (result);
} }
static isc_result_t
get_viewinfo(const cfg_obj_t *vconfig, const char **namep,
dns_rdataclass_t *classp)
{
isc_result_t result = ISC_R_SUCCESS;
const char *viewname;
dns_rdataclass_t viewclass;
REQUIRE(namep != NULL && *namep == NULL);
REQUIRE(classp != NULL);
if (vconfig != NULL) {
const cfg_obj_t *classobj = NULL;
viewname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name"));
classobj = cfg_tuple_get(vconfig, "class");
result = ns_config_getclass(classobj, dns_rdataclass_in,
&viewclass);
} else {
viewname = "_default";
viewclass = dns_rdataclass_in;
}
*namep = viewname;
*classp = viewclass;
return (result);
}
/*
* Find a view based on its configuration info and attach to it.
*
* If 'vconfig' is NULL, attach to the default view.
*/
static isc_result_t
find_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
dns_view_t **viewp)
{
isc_result_t result;
const char *viewname = NULL;
dns_rdataclass_t viewclass;
dns_view_t *view = NULL;
result = get_viewinfo(vconfig, &viewname, &viewclass);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_viewlist_find(viewlist, viewname, viewclass, &view);
if (result != ISC_R_SUCCESS)
return (result);
*viewp = view;
return (ISC_R_SUCCESS);
}
/* /*
* Create a new view and add it to the list. * Create a new view and add it to the list.
* *
@@ -3169,22 +3193,14 @@ create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
dns_view_t **viewp) dns_view_t **viewp)
{ {
isc_result_t result; isc_result_t result;
const char *viewname; const char *viewname = NULL;
dns_rdataclass_t viewclass; dns_rdataclass_t viewclass;
dns_view_t *view = NULL; dns_view_t *view = NULL;
if (vconfig != NULL) { result = get_viewinfo(vconfig, &viewname, &viewclass);
const cfg_obj_t *classobj = NULL; if (result != ISC_R_SUCCESS)
return (result);
viewname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name"));
classobj = cfg_tuple_get(vconfig, "class");
result = ns_config_getclass(classobj, dns_rdataclass_in,
&viewclass);
INSIST(result == ISC_R_SUCCESS);
} else {
viewname = "_default";
viewclass = dns_rdataclass_in;
}
result = dns_viewlist_find(viewlist, viewname, viewclass, &view); result = dns_viewlist_find(viewlist, viewname, viewclass, &view);
if (result == ISC_R_SUCCESS) if (result == ISC_R_SUCCESS)
return (ISC_R_EXISTS); return (ISC_R_EXISTS);
@@ -4175,6 +4191,95 @@ configure_session_key(const cfg_obj_t **maps, ns_server_t *server,
return (result); return (result);
} }
static isc_result_t
setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
cfg_parser_t *parser, cfg_aclconfctx_t *actx)
{
isc_result_t result = ISC_R_SUCCESS;
isc_boolean_t allow = ISC_FALSE;
struct cfg_context *nzcfg = NULL;
cfg_parser_t *nzparser = NULL;
cfg_obj_t *nzconfig = NULL;
const cfg_obj_t *maps[4];
const cfg_obj_t *options = NULL, *voptions = NULL;
const cfg_obj_t *nz = NULL;
int i = 0;
REQUIRE (config != NULL);
if (vconfig != NULL)
voptions = cfg_tuple_get(vconfig, "options");
if (voptions != NULL)
maps[i++] = voptions;
result = cfg_map_get(config, "options", &options);
if (result == ISC_R_SUCCESS)
maps[i++] = options;
maps[i++] = ns_g_defaults;
maps[i] = NULL;
result = ns_config_get(maps, "allow-new-zones", &nz);
if (result == ISC_R_SUCCESS)
allow = cfg_obj_asboolean(nz);
if (!allow) {
dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
return (ISC_R_SUCCESS);
}
nzcfg = isc_mem_get(view->mctx, sizeof(*nzcfg));
if (nzcfg == NULL) {
dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
return (ISC_R_NOMEMORY);
}
dns_view_setnewzones(view, allow, nzcfg, newzone_cfgctx_destroy);
memset(nzcfg, 0, sizeof(*nzcfg));
isc_mem_attach(view->mctx, &nzcfg->mctx);
cfg_obj_attach(config, &nzcfg->config);
cfg_parser_attach(parser, &nzcfg->parser);
cfg_aclconfctx_attach(actx, &nzcfg->actx);
/*
* Attempt to create a parser and parse the newzones
* file. If successful, preserve both; otherwise leave
* them NULL.
*/
result = cfg_parser_create(view->mctx, ns_g_lctx, &nzparser);
if (result == ISC_R_SUCCESS)
result = cfg_parse_file(nzparser, view->new_zone_file,
&cfg_type_newzones, &nzconfig);
if (result == ISC_R_SUCCESS) {
cfg_parser_attach(nzparser, &nzcfg->nzparser);
cfg_obj_attach(nzconfig, &nzcfg->nzconfig);
}
if (nzparser != NULL) {
if (nzconfig != NULL)
cfg_obj_destroy(nzparser, &nzconfig);
cfg_parser_destroy(&nzparser);
}
return (ISC_R_SUCCESS);
}
static int
count_zones(const cfg_obj_t *conf) {
const cfg_obj_t *zonelist = NULL;
const cfg_listelt_t *element;
int n = 0;
REQUIRE(conf != NULL);
cfg_map_get(conf, "zone", &zonelist);
for (element = cfg_list_first(zonelist);
element != NULL;
element = cfg_list_next(element))
n++;
return (n);
}
static isc_result_t static isc_result_t
load_configuration(const char *filename, ns_server_t *server, load_configuration(const char *filename, ns_server_t *server,
isc_boolean_t first_time) isc_boolean_t first_time)
@@ -4206,6 +4311,8 @@ load_configuration(const char *filename, ns_server_t *server,
ns_cachelist_t cachelist, tmpcachelist; ns_cachelist_t cachelist, tmpcachelist;
unsigned int maxsocks; unsigned int maxsocks;
ns_cache_t *nsc; ns_cache_t *nsc;
struct cfg_context *nzctx;
int num_zones = 0;
ISC_LIST_INIT(viewlist); ISC_LIST_INIT(viewlist);
ISC_LIST_INIT(builtin_viewlist); ISC_LIST_INIT(builtin_viewlist);
@@ -4633,25 +4740,87 @@ load_configuration(const char *filename, ns_server_t *server,
*/ */
(void)configure_session_key(maps, server, ns_g_mctx); (void)configure_session_key(maps, server, ns_g_mctx);
/*
* Configure and freeze all explicit views. Explicit
* views that have zones were already created at parsing
* time, but views with no zones must be created here.
*/
views = NULL; views = NULL;
(void)cfg_map_get(config, "view", &views); (void)cfg_map_get(config, "view", &views);
/*
* Create the views and count all the configured zones in
* order to correctly size the zone manager's task table.
* (We only count zones for configured views; the built-in
* "bind" view can be ignored as it only adds a negligible
* number of zones.)
*
* If we're allowing new zones, we need to be able to find the
* new zone file and count those as well. So we setup the new
* zone configuration context, but otherwise view configuration
* waits until after the zone manager's task list has been sized.
*/
for (element = cfg_list_first(views); for (element = cfg_list_first(views);
element != NULL; element != NULL;
element = cfg_list_next(element)) element = cfg_list_next(element))
{ {
cfg_obj_t *vconfig = cfg_listelt_value(element); cfg_obj_t *vconfig = cfg_listelt_value(element);
const cfg_obj_t *voptions = cfg_tuple_get(vconfig, "options");
view = NULL; view = NULL;
CHECK(create_view(vconfig, &viewlist, &view)); CHECK(create_view(vconfig, &viewlist, &view));
INSIST(view != NULL); INSIST(view != NULL);
CHECK(configure_view(view, conf_parser, config, vconfig,
&cachelist, bindkeys, num_zones += count_zones(voptions);
ns_g_mctx, ns_g_aclconfctx, ISC_TRUE)); CHECK(setup_newzones(view, config, vconfig, conf_parser,
ns_g_aclconfctx));
nzctx = view->new_zone_config;
if (nzctx != NULL && nzctx->nzconfig != NULL)
num_zones += count_zones(nzctx->nzconfig);
dns_view_detach(&view);
}
/*
* If there were no explicit views then we do the default
* view here.
*/
if (views == NULL) {
CHECK(create_view(NULL, &viewlist, &view));
INSIST(view != NULL);
num_zones = count_zones(config);
CHECK(setup_newzones(view, config, NULL, conf_parser,
ns_g_aclconfctx));
nzctx = view->new_zone_config;
if (nzctx != NULL && nzctx->nzconfig != NULL)
num_zones += count_zones(nzctx->nzconfig);
dns_view_detach(&view);
}
/*
* Zones have been counted; set the zone manager task pool size.
*/
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"sizing zone task pool based on %d zones", num_zones);
CHECK(dns_zonemgr_setsize(ns_g_server->zonemgr, num_zones));
/*
* Configure and freeze all explicit views. Explicit
* views that have zones were already created at parsing
* time, but views with no zones must be created here.
*/
for (element = cfg_list_first(views);
element != NULL;
element = cfg_list_next(element))
{
cfg_obj_t *vconfig = cfg_listelt_value(element);
view = NULL;
CHECK(find_view(vconfig, &viewlist, &view));
CHECK(configure_view(view, config, vconfig,
&cachelist, bindkeys, ns_g_mctx,
ns_g_aclconfctx, ISC_TRUE));
dns_view_freeze(view); dns_view_freeze(view);
dns_view_detach(&view); dns_view_detach(&view);
} }
@@ -4661,14 +4830,9 @@ load_configuration(const char *filename, ns_server_t *server,
* were no explicit views. * were no explicit views.
*/ */
if (views == NULL) { if (views == NULL) {
/* view = NULL;
* No explicit views; there ought to be a default view. CHECK(find_view(NULL, &viewlist, &view));
* There may already be one created as a side effect CHECK(configure_view(view, config, NULL,
* of zone statements, or we may have to create one.
* In either case, we need to configure and freeze it.
*/
CHECK(create_view(NULL, &viewlist, &view));
CHECK(configure_view(view, conf_parser, config, NULL,
&cachelist, bindkeys, &cachelist, bindkeys,
ns_g_mctx, ns_g_aclconfctx, ISC_TRUE)); ns_g_mctx, ns_g_aclconfctx, ISC_TRUE));
dns_view_freeze(view); dns_view_freeze(view);
@@ -4688,7 +4852,7 @@ load_configuration(const char *filename, ns_server_t *server,
cfg_obj_t *vconfig = cfg_listelt_value(element); cfg_obj_t *vconfig = cfg_listelt_value(element);
CHECK(create_view(vconfig, &builtin_viewlist, &view)); CHECK(create_view(vconfig, &builtin_viewlist, &view));
CHECK(configure_view(view, conf_parser, config, vconfig, CHECK(configure_view(view, config, vconfig,
&cachelist, bindkeys, &cachelist, bindkeys,
ns_g_mctx, ns_g_aclconfctx, ISC_FALSE)); ns_g_mctx, ns_g_aclconfctx, ISC_FALSE));
dns_view_freeze(view); dns_view_freeze(view);
@@ -5311,6 +5475,8 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
CHECKFATAL(dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr, CHECKFATAL(dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr,
ns_g_socketmgr, &server->zonemgr), ns_g_socketmgr, &server->zonemgr),
"dns_zonemgr_create"); "dns_zonemgr_create");
CHECKFATAL(dns_zonemgr_setsize(server->zonemgr, 1000),
"dns_zonemgr_setsize");
server->statsfile = isc_mem_strdup(server->mctx, "named.stats"); server->statsfile = isc_mem_strdup(server->mctx, "named.stats");
CHECKFATAL(server->statsfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, CHECKFATAL(server->statsfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
@@ -5420,7 +5586,8 @@ ns_server_destroy(ns_server_t **serverp) {
if (server->server_id != NULL) if (server->server_id != NULL)
isc_mem_free(server->mctx, server->server_id); isc_mem_free(server->mctx, server->server_id);
dns_zonemgr_detach(&server->zonemgr); if (server->zonemgr != NULL)
dns_zonemgr_detach(&server->zonemgr);
if (server->tkeyctx != NULL) if (server->tkeyctx != NULL)
dns_tkeyctx_destroy(&server->tkeyctx); dns_tkeyctx_destroy(&server->tkeyctx);
@@ -7589,6 +7756,11 @@ newzone_cfgctx_destroy(void **cfgp) {
cfg_obj_destroy(cfg->parser, &cfg->config); cfg_obj_destroy(cfg->parser, &cfg->config);
cfg_parser_destroy(&cfg->parser); cfg_parser_destroy(&cfg->parser);
} }
if (cfg->nzparser != NULL) {
if (cfg->nzconfig != NULL)
cfg_obj_destroy(cfg->nzparser, &cfg->nzconfig);
cfg_parser_destroy(&cfg->nzparser);
}
isc_mem_putanddetach(&cfg->mctx, cfg, sizeof(*cfg)); isc_mem_putanddetach(&cfg->mctx, cfg, sizeof(*cfg));
*cfgp = NULL; *cfgp = NULL;

531
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
esyscmd([sed "s/^/# /" COPYRIGHT])dnl esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl AC_DIVERT_POP()dnl
AC_REVISION($Revision: 1.526 $) AC_REVISION($Revision: 1.527 $)
AC_INIT(lib/dns/name.c) AC_INIT(lib/dns/name.c)
AC_PREREQ(2.59) AC_PREREQ(2.59)
@@ -3508,6 +3508,7 @@ AC_CONFIG_FILES([
lib/isc/include/Makefile lib/isc/include/Makefile
lib/isc/include/isc/Makefile lib/isc/include/isc/Makefile
lib/isc/include/isc/platform.h lib/isc/include/isc/platform.h
lib/isc/tests/Makefile
lib/isc/nls/Makefile lib/isc/nls/Makefile
lib/isc/unix/Makefile lib/isc/unix/Makefile
lib/isc/unix/include/Makefile lib/isc/unix/include/Makefile

View File

@@ -3,3 +3,4 @@ Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9 prop: test-suite = bind9
tp: dns tp: dns
tp: isc

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: zone.h,v 1.190 2011/07/01 02:25:48 marka Exp $ */ /* $Id: zone.h,v 1.191 2011/07/06 01:36:32 each Exp $ */
#ifndef DNS_ZONE_H #ifndef DNS_ZONE_H
#define DNS_ZONE_H 1 #define DNS_ZONE_H 1
@@ -1388,7 +1388,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
dns_zonemgr_t **zmgrp); dns_zonemgr_t **zmgrp);
/*%< /*%<
* Create a zone manager. * Create a zone manager. Note: the zone manager will not be able to
* manage any zones until dns_zonemgr_setsize() has been run.
* *
* Requires: * Requires:
*\li 'mctx' to be a valid memory context. *\li 'mctx' to be a valid memory context.
@@ -1397,6 +1398,18 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
*\li 'zmgrp' to point to a NULL pointer. *\li 'zmgrp' to point to a NULL pointer.
*/ */
isc_result_t
dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones);
/*%<
* Set the size of the zone manager task pool. This must be run
* before zmgr can be used for managing zones. Currently, it can only
* be run once; the task pool cannot be resized.
*
* Requires:
*\li zmgr is a valid zone manager.
*\li zmgr->zonetasks has been initialized.
*/
isc_result_t isc_result_t
dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone); dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
/*%< /*%<

View File

@@ -12,7 +12,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.4 2011/07/01 02:25:48 marka Exp $ # $Id: Makefile.in,v 1.5 2011/07/06 01:36:32 each Exp $
srcdir = @srcdir@ srcdir = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
@@ -37,10 +37,12 @@ DNSDEPLIBS = ../libdns.@A@
LIBS = @LIBS@ @ATFLIBS@ LIBS = @LIBS@ @ATFLIBS@
OBJS = dnstest.@O@ OBJS = dnstest.@O@
SRCS = dnstest.c master_test.c time_test.c update_test.c SRCS = dnstest.c master_test.c time_test.c update_test.c \
zonemgr_test.c
SUBDIRS = SUBDIRS =
TARGETS = master_test@EXEEXT@ time_test@EXEEXT@ update_test@EXEEXT@ TARGETS = master_test@EXEEXT@ time_test@EXEEXT@ update_test@EXEEXT@ \
zonemgr_test@EXEEXT@
@BIND9_MAKE_RULES@ @BIND9_MAKE_RULES@
@@ -59,5 +61,10 @@ update_test@EXEEXT@: update_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
update_test.@O@ dnstest.@O@ ${DNSLIBS} \ update_test.@O@ dnstest.@O@ ${DNSLIBS} \
${ISCLIBS} ${LIBS} ${ISCLIBS} ${LIBS}
zonemgr_test@EXEEXT@: zonemgr_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
zonemgr_test.@O@ dnstest.@O@ ${DNSLIBS} \
${ISCLIBS} ${LIBS}
clean distclean:: clean distclean::
rm -f ${TARGETS} rm -f ${TARGETS}

View File

@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: dnstest.c,v 1.3 2011/03/01 23:48:07 tbox Exp $ */ /* $Id: dnstest.c,v 1.4 2011/07/06 01:36:32 each Exp $ */
/*! \file */ /*! \file */
@@ -25,7 +25,11 @@
#include <isc/entropy.h> #include <isc/entropy.h>
#include <isc/hash.h> #include <isc/hash.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/os.h>
#include <isc/string.h> #include <isc/string.h>
#include <isc/socket.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h> #include <isc/util.h>
#include <dns/log.h> #include <dns/log.h>
@@ -39,6 +43,10 @@
isc_mem_t *mctx = NULL; isc_mem_t *mctx = NULL;
isc_entropy_t *ectx = NULL; isc_entropy_t *ectx = NULL;
isc_log_t *lctx = NULL; isc_log_t *lctx = NULL;
isc_taskmgr_t *taskmgr = NULL;
isc_timermgr_t *timermgr = NULL;
isc_socketmgr_t *socketmgr = NULL;
int ncpus;
static isc_boolean_t hash_active = ISC_FALSE, dst_active = ISC_FALSE; static isc_boolean_t hash_active = ISC_FALSE, dst_active = ISC_FALSE;
@@ -57,8 +65,37 @@ static isc_logcategory_t categories[] = {
{ NULL, 0 } { NULL, 0 }
}; };
static void
cleanup_managers() {
if (socketmgr != NULL)
isc_socketmgr_destroy(&socketmgr);
if (taskmgr != NULL)
isc_taskmgr_destroy(&taskmgr);
if (timermgr != NULL)
isc_timermgr_destroy(&timermgr);
}
static isc_result_t
create_managers() {
isc_result_t result;
#ifdef ISC_PLATFORM_USETHREADS
ncpus = isc_os_ncpus();
#else
ncpus = 1;
#endif
CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
CHECK(isc_timermgr_create(mctx, &timermgr));
CHECK(isc_socketmgr_create(mctx, &socketmgr));
return (ISC_R_SUCCESS);
cleanup:
cleanup_managers();
return (result);
}
isc_result_t isc_result_t
dns_test_begin(FILE *logfile) { dns_test_begin(FILE *logfile, isc_boolean_t start_managers) {
isc_result_t result; isc_result_t result;
isc_mem_debugging |= ISC_MEM_DEBUGRECORD; isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
@@ -94,6 +131,9 @@ dns_test_begin(FILE *logfile) {
dns_result_register(); dns_result_register();
if (start_managers)
CHECK(create_managers());
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
cleanup: cleanup:
@@ -115,6 +155,9 @@ dns_test_end() {
} }
if (ectx != NULL) if (ectx != NULL)
isc_entropy_detach(&ectx); isc_entropy_detach(&ectx);
cleanup_managers();
if (mctx != NULL) if (mctx != NULL)
isc_mem_destroy(&mctx); isc_mem_destroy(&mctx);
} }

View File

@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: dnstest.h,v 1.2 2011/02/26 02:26:11 each Exp $ */ /* $Id: dnstest.h,v 1.3 2011/07/06 01:36:32 each Exp $ */
/*! \file */ /*! \file */
@@ -42,9 +42,14 @@
extern isc_mem_t *mctx; extern isc_mem_t *mctx;
extern isc_entropy_t *ectx; extern isc_entropy_t *ectx;
extern isc_log_t *lctx; extern isc_log_t *lctx;
isc_taskmgr_t *taskmgr;
isc_timermgr_t *timermgr;
isc_socketmgr_t *socketmgr;
int ncpus;
isc_result_t isc_result_t
dns_test_begin(FILE *logfile); dns_test_begin(FILE *logfile, isc_boolean_t create_managers);
void void
dns_test_end(void); dns_test_end(void);

View File

@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: master_test.c,v 1.3 2011/03/01 23:48:07 tbox Exp $ */ /* $Id: master_test.c,v 1.4 2011/07/06 01:36:32 each Exp $ */
/*! \file */ /*! \file */
@@ -114,7 +114,7 @@ ATF_TC_BODY(master_load, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master1.data"); result = test_master("testdata/master/master1.data");
@@ -136,7 +136,7 @@ ATF_TC_BODY(master_unexpected, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master2.data"); result = test_master("testdata/master/master2.data");
@@ -158,7 +158,7 @@ ATF_TC_BODY(master_noowner, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master3.data"); result = test_master("testdata/master/master3.data");
@@ -181,7 +181,7 @@ ATF_TC_BODY(master_nottl, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master4.data"); result = test_master("testdata/master/master4.data");
@@ -203,7 +203,7 @@ ATF_TC_BODY(master_badclass, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master5.data"); result = test_master("testdata/master/master5.data");
@@ -223,7 +223,7 @@ ATF_TC_BODY(master_dnskey, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master6.data"); result = test_master("testdata/master/master6.data");
@@ -244,7 +244,7 @@ ATF_TC_BODY(master_dnsnokey, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master7.data"); result = test_master("testdata/master/master7.data");
@@ -264,7 +264,7 @@ ATF_TC_BODY(master_include, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master8.data"); result = test_master("testdata/master/master8.data");
@@ -284,7 +284,7 @@ ATF_TC_BODY(master_includefail, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master9.data"); result = test_master("testdata/master/master9.data");
@@ -305,7 +305,7 @@ ATF_TC_BODY(master_blanklines, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master10.data"); result = test_master("testdata/master/master10.data");
@@ -325,7 +325,7 @@ ATF_TC_BODY(master_leadingzero, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = test_master("testdata/master/master11.data"); result = test_master("testdata/master/master11.data");

View File

@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: time_test.c,v 1.2 2011/03/09 07:22:32 marka Exp $ */ /* $Id: time_test.c,v 1.3 2011/07/06 01:36:32 each Exp $ */
/*! \file */ /*! \file */
@@ -49,7 +49,7 @@ ATF_TC_BODY(epoch_minus_one, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
isc_buffer_init(&target, buf, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf));
@@ -77,7 +77,7 @@ ATF_TC_BODY(epoch, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
isc_buffer_init(&target, buf, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf));
@@ -105,7 +105,7 @@ ATF_TC_BODY(half_maxint, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
isc_buffer_init(&target, buf, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf));
@@ -133,7 +133,7 @@ ATF_TC_BODY(half_plus_one, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
isc_buffer_init(&target, buf, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf));
@@ -161,7 +161,7 @@ ATF_TC_BODY(fifty_before, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
isc_buffer_init(&target, buf, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf));
@@ -189,7 +189,7 @@ ATF_TC_BODY(some_ago, tc) {
UNUSED(tc); UNUSED(tc);
result = dns_test_begin(NULL); result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
isc_buffer_init(&target, buf, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf));

View File

@@ -910,6 +910,7 @@ dns_zonemgr_releasezone
dns_zonemgr_resumexfrs dns_zonemgr_resumexfrs
dns_zonemgr_setiolimit dns_zonemgr_setiolimit
dns_zonemgr_setserialqueryrate dns_zonemgr_setserialqueryrate
dns_zonemgr_setsize
dns_zonemgr_settransfersin dns_zonemgr_settransfersin
dns_zonemgr_settransfersperns dns_zonemgr_settransfersperns
dns_zonemgr_shutdown dns_zonemgr_shutdown

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: zone.c,v 1.616 2011/07/01 02:25:48 marka Exp $ */ /* $Id: zone.c,v 1.617 2011/07/06 01:36:31 each Exp $ */
/*! \file */ /*! \file */
@@ -12681,16 +12681,10 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
zmgr->transfersin = 10; zmgr->transfersin = 10;
zmgr->transfersperns = 2; zmgr->transfersperns = 2;
/* Create the zone task pool. */
result = isc_taskpool_create(taskmgr, mctx,
8 /* XXX */, 2, &zmgr->zonetasks);
if (result != ISC_R_SUCCESS)
goto free_rwlock;
/* Create a single task for queueing of SOA queries. */ /* Create a single task for queueing of SOA queries. */
result = isc_task_create(taskmgr, 1, &zmgr->task); result = isc_task_create(taskmgr, 1, &zmgr->task);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto free_taskpool; goto free_rwlock;
isc_task_setname(zmgr->task, "zmgr", zmgr); isc_task_setname(zmgr->task, "zmgr", zmgr);
result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
&zmgr->rl); &zmgr->rl);
@@ -12724,8 +12718,6 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
isc_ratelimiter_detach(&zmgr->rl); isc_ratelimiter_detach(&zmgr->rl);
free_task: free_task:
isc_task_detach(&zmgr->task); isc_task_detach(&zmgr->task);
free_taskpool:
isc_taskpool_destroy(&zmgr->zonetasks);
free_rwlock: free_rwlock:
isc_rwlock_destroy(&zmgr->rwlock); isc_rwlock_destroy(&zmgr->rwlock);
free_mem: free_mem:
@@ -12741,16 +12733,16 @@ dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(DNS_ZONEMGR_VALID(zmgr)); REQUIRE(DNS_ZONEMGR_VALID(zmgr));
if (zmgr->zonetasks == NULL)
return (ISC_R_FAILURE);
RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
LOCK_ZONE(zone); LOCK_ZONE(zone);
REQUIRE(zone->task == NULL); REQUIRE(zone->task == NULL);
REQUIRE(zone->timer == NULL); REQUIRE(zone->timer == NULL);
REQUIRE(zone->zmgr == NULL); REQUIRE(zone->zmgr == NULL);
isc_taskpool_gettask(zmgr->zonetasks, isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
dns_name_hash(dns_zone_getorigin(zone),
ISC_FALSE),
&zone->task);
/* /*
* Set the task name. The tag will arbitrarily point to one * Set the task name. The tag will arbitrarily point to one
@@ -12843,6 +12835,7 @@ dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
if (free_now) if (free_now)
zonemgr_free(zmgr); zonemgr_free(zmgr);
*zmgrp = NULL;
} }
isc_result_t isc_result_t
@@ -12894,6 +12887,35 @@ dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
isc_taskpool_destroy(&zmgr->zonetasks); isc_taskpool_destroy(&zmgr->zonetasks);
} }
isc_result_t
dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
isc_result_t result;
int ntasks = num_zones / 100;
isc_taskpool_t *pool = NULL;
REQUIRE(DNS_ZONEMGR_VALID(zmgr));
/*
* For anything fewer than 1000 zones we use 10 tasks in
* the task pool. More than that, and we'll scale at one
* task per 100 zones.
*/
if (ntasks < 10)
ntasks = 10;
/* Create or resize the zone task pool. */
if (zmgr->zonetasks == NULL)
result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
ntasks, 2, &pool);
else
result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
if (result == ISC_R_SUCCESS)
zmgr->zonetasks = pool;
return (result);
}
static void static void
zonemgr_free(dns_zonemgr_t *zmgr) { zonemgr_free(dns_zonemgr_t *zmgr) {
isc_mem_t *mctx; isc_mem_t *mctx;

View File

@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.109 2010/06/09 01:43:09 marka Exp $ # $Id: Makefile.in,v 1.110 2011/07/06 01:36:32 each Exp $
srcdir = @srcdir@ srcdir = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
@@ -88,6 +88,7 @@ LIBS = @LIBS@
.NO_PARALLEL: .NO_PARALLEL:
SUBDIRS = include unix nls @ISC_THREAD_DIR@ @ISC_ARCH_DIR@ SUBDIRS = include unix nls @ISC_THREAD_DIR@ @ISC_ARCH_DIR@
TARGETS = timestamp TARGETS = timestamp
TESTDIRS = @UNITTESTS@
@BIND9_MAKE_RULES@ @BIND9_MAKE_RULES@

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: taskpool.h,v 1.15 2007/06/19 23:47:18 tbox Exp $ */ /* $Id: taskpool.h,v 1.16 2011/07/06 01:36:32 each Exp $ */
#ifndef ISC_TASKPOOL_H #ifndef ISC_TASKPOOL_H
#define ISC_TASKPOOL_H 1 #define ISC_TASKPOOL_H 1
@@ -84,10 +84,49 @@ isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx,
*/ */
void void
isc_taskpool_gettask(isc_taskpool_t *pool, unsigned int hash, isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp);
isc_task_t **targetp);
/*%< /*%<
* Attach to the task corresponding to the hash value "hash". * Attach to a task from the pool. Currently the next task is chosen
* from the pool at random. (This may be changed in the future to
* something that guaratees balance.)
*/
int
isc_taskpool_size(isc_taskpool_t *pool);
/*%<
* Returns the number of tasks in the task pool 'pool'.
*/
isc_result_t
isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size,
isc_taskpool_t **targetp);
/*%<
* If 'size' is larger than the number of tasks in the pool pointed to by
* 'sourcep', then a new taskpool of size 'size' is allocated, the existing
* tasks from are moved into it, additional tasks are created to bring the
* total number up to 'size', and the resulting pool is attached to
* 'targetp'.
*
* If 'size' is less than or equal to the tasks in pool 'source', then
* 'sourcep' is attached to 'targetp' without any other action being taken.
*
* In either case, 'sourcep' is detached.
*
* Requires:
*
* \li 'sourcep' is not NULL and '*source' is not NULL
* \li 'targetp' is not NULL and '*source' is NULL
*
* Ensures:
*
* \li On success, '*targetp' points to a valid task pool.
* \li On success, '*sourcep' points to NULL.
*
* Returns:
*
* \li #ISC_R_SUCCESS
* \li #ISC_R_NOMEMORY
*/ */
void void

View File

@@ -15,13 +15,14 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: taskpool.c,v 1.18 2007/06/18 23:47:44 tbox Exp $ */ /* $Id: taskpool.c,v 1.19 2011/07/06 01:36:32 each Exp $ */
/*! \file */ /*! \file */
#include <config.h> #include <config.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/random.h>
#include <isc/taskpool.h> #include <isc/taskpool.h>
#include <isc/util.h> #include <isc/util.h>
@@ -31,28 +32,30 @@
struct isc_taskpool { struct isc_taskpool {
isc_mem_t * mctx; isc_mem_t * mctx;
isc_taskmgr_t * tmgr;
unsigned int ntasks; unsigned int ntasks;
unsigned int quantum;
isc_task_t ** tasks; isc_task_t ** tasks;
}; };
/*** /***
*** Functions. *** Functions.
***/ ***/
isc_result_t static isc_result_t
isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks,
unsigned int ntasks, unsigned int quantum, unsigned int quantum, isc_taskpool_t **poolp)
isc_taskpool_t **poolp)
{ {
unsigned int i;
isc_taskpool_t *pool; isc_taskpool_t *pool;
isc_result_t result; unsigned int i;
INSIST(ntasks > 0);
pool = isc_mem_get(mctx, sizeof(*pool)); pool = isc_mem_get(mctx, sizeof(*pool));
if (pool == NULL) if (pool == NULL)
return (ISC_R_NOMEMORY); return (ISC_R_NOMEMORY);
pool->mctx = mctx; pool->mctx = mctx;
pool->ntasks = ntasks; pool->ntasks = ntasks;
pool->quantum = quantum;
pool->tmgr = tmgr;
pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *)); pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
if (pool->tasks == NULL) { if (pool->tasks == NULL) {
isc_mem_put(mctx, pool, sizeof(*pool)); isc_mem_put(mctx, pool, sizeof(*pool));
@@ -60,6 +63,28 @@ isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx,
} }
for (i = 0; i < ntasks; i++) for (i = 0; i < ntasks; i++)
pool->tasks[i] = NULL; pool->tasks[i] = NULL;
*poolp = pool;
return (ISC_R_SUCCESS);
}
isc_result_t
isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx,
unsigned int ntasks, unsigned int quantum,
isc_taskpool_t **poolp)
{
unsigned int i;
isc_taskpool_t *pool = NULL;
isc_result_t result;
INSIST(ntasks > 0);
/* Allocate the pool structure */
result = alloc_pool(tmgr, mctx, ntasks, quantum, &pool);
if (result != ISC_R_SUCCESS)
return (result);
/* Create the tasks */
for (i = 0; i < ntasks; i++) { for (i = 0; i < ntasks; i++) {
result = isc_task_create(tmgr, quantum, &pool->tasks[i]); result = isc_task_create(tmgr, quantum, &pool->tasks[i]);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
@@ -68,14 +93,69 @@ isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx,
} }
isc_task_setname(pool->tasks[i], "taskpool", NULL); isc_task_setname(pool->tasks[i], "taskpool", NULL);
} }
*poolp = pool; *poolp = pool;
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
void isc_taskpool_gettask(isc_taskpool_t *pool, unsigned int hash, void
isc_task_t **targetp) isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) {
isc_uint32_t i;
isc_random_get(&i);
isc_task_attach(pool->tasks[i % pool->ntasks], targetp);
}
int
isc_taskpool_size(isc_taskpool_t *pool) {
REQUIRE(pool != NULL);
return (pool->ntasks);
}
isc_result_t
isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size,
isc_taskpool_t **targetp)
{ {
isc_task_attach(pool->tasks[hash % pool->ntasks], targetp); isc_result_t result;
isc_taskpool_t *pool;
REQUIRE(sourcep != NULL && *sourcep != NULL);
REQUIRE(targetp != NULL && *targetp == NULL);
pool = *sourcep;
if (size > pool->ntasks) {
isc_taskpool_t *newpool = NULL;
unsigned int i;
/* Allocate a new pool structure */
result = alloc_pool(pool->tmgr, pool->mctx, size,
pool->quantum, &newpool);
if (result != ISC_R_SUCCESS)
return (result);
/* Copy over the tasks from the old pool */
for (i = 0; i < pool->ntasks; i++) {
newpool->tasks[i] = pool->tasks[i];
pool->tasks[i] = NULL;
}
/* Create new tasks */
for (i = pool->ntasks; i < size; i++) {
result = isc_task_create(pool->tmgr, pool->quantum,
&newpool->tasks[i]);
if (result != ISC_R_SUCCESS) {
isc_taskpool_destroy(&newpool);
return (result);
}
isc_task_setname(newpool->tasks[i], "taskpool", NULL);
}
isc_taskpool_destroy(&pool);
pool = newpool;
}
*sourcep = NULL;
*targetp = pool;
return (ISC_R_SUCCESS);
} }
void void

View File

@@ -531,7 +531,9 @@ isc_syslog_facilityfromstring
isc_taskmgr_renderxml isc_taskmgr_renderxml
isc_taskpool_create isc_taskpool_create
isc_taskpool_destroy isc_taskpool_destroy
isc_taskpool_expand
isc_taskpool_gettask isc_taskpool_gettask
isc_taskpool_size
isc_thread_create isc_thread_create
isc_thread_join isc_thread_join
isc_thread_key_create isc_thread_key_create