1258945Sroberto/* 2280849Scy * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") 3258945Sroberto * Copyright (C) 1999-2001 Internet Software Consortium. 4258945Sroberto * 5258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any 6258945Sroberto * purpose with or without fee is hereby granted, provided that the above 7258945Sroberto * copyright notice and this permission notice appear in all copies. 8258945Sroberto * 9258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11258945Sroberto * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15258945Sroberto * PERFORMANCE OF THIS SOFTWARE. 16258945Sroberto */ 17258945Sroberto 18280849Scy/* $Id$ */ 19258945Sroberto 20258945Sroberto/*! \file */ 21258945Sroberto 22258945Sroberto#include <config.h> 23258945Sroberto 24258945Sroberto#include <isc/mem.h> 25280849Scy#include <isc/random.h> 26258945Sroberto#include <isc/taskpool.h> 27258945Sroberto#include <isc/util.h> 28258945Sroberto 29258945Sroberto/*** 30258945Sroberto *** Types. 31258945Sroberto ***/ 32258945Sroberto 33258945Srobertostruct isc_taskpool { 34258945Sroberto isc_mem_t * mctx; 35280849Scy isc_taskmgr_t * tmgr; 36258945Sroberto unsigned int ntasks; 37280849Scy unsigned int quantum; 38258945Sroberto isc_task_t ** tasks; 39258945Sroberto}; 40280849Scy 41258945Sroberto/*** 42258945Sroberto *** Functions. 43258945Sroberto ***/ 44258945Sroberto 45280849Scystatic isc_result_t 46280849Scyalloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks, 47280849Scy unsigned int quantum, isc_taskpool_t **poolp) 48258945Sroberto{ 49280849Scy isc_taskpool_t *pool; 50258945Sroberto unsigned int i; 51258945Sroberto 52258945Sroberto pool = isc_mem_get(mctx, sizeof(*pool)); 53258945Sroberto if (pool == NULL) 54258945Sroberto return (ISC_R_NOMEMORY); 55258945Sroberto pool->mctx = mctx; 56258945Sroberto pool->ntasks = ntasks; 57280849Scy pool->quantum = quantum; 58280849Scy pool->tmgr = tmgr; 59258945Sroberto pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *)); 60258945Sroberto if (pool->tasks == NULL) { 61258945Sroberto isc_mem_put(mctx, pool, sizeof(*pool)); 62258945Sroberto return (ISC_R_NOMEMORY); 63258945Sroberto } 64258945Sroberto for (i = 0; i < ntasks; i++) 65258945Sroberto pool->tasks[i] = NULL; 66280849Scy 67280849Scy *poolp = pool; 68280849Scy return (ISC_R_SUCCESS); 69280849Scy} 70280849Scy 71280849Scyisc_result_t 72280849Scyisc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, 73280849Scy unsigned int ntasks, unsigned int quantum, 74280849Scy isc_taskpool_t **poolp) 75280849Scy{ 76280849Scy unsigned int i; 77280849Scy isc_taskpool_t *pool = NULL; 78280849Scy isc_result_t result; 79280849Scy 80280849Scy INSIST(ntasks > 0); 81280849Scy 82280849Scy /* Allocate the pool structure */ 83280849Scy result = alloc_pool(tmgr, mctx, ntasks, quantum, &pool); 84280849Scy if (result != ISC_R_SUCCESS) 85280849Scy return (result); 86280849Scy 87280849Scy /* Create the tasks */ 88258945Sroberto for (i = 0; i < ntasks; i++) { 89258945Sroberto result = isc_task_create(tmgr, quantum, &pool->tasks[i]); 90258945Sroberto if (result != ISC_R_SUCCESS) { 91258945Sroberto isc_taskpool_destroy(&pool); 92258945Sroberto return (result); 93258945Sroberto } 94258945Sroberto isc_task_setname(pool->tasks[i], "taskpool", NULL); 95258945Sroberto } 96280849Scy 97258945Sroberto *poolp = pool; 98258945Sroberto return (ISC_R_SUCCESS); 99258945Sroberto} 100258945Sroberto 101280849Scyvoid 102280849Scyisc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) { 103280849Scy isc_uint32_t i; 104280849Scy isc_random_get(&i); 105280849Scy isc_task_attach(pool->tasks[i % pool->ntasks], targetp); 106280849Scy} 107280849Scy 108280849Scyint 109280849Scyisc_taskpool_size(isc_taskpool_t *pool) { 110280849Scy REQUIRE(pool != NULL); 111280849Scy return (pool->ntasks); 112280849Scy} 113280849Scy 114280849Scyisc_result_t 115280849Scyisc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size, 116280849Scy isc_taskpool_t **targetp) 117258945Sroberto{ 118280849Scy isc_result_t result; 119280849Scy isc_taskpool_t *pool; 120280849Scy 121280849Scy REQUIRE(sourcep != NULL && *sourcep != NULL); 122280849Scy REQUIRE(targetp != NULL && *targetp == NULL); 123280849Scy 124280849Scy pool = *sourcep; 125280849Scy if (size > pool->ntasks) { 126280849Scy isc_taskpool_t *newpool = NULL; 127280849Scy unsigned int i; 128280849Scy 129280849Scy /* Allocate a new pool structure */ 130280849Scy result = alloc_pool(pool->tmgr, pool->mctx, size, 131280849Scy pool->quantum, &newpool); 132280849Scy if (result != ISC_R_SUCCESS) 133280849Scy return (result); 134280849Scy 135280849Scy /* Copy over the tasks from the old pool */ 136280849Scy for (i = 0; i < pool->ntasks; i++) { 137280849Scy newpool->tasks[i] = pool->tasks[i]; 138280849Scy pool->tasks[i] = NULL; 139280849Scy } 140280849Scy 141280849Scy /* Create new tasks */ 142280849Scy for (i = pool->ntasks; i < size; i++) { 143280849Scy result = isc_task_create(pool->tmgr, pool->quantum, 144280849Scy &newpool->tasks[i]); 145280849Scy if (result != ISC_R_SUCCESS) { 146280849Scy isc_taskpool_destroy(&newpool); 147280849Scy return (result); 148280849Scy } 149280849Scy isc_task_setname(newpool->tasks[i], "taskpool", NULL); 150280849Scy } 151280849Scy 152280849Scy isc_taskpool_destroy(&pool); 153280849Scy pool = newpool; 154280849Scy } 155280849Scy 156280849Scy *sourcep = NULL; 157280849Scy *targetp = pool; 158280849Scy return (ISC_R_SUCCESS); 159258945Sroberto} 160258945Sroberto 161258945Srobertovoid 162258945Srobertoisc_taskpool_destroy(isc_taskpool_t **poolp) { 163258945Sroberto unsigned int i; 164258945Sroberto isc_taskpool_t *pool = *poolp; 165258945Sroberto for (i = 0; i < pool->ntasks; i++) { 166280849Scy if (pool->tasks[i] != NULL) 167258945Sroberto isc_task_detach(&pool->tasks[i]); 168258945Sroberto } 169258945Sroberto isc_mem_put(pool->mctx, pool->tasks, 170258945Sroberto pool->ntasks * sizeof(isc_task_t *)); 171258945Sroberto isc_mem_put(pool->mctx, pool, sizeof(*pool)); 172258945Sroberto *poolp = NULL; 173258945Sroberto} 174258945Sroberto 175280849Scyvoid 176280849Scyisc_taskpool_setprivilege(isc_taskpool_t *pool, isc_boolean_t priv) { 177280849Scy unsigned int i; 178258945Sroberto 179280849Scy REQUIRE(pool != NULL); 180280849Scy 181280849Scy for (i = 0; i < pool->ntasks; i++) { 182280849Scy if (pool->tasks[i] != NULL) 183280849Scy isc_task_setprivilege(pool->tasks[i], priv); 184280849Scy } 185280849Scy} 186