dispatch_cascade.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Copyright (c) 2008-2011 Apple Inc. All rights reserved.
  3. *
  4. * @APPLE_APACHE_LICENSE_HEADER_START@
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * @APPLE_APACHE_LICENSE_HEADER_END@
  19. */
  20. #include <stdio.h>
  21. #include <dispatch/dispatch.h>
  22. #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
  23. #include <unistd.h>
  24. #endif
  25. #include <stdlib.h>
  26. #include <bsdtests.h>
  27. #include "dispatch_test.h"
  28. int done = 0;
  29. #define QUEUES 80
  30. dispatch_queue_t queues[QUEUES];
  31. #define BLOCKS 10000
  32. union {
  33. size_t index;
  34. char padding[64];
  35. } indices[BLOCKS];
  36. size_t iterations = (QUEUES * BLOCKS) / 4;
  37. static void
  38. noop(void *ctxt __attribute__((unused)))
  39. {
  40. return;
  41. }
  42. static void
  43. cleanup(void *ctxt __attribute__((unused)))
  44. {
  45. size_t q;
  46. for (q = 0; q < QUEUES; ++q) {
  47. dispatch_sync_f(queues[q], NULL, noop);
  48. dispatch_release(queues[q]);
  49. }
  50. test_stop();
  51. exit(0);
  52. }
  53. static void
  54. histogram(void)
  55. {
  56. size_t counts[QUEUES] = {};
  57. size_t maxcount = 0;
  58. size_t q;
  59. for (q = 0; q < QUEUES; ++q) {
  60. size_t i;
  61. for (i = 0; i < BLOCKS; ++i) {
  62. if (indices[i].index == q) {
  63. ++counts[q];
  64. }
  65. }
  66. }
  67. for (q = 0; q < QUEUES; ++q) {
  68. if (counts[q] > maxcount) {
  69. maxcount = counts[q];
  70. }
  71. }
  72. printf("maxcount = %zd\n", maxcount);
  73. size_t x,y;
  74. for (y = 20; y > 0; --y) {
  75. for (x = 0; x < QUEUES; ++x) {
  76. double fraction = (double)counts[x] / (double)maxcount;
  77. double value = fraction * (double)20;
  78. printf("%s", (value > y) ? "*" : " ");
  79. }
  80. printf("\n");
  81. }
  82. }
  83. static void
  84. cascade(void* context)
  85. {
  86. size_t idx, *idxptr = context;
  87. if (done) return;
  88. idx = *idxptr + 1;
  89. if (idx < QUEUES) {
  90. *idxptr = idx;
  91. dispatch_async_f(queues[idx], context, cascade);
  92. }
  93. if (__sync_sub_and_fetch(&iterations, 1) == 0) {
  94. done = 1;
  95. histogram();
  96. dispatch_async_f(dispatch_get_main_queue(), NULL, cleanup);
  97. }
  98. }
  99. int
  100. main(int argc __attribute__((unused)), char* argv[] __attribute__((unused)))
  101. {
  102. int i;
  103. dispatch_test_start("Dispatch Cascade");
  104. for (i = 0; i < QUEUES; ++i) {
  105. queues[i] = dispatch_queue_create(NULL, NULL);
  106. }
  107. for (i = 0; i < BLOCKS; ++i) {
  108. cascade(&indices[i].index);
  109. }
  110. dispatch_main();
  111. return 0;
  112. }