PageRenderTime 29ms CodeModel.GetById 11ms app.highlight 13ms RepoModel.GetById 2ms app.codeStats 0ms

/contrib/bind9/lib/isc/taskpool.c

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