xref: /minix3/external/bsd/bind/dist/lib/isc/taskpool.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
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