00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
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
00085 result = alloc_pool(tmgr, mctx, ntasks, quantum, &pool);
00086 if (result != ISC_R_SUCCESS)
00087 return (result);
00088
00089
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
00132 result = alloc_pool(pool->tmgr, pool->mctx, size,
00133 pool->quantum, &newpool);
00134 if (result != ISC_R_SUCCESS)
00135 return (result);
00136
00137
00138 for (i = 0; i < pool->ntasks; i++) {
00139 newpool->tasks[i] = pool->tasks[i];
00140 pool->tasks[i] = NULL;
00141 }
00142
00143
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 }