1*00b67f09SDavid van Moolenbroek /* $NetBSD: taskpool.c,v 1.6 2014/12/10 04:37:59 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek * Copyright (C) 1999-2001 Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek *
7*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek *
11*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /* Id */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek
26*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
27*00b67f09SDavid van Moolenbroek #include <isc/random.h>
28*00b67f09SDavid van Moolenbroek #include <isc/taskpool.h>
29*00b67f09SDavid van Moolenbroek #include <isc/util.h>
30*00b67f09SDavid van Moolenbroek
31*00b67f09SDavid van Moolenbroek /***
32*00b67f09SDavid van Moolenbroek *** Types.
33*00b67f09SDavid van Moolenbroek ***/
34*00b67f09SDavid van Moolenbroek
35*00b67f09SDavid van Moolenbroek struct isc_taskpool {
36*00b67f09SDavid van Moolenbroek isc_mem_t * mctx;
37*00b67f09SDavid van Moolenbroek isc_taskmgr_t * tmgr;
38*00b67f09SDavid van Moolenbroek unsigned int ntasks;
39*00b67f09SDavid van Moolenbroek unsigned int quantum;
40*00b67f09SDavid van Moolenbroek isc_task_t ** tasks;
41*00b67f09SDavid van Moolenbroek };
42*00b67f09SDavid van Moolenbroek
43*00b67f09SDavid van Moolenbroek /***
44*00b67f09SDavid van Moolenbroek *** Functions.
45*00b67f09SDavid van Moolenbroek ***/
46*00b67f09SDavid van Moolenbroek
47*00b67f09SDavid van Moolenbroek static isc_result_t
alloc_pool(isc_taskmgr_t * tmgr,isc_mem_t * mctx,unsigned int ntasks,unsigned int quantum,isc_taskpool_t ** poolp)48*00b67f09SDavid van Moolenbroek alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks,
49*00b67f09SDavid van Moolenbroek unsigned int quantum, isc_taskpool_t **poolp)
50*00b67f09SDavid van Moolenbroek {
51*00b67f09SDavid van Moolenbroek isc_taskpool_t *pool;
52*00b67f09SDavid van Moolenbroek unsigned int i;
53*00b67f09SDavid van Moolenbroek
54*00b67f09SDavid van Moolenbroek pool = isc_mem_get(mctx, sizeof(*pool));
55*00b67f09SDavid van Moolenbroek if (pool == NULL)
56*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
57*00b67f09SDavid van Moolenbroek
58*00b67f09SDavid van Moolenbroek pool->mctx = NULL;
59*00b67f09SDavid van Moolenbroek isc_mem_attach(mctx, &pool->mctx);
60*00b67f09SDavid van Moolenbroek pool->ntasks = ntasks;
61*00b67f09SDavid van Moolenbroek pool->quantum = quantum;
62*00b67f09SDavid van Moolenbroek pool->tmgr = tmgr;
63*00b67f09SDavid van Moolenbroek pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
64*00b67f09SDavid van Moolenbroek if (pool->tasks == NULL) {
65*00b67f09SDavid van Moolenbroek isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool));
66*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
67*00b67f09SDavid van Moolenbroek }
68*00b67f09SDavid van Moolenbroek for (i = 0; i < ntasks; i++)
69*00b67f09SDavid van Moolenbroek pool->tasks[i] = NULL;
70*00b67f09SDavid van Moolenbroek
71*00b67f09SDavid van Moolenbroek *poolp = pool;
72*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
73*00b67f09SDavid van Moolenbroek }
74*00b67f09SDavid van Moolenbroek
75*00b67f09SDavid van Moolenbroek isc_result_t
isc_taskpool_create(isc_taskmgr_t * tmgr,isc_mem_t * mctx,unsigned int ntasks,unsigned int quantum,isc_taskpool_t ** poolp)76*00b67f09SDavid van Moolenbroek isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx,
77*00b67f09SDavid van Moolenbroek unsigned int ntasks, unsigned int quantum,
78*00b67f09SDavid van Moolenbroek isc_taskpool_t **poolp)
79*00b67f09SDavid van Moolenbroek {
80*00b67f09SDavid van Moolenbroek unsigned int i;
81*00b67f09SDavid van Moolenbroek isc_taskpool_t *pool = NULL;
82*00b67f09SDavid van Moolenbroek isc_result_t result;
83*00b67f09SDavid van Moolenbroek
84*00b67f09SDavid van Moolenbroek INSIST(ntasks > 0);
85*00b67f09SDavid van Moolenbroek
86*00b67f09SDavid van Moolenbroek /* Allocate the pool structure */
87*00b67f09SDavid van Moolenbroek result = alloc_pool(tmgr, mctx, ntasks, quantum, &pool);
88*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
89*00b67f09SDavid van Moolenbroek return (result);
90*00b67f09SDavid van Moolenbroek
91*00b67f09SDavid van Moolenbroek /* Create the tasks */
92*00b67f09SDavid van Moolenbroek for (i = 0; i < ntasks; i++) {
93*00b67f09SDavid van Moolenbroek result = isc_task_create(tmgr, quantum, &pool->tasks[i]);
94*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
95*00b67f09SDavid van Moolenbroek isc_taskpool_destroy(&pool);
96*00b67f09SDavid van Moolenbroek return (result);
97*00b67f09SDavid van Moolenbroek }
98*00b67f09SDavid van Moolenbroek isc_task_setname(pool->tasks[i], "taskpool", NULL);
99*00b67f09SDavid van Moolenbroek }
100*00b67f09SDavid van Moolenbroek
101*00b67f09SDavid van Moolenbroek *poolp = pool;
102*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
103*00b67f09SDavid van Moolenbroek }
104*00b67f09SDavid van Moolenbroek
105*00b67f09SDavid van Moolenbroek void
isc_taskpool_gettask(isc_taskpool_t * pool,isc_task_t ** targetp)106*00b67f09SDavid van Moolenbroek isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) {
107*00b67f09SDavid van Moolenbroek isc_uint32_t i;
108*00b67f09SDavid van Moolenbroek isc_random_get(&i);
109*00b67f09SDavid van Moolenbroek isc_task_attach(pool->tasks[i % pool->ntasks], targetp);
110*00b67f09SDavid van Moolenbroek }
111*00b67f09SDavid van Moolenbroek
112*00b67f09SDavid van Moolenbroek int
isc_taskpool_size(isc_taskpool_t * pool)113*00b67f09SDavid van Moolenbroek isc_taskpool_size(isc_taskpool_t *pool) {
114*00b67f09SDavid van Moolenbroek REQUIRE(pool != NULL);
115*00b67f09SDavid van Moolenbroek return (pool->ntasks);
116*00b67f09SDavid van Moolenbroek }
117*00b67f09SDavid van Moolenbroek
118*00b67f09SDavid van Moolenbroek isc_result_t
isc_taskpool_expand(isc_taskpool_t ** sourcep,unsigned int size,isc_taskpool_t ** targetp)119*00b67f09SDavid van Moolenbroek isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size,
120*00b67f09SDavid van Moolenbroek isc_taskpool_t **targetp)
121*00b67f09SDavid van Moolenbroek {
122*00b67f09SDavid van Moolenbroek isc_result_t result;
123*00b67f09SDavid van Moolenbroek isc_taskpool_t *pool;
124*00b67f09SDavid van Moolenbroek
125*00b67f09SDavid van Moolenbroek REQUIRE(sourcep != NULL && *sourcep != NULL);
126*00b67f09SDavid van Moolenbroek REQUIRE(targetp != NULL && *targetp == NULL);
127*00b67f09SDavid van Moolenbroek
128*00b67f09SDavid van Moolenbroek pool = *sourcep;
129*00b67f09SDavid van Moolenbroek if (size > pool->ntasks) {
130*00b67f09SDavid van Moolenbroek isc_taskpool_t *newpool = NULL;
131*00b67f09SDavid van Moolenbroek unsigned int i;
132*00b67f09SDavid van Moolenbroek
133*00b67f09SDavid van Moolenbroek /* Allocate a new pool structure */
134*00b67f09SDavid van Moolenbroek result = alloc_pool(pool->tmgr, pool->mctx, size,
135*00b67f09SDavid van Moolenbroek pool->quantum, &newpool);
136*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
137*00b67f09SDavid van Moolenbroek return (result);
138*00b67f09SDavid van Moolenbroek
139*00b67f09SDavid van Moolenbroek /* Copy over the tasks from the old pool */
140*00b67f09SDavid van Moolenbroek for (i = 0; i < pool->ntasks; i++) {
141*00b67f09SDavid van Moolenbroek newpool->tasks[i] = pool->tasks[i];
142*00b67f09SDavid van Moolenbroek pool->tasks[i] = NULL;
143*00b67f09SDavid van Moolenbroek }
144*00b67f09SDavid van Moolenbroek
145*00b67f09SDavid van Moolenbroek /* Create new tasks */
146*00b67f09SDavid van Moolenbroek for (i = pool->ntasks; i < size; i++) {
147*00b67f09SDavid van Moolenbroek result = isc_task_create(pool->tmgr, pool->quantum,
148*00b67f09SDavid van Moolenbroek &newpool->tasks[i]);
149*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
150*00b67f09SDavid van Moolenbroek isc_taskpool_destroy(&newpool);
151*00b67f09SDavid van Moolenbroek return (result);
152*00b67f09SDavid van Moolenbroek }
153*00b67f09SDavid van Moolenbroek isc_task_setname(newpool->tasks[i], "taskpool", NULL);
154*00b67f09SDavid van Moolenbroek }
155*00b67f09SDavid van Moolenbroek
156*00b67f09SDavid van Moolenbroek isc_taskpool_destroy(&pool);
157*00b67f09SDavid van Moolenbroek pool = newpool;
158*00b67f09SDavid van Moolenbroek }
159*00b67f09SDavid van Moolenbroek
160*00b67f09SDavid van Moolenbroek *sourcep = NULL;
161*00b67f09SDavid van Moolenbroek *targetp = pool;
162*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
163*00b67f09SDavid van Moolenbroek }
164*00b67f09SDavid van Moolenbroek
165*00b67f09SDavid van Moolenbroek void
isc_taskpool_destroy(isc_taskpool_t ** poolp)166*00b67f09SDavid van Moolenbroek isc_taskpool_destroy(isc_taskpool_t **poolp) {
167*00b67f09SDavid van Moolenbroek unsigned int i;
168*00b67f09SDavid van Moolenbroek isc_taskpool_t *pool = *poolp;
169*00b67f09SDavid van Moolenbroek for (i = 0; i < pool->ntasks; i++) {
170*00b67f09SDavid van Moolenbroek if (pool->tasks[i] != NULL)
171*00b67f09SDavid van Moolenbroek isc_task_detach(&pool->tasks[i]);
172*00b67f09SDavid van Moolenbroek }
173*00b67f09SDavid van Moolenbroek isc_mem_put(pool->mctx, pool->tasks,
174*00b67f09SDavid van Moolenbroek pool->ntasks * sizeof(isc_task_t *));
175*00b67f09SDavid van Moolenbroek isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool));
176*00b67f09SDavid van Moolenbroek *poolp = NULL;
177*00b67f09SDavid van Moolenbroek }
178*00b67f09SDavid van Moolenbroek
179*00b67f09SDavid van Moolenbroek void
isc_taskpool_setprivilege(isc_taskpool_t * pool,isc_boolean_t priv)180*00b67f09SDavid van Moolenbroek isc_taskpool_setprivilege(isc_taskpool_t *pool, isc_boolean_t priv) {
181*00b67f09SDavid van Moolenbroek unsigned int i;
182*00b67f09SDavid van Moolenbroek
183*00b67f09SDavid van Moolenbroek REQUIRE(pool != NULL);
184*00b67f09SDavid van Moolenbroek
185*00b67f09SDavid van Moolenbroek for (i = 0; i < pool->ntasks; i++) {
186*00b67f09SDavid van Moolenbroek if (pool->tasks[i] != NULL)
187*00b67f09SDavid van Moolenbroek isc_task_setprivilege(pool->tasks[i], priv);
188*00b67f09SDavid van Moolenbroek }
189*00b67f09SDavid van Moolenbroek }
190