2
0

testrmm.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
  2. * applicable.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "apr_shm.h"
  17. #include "apr_rmm.h"
  18. #include "apr_errno.h"
  19. #include "apr_general.h"
  20. #include "apr_lib.h"
  21. #include "apr_strings.h"
  22. #include "apr_time.h"
  23. #include <errno.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #if APR_HAVE_UNISTD_H
  27. #include <unistd.h>
  28. #endif
  29. #if APR_HAS_SHARED_MEMORY
  30. #define FRAG_SIZE 80
  31. #define FRAG_COUNT 10
  32. #define SHARED_SIZE (apr_size_t)(FRAG_SIZE * FRAG_COUNT * sizeof(char*))
  33. static apr_status_t test_rmm(apr_pool_t *parpool)
  34. {
  35. apr_status_t rv;
  36. apr_pool_t *pool;
  37. apr_shm_t *shm;
  38. apr_rmm_t *rmm;
  39. apr_size_t size, fragsize;
  40. apr_rmm_off_t *off;
  41. int i;
  42. void *entity;
  43. rv = apr_pool_create(&pool, parpool);
  44. if (rv != APR_SUCCESS) {
  45. fprintf(stderr, "Error creating child pool\n");
  46. return rv;
  47. }
  48. /* We're going to want 10 blocks of data from our target rmm. */
  49. size = SHARED_SIZE + apr_rmm_overhead_get(FRAG_COUNT + 1);
  50. printf("Creating anonymous shared memory (%"
  51. APR_SIZE_T_FMT " bytes).....", size);
  52. rv = apr_shm_create(&shm, size, NULL, pool);
  53. if (rv != APR_SUCCESS) {
  54. fprintf(stderr, "Error allocating shared memory block\n");
  55. return rv;
  56. }
  57. fprintf(stdout, "OK\n");
  58. printf("Creating rmm segment.............................");
  59. rv = apr_rmm_init(&rmm, NULL, apr_shm_baseaddr_get(shm), size,
  60. pool);
  61. if (rv != APR_SUCCESS) {
  62. fprintf(stderr, "Error allocating rmm..............\n");
  63. return rv;
  64. }
  65. fprintf(stdout, "OK\n");
  66. fragsize = SHARED_SIZE / FRAG_COUNT;
  67. printf("Creating each fragment of size %" APR_SIZE_T_FMT "................",
  68. fragsize);
  69. off = apr_palloc(pool, FRAG_COUNT * sizeof(apr_rmm_off_t));
  70. for (i = 0; i < FRAG_COUNT; i++) {
  71. off[i] = apr_rmm_malloc(rmm, fragsize);
  72. }
  73. fprintf(stdout, "OK\n");
  74. printf("Checking for out of memory allocation............");
  75. if (apr_rmm_malloc(rmm, FRAG_SIZE * FRAG_COUNT) == 0) {
  76. fprintf(stdout, "OK\n");
  77. }
  78. else {
  79. return APR_EGENERAL;
  80. }
  81. printf("Checking each fragment for address alignment.....");
  82. for (i = 0; i < FRAG_COUNT; i++) {
  83. char *c = apr_rmm_addr_get(rmm, off[i]);
  84. apr_size_t sc = (apr_size_t)c;
  85. if (off[i] == 0) {
  86. printf("allocation failed for offset %d\n", i);
  87. return APR_ENOMEM;
  88. }
  89. if (sc & 7) {
  90. printf("Bad alignment for fragment %d; %p not %p!\n",
  91. i, c, (void *)APR_ALIGN_DEFAULT((apr_size_t)c));
  92. return APR_EGENERAL;
  93. }
  94. }
  95. fprintf(stdout, "OK\n");
  96. printf("Setting each fragment to a unique value..........");
  97. for (i = 0; i < FRAG_COUNT; i++) {
  98. int j;
  99. char **c = apr_rmm_addr_get(rmm, off[i]);
  100. for (j = 0; j < FRAG_SIZE; j++, c++) {
  101. *c = apr_itoa(pool, i + j);
  102. }
  103. }
  104. fprintf(stdout, "OK\n");
  105. printf("Checking each fragment for its unique value......");
  106. for (i = 0; i < FRAG_COUNT; i++) {
  107. int j;
  108. char **c = apr_rmm_addr_get(rmm, off[i]);
  109. for (j = 0; j < FRAG_SIZE; j++, c++) {
  110. char *d = apr_itoa(pool, i + j);
  111. if (strcmp(*c, d) != 0) {
  112. return APR_EGENERAL;
  113. }
  114. }
  115. }
  116. fprintf(stdout, "OK\n");
  117. printf("Freeing each fragment............................");
  118. for (i = 0; i < FRAG_COUNT; i++) {
  119. rv = apr_rmm_free(rmm, off[i]);
  120. if (rv != APR_SUCCESS) {
  121. return rv;
  122. }
  123. }
  124. fprintf(stdout, "OK\n");
  125. printf("Creating one large segment.......................");
  126. off[0] = apr_rmm_calloc(rmm, SHARED_SIZE);
  127. fprintf(stdout, "OK\n");
  128. printf("Setting large segment............................");
  129. for (i = 0; i < FRAG_COUNT * FRAG_SIZE; i++) {
  130. char **c = apr_rmm_addr_get(rmm, off[0]);
  131. c[i] = apr_itoa(pool, i);
  132. }
  133. fprintf(stdout, "OK\n");
  134. printf("Freeing large segment............................");
  135. apr_rmm_free(rmm, off[0]);
  136. fprintf(stdout, "OK\n");
  137. printf("Creating each fragment of size %" APR_SIZE_T_FMT " (again)........",
  138. fragsize);
  139. for (i = 0; i < FRAG_COUNT; i++) {
  140. off[i] = apr_rmm_malloc(rmm, fragsize);
  141. }
  142. fprintf(stdout, "OK\n");
  143. printf("Freeing each fragment backwards..................");
  144. for (i = FRAG_COUNT - 1; i >= 0; i--) {
  145. rv = apr_rmm_free(rmm, off[i]);
  146. if (rv != APR_SUCCESS) {
  147. return rv;
  148. }
  149. }
  150. fprintf(stdout, "OK\n");
  151. printf("Creating one large segment (again)...............");
  152. off[0] = apr_rmm_calloc(rmm, SHARED_SIZE);
  153. fprintf(stdout, "OK\n");
  154. printf("Freeing large segment............................");
  155. apr_rmm_free(rmm, off[0]);
  156. fprintf(stdout, "OK\n");
  157. printf("Checking realloc.................................");
  158. off[0] = apr_rmm_calloc(rmm, SHARED_SIZE - 100);
  159. off[1] = apr_rmm_calloc(rmm, 100);
  160. if (off[0] == 0 || off[1] == 0) {
  161. printf("FAILED\n");
  162. return APR_EINVAL;
  163. }
  164. entity = apr_rmm_addr_get(rmm, off[1]);
  165. rv = apr_rmm_free(rmm, off[0]);
  166. if (rv != APR_SUCCESS) {
  167. printf("FAILED\n");
  168. return rv;
  169. }
  170. {
  171. unsigned char *c = entity;
  172. /* Fill in the region; the first half with zereos, which will
  173. * likely catch the apr_rmm_realloc offset calculation bug by
  174. * making it think the old region was zero length. */
  175. for (i = 0; i < 100; i++) {
  176. c[i] = (i < 50) ? 0 : i;
  177. }
  178. }
  179. /* now we can realloc off[1] and get many more bytes */
  180. off[0] = apr_rmm_realloc(rmm, entity, SHARED_SIZE - 100);
  181. if (off[0] == 0) {
  182. printf("FAILED\n");
  183. return APR_EINVAL;
  184. }
  185. {
  186. unsigned char *c = apr_rmm_addr_get(rmm, off[0]);
  187. /* fill in the region */
  188. for (i = 0; i < 100; i++) {
  189. if (c[i] != (i < 50 ? 0 : i)) {
  190. printf("FAILED at offset %d: %hx\n", i, c[i]);
  191. return APR_EGENERAL;
  192. }
  193. }
  194. }
  195. fprintf(stdout, "OK\n");
  196. printf("Destroying rmm segment...........................");
  197. rv = apr_rmm_destroy(rmm);
  198. if (rv != APR_SUCCESS) {
  199. printf("FAILED\n");
  200. return rv;
  201. }
  202. printf("OK\n");
  203. printf("Destroying shared memory segment.................");
  204. rv = apr_shm_destroy(shm);
  205. if (rv != APR_SUCCESS) {
  206. printf("FAILED\n");
  207. return rv;
  208. }
  209. printf("OK\n");
  210. apr_pool_destroy(pool);
  211. return APR_SUCCESS;
  212. }
  213. int main(void)
  214. {
  215. apr_status_t rv;
  216. apr_pool_t *pool;
  217. char errmsg[200];
  218. apr_initialize();
  219. printf("APR RMM Memory Test\n");
  220. printf("======================\n\n");
  221. printf("Initializing the pool............................");
  222. if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
  223. printf("could not initialize pool\n");
  224. exit(-1);
  225. }
  226. printf("OK\n");
  227. rv = test_rmm(pool);
  228. if (rv != APR_SUCCESS) {
  229. printf("Anonymous shared memory test FAILED: [%d] %s\n",
  230. rv, apr_strerror(rv, errmsg, sizeof(errmsg)));
  231. exit(-2);
  232. }
  233. printf("RMM test passed!\n");
  234. return 0;
  235. }
  236. #else /* APR_HAS_SHARED_MEMORY */
  237. #error shmem is not supported on this platform
  238. #endif /* APR_HAS_SHARED_MEMORY */