taskpool.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004, 2005, 2007, 2011-2013  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1999-2001  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id$ */
00019 
00020 /*! \file */
00021 
00022 #include <config.h>
00023 
00024 #include <isc/mem.h>
00025 #include <isc/random.h>
00026 #include <isc/taskpool.h>
00027 #include <isc/util.h>
00028 
00029 /***
00030  *** Types.
00031  ***/
00032 
00033 struct isc_taskpool {
00034         isc_mem_t *                     mctx;
00035         isc_taskmgr_t *                 tmgr;
00036         unsigned int                    ntasks;
00037         unsigned int                    quantum;
00038         isc_task_t **                   tasks;
00039 };
00040 
00041 /***
00042  *** Functions.
00043  ***/
00044 
00045 static isc_result_t
00046 alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks,
00047            unsigned int quantum, isc_taskpool_t **poolp)
00048 {
00049         isc_taskpool_t *pool;
00050         unsigned int i;
00051 
00052         pool = isc_mem_get(mctx, sizeof(*pool));
00053         if (pool == NULL)
00054                 return (ISC_R_NOMEMORY);
00055 
00056         pool->mctx = NULL;
00057         isc_mem_attach(mctx, &pool->mctx);
00058         pool->ntasks = ntasks;
00059         pool->quantum = quantum;
00060         pool->tmgr = tmgr;
00061         pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
00062         if (pool->tasks == NULL) {
00063                 isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool));
00064                 return (ISC_R_NOMEMORY);
00065         }
00066         for (i = 0; i < ntasks; i++)
00067                 pool->tasks[i] = NULL;
00068 
00069         *poolp = pool;
00070         return (ISC_R_SUCCESS);
00071 }
00072 
00073 isc_result_t
00074 isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx,
00075                     unsigned int ntasks, unsigned int quantum,
00076                     isc_taskpool_t **poolp)
00077 {
00078         unsigned int i;
00079         isc_taskpool_t *pool = NULL;
00080         isc_result_t result;
00081 
00082         INSIST(ntasks > 0);
00083 
00084         /* Allocate the pool structure */
00085         result = alloc_pool(tmgr, mctx, ntasks, quantum, &pool);
00086         if (result != ISC_R_SUCCESS)
00087                 return (result);
00088 
00089         /* Create the tasks */
00090         for (i = 0; i < ntasks; i++) {
00091                 result = isc_task_create(tmgr, quantum, &pool->tasks[i]);
00092                 if (result != ISC_R_SUCCESS) {
00093                         isc_taskpool_destroy(&pool);
00094                         return (result);
00095                 }
00096                 isc_task_setname(pool->tasks[i], "taskpool", NULL);
00097         }
00098 
00099         *poolp = pool;
00100         return (ISC_R_SUCCESS);
00101 }
00102 
00103 void
00104 isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) {
00105         isc_uint32_t i;
00106         isc_random_get(&i);
00107         isc_task_attach(pool->tasks[i % pool->ntasks], targetp);
00108 }
00109 
00110 int
00111 isc_taskpool_size(isc_taskpool_t *pool) {
00112         REQUIRE(pool != NULL);
00113         return (pool->ntasks);
00114 }
00115 
00116 isc_result_t
00117 isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size,
00118                     isc_taskpool_t **targetp)
00119 {
00120         isc_result_t result;
00121         isc_taskpool_t *pool;
00122 
00123         REQUIRE(sourcep != NULL && *sourcep != NULL);
00124         REQUIRE(targetp != NULL && *targetp == NULL);
00125 
00126         pool = *sourcep;
00127         if (size > pool->ntasks) {
00128                 isc_taskpool_t *newpool = NULL;
00129                 unsigned int i;
00130 
00131                 /* Allocate a new pool structure */
00132                 result = alloc_pool(pool->tmgr, pool->mctx, size,
00133                                     pool->quantum, &newpool);
00134                 if (result != ISC_R_SUCCESS)
00135                         return (result);
00136 
00137                 /* Copy over the tasks from the old pool */
00138                 for (i = 0; i < pool->ntasks; i++) {
00139                         newpool->tasks[i] = pool->tasks[i];
00140                         pool->tasks[i] = NULL;
00141                 }
00142 
00143                 /* Create new tasks */
00144                 for (i = pool->ntasks; i < size; i++) {
00145                         result = isc_task_create(pool->tmgr, pool->quantum,
00146                                                  &newpool->tasks[i]);
00147                         if (result != ISC_R_SUCCESS) {
00148                                 isc_taskpool_destroy(&newpool);
00149                                 return (result);
00150                         }
00151                         isc_task_setname(newpool->tasks[i], "taskpool", NULL);
00152                 }
00153 
00154                 isc_taskpool_destroy(&pool);
00155                 pool = newpool;
00156         }
00157 
00158         *sourcep = NULL;
00159         *targetp = pool;
00160         return (ISC_R_SUCCESS);
00161 }
00162 
00163 void
00164 isc_taskpool_destroy(isc_taskpool_t **poolp) {
00165         unsigned int i;
00166         isc_taskpool_t *pool = *poolp;
00167         for (i = 0; i < pool->ntasks; i++) {
00168                 if (pool->tasks[i] != NULL)
00169                         isc_task_detach(&pool->tasks[i]);
00170         }
00171         isc_mem_put(pool->mctx, pool->tasks,
00172                     pool->ntasks * sizeof(isc_task_t *));
00173         isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool));
00174         *poolp = NULL;
00175 }
00176 
00177 void
00178 isc_taskpool_setprivilege(isc_taskpool_t *pool, isc_boolean_t priv) {
00179         unsigned int i;
00180 
00181         REQUIRE(pool != NULL);
00182 
00183         for (i = 0; i < pool->ntasks; i++) {
00184                 if (pool->tasks[i] != NULL)
00185                         isc_task_setprivilege(pool->tasks[i], priv);
00186         }
00187 }

Generated on Tue Apr 28 17:41:05 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha