/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. /* $Id$ */
  18. /*! \file */
  19. #include <config.h>
  20. #include <isc/mem.h>
  21. #include <isc/random.h>
  22. #include <isc/taskpool.h>
  23. #include <isc/util.h>
  24. /***
  25. *** Types.
  26. ***/
  27. struct isc_taskpool {
  28. isc_mem_t * mctx;
  29. isc_taskmgr_t * tmgr;
  30. unsigned int ntasks;
  31. unsigned int quantum;
  32. isc_task_t ** tasks;
  33. };
  34. /***
  35. *** Functions.
  36. ***/
  37. static isc_result_t
  38. alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks,
  39. unsigned int quantum, isc_taskpool_t **poolp)
  40. {
  41. isc_taskpool_t *pool;
  42. unsigned int i;
  43. pool = isc_mem_get(mctx, sizeof(*pool));
  44. if (pool == NULL)
  45. return (ISC_R_NOMEMORY);
  46. pool->mctx = mctx;
  47. pool->ntasks = ntasks;
  48. pool->quantum = quantum;
  49. pool->tmgr = tmgr;
  50. pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
  51. if (pool->tasks == NULL) {
  52. isc_mem_put(mctx, pool, sizeof(*pool));
  53. return (ISC_R_NOMEMORY);
  54. }
  55. for (i = 0; i < ntasks; i++)
  56. pool->tasks[i] = NULL;
  57. *poolp = pool;
  58. return (ISC_R_SUCCESS);
  59. }
  60. isc_result_t
  61. isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx,
  62. unsigned int ntasks, unsigned int quantum,
  63. isc_taskpool_t **poolp)
  64. {
  65. unsigned int i;
  66. isc_taskpool_t *pool = NULL;
  67. isc_result_t result;
  68. INSIST(ntasks > 0);
  69. /* Allocate the pool structure */
  70. result = alloc_pool(tmgr, mctx, ntasks, quantum, &pool);
  71. if (result != ISC_R_SUCCESS)
  72. return (result);
  73. /* Create the tasks */
  74. for (i = 0; i < ntasks; i++) {
  75. result = isc_task_create(tmgr, quantum, &pool->tasks[i]);
  76. if (result != ISC_R_SUCCESS) {
  77. isc_taskpool_destroy(&pool);
  78. return (result);
  79. }
  80. isc_task_setname(pool->tasks[i], "taskpool", NULL);
  81. }
  82. *poolp = pool;
  83. return (ISC_R_SUCCESS);
  84. }
  85. void
  86. isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) {
  87. isc_uint32_t i;
  88. isc_random_get(&i);
  89. isc_task_attach(pool->tasks[i % pool->ntasks], targetp);
  90. }
  91. int
  92. isc_taskpool_size(isc_taskpool_t *pool) {
  93. REQUIRE(pool != NULL);
  94. return (pool->ntasks);
  95. }
  96. isc_result_t
  97. isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size,
  98. isc_taskpool_t **targetp)
  99. {
  100. isc_result_t result;
  101. isc_taskpool_t *pool;
  102. REQUIRE(sourcep != NULL && *sourcep != NULL);
  103. REQUIRE(targetp != NULL && *targetp == NULL);
  104. pool = *sourcep;
  105. if (size > pool->ntasks) {
  106. isc_taskpool_t *newpool = NULL;
  107. unsigned int i;
  108. /* Allocate a new pool structure */
  109. result = alloc_pool(pool->tmgr, pool->mctx, size,
  110. pool->quantum, &newpool);
  111. if (result != ISC_R_SUCCESS)
  112. return (result);
  113. /* Copy over the tasks from the old pool */
  114. for (i = 0; i < pool->ntasks; i++) {
  115. newpool->tasks[i] = pool->tasks[i];
  116. pool->tasks[i] = NULL;
  117. }
  118. /* Create new tasks */
  119. for (i = pool->ntasks; i < size; i++) {
  120. result = isc_task_create(pool->tmgr, pool->quantum,
  121. &newpool->tasks[i]);
  122. if (result != ISC_R_SUCCESS) {
  123. isc_taskpool_destroy(&newpool);
  124. return (result);
  125. }
  126. isc_task_setname(newpool->tasks[i], "taskpool", NULL);
  127. }
  128. isc_taskpool_destroy(&pool);
  129. pool = newpool;
  130. }
  131. *sourcep = NULL;
  132. *targetp = pool;
  133. return (ISC_R_SUCCESS);
  134. }
  135. void
  136. isc_taskpool_destroy(isc_taskpool_t **poolp) {
  137. unsigned int i;
  138. isc_taskpool_t *pool = *poolp;
  139. for (i = 0; i < pool->ntasks; i++) {
  140. if (pool->tasks[i] != NULL) {
  141. isc_task_detach(&pool->tasks[i]);
  142. }
  143. }
  144. isc_mem_put(pool->mctx, pool->tasks,
  145. pool->ntasks * sizeof(isc_task_t *));
  146. isc_mem_put(pool->mctx, pool, sizeof(*pool));
  147. *poolp = NULL;
  148. }