/* * Copyright (c) 2008-2011 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ #include #include #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) #include #endif #include #include #include "dispatch_test.h" int done = 0; #define QUEUES 80 dispatch_queue_t queues[QUEUES]; #define BLOCKS 10000 union { size_t index; char padding[64]; } indices[BLOCKS]; size_t iterations = (QUEUES * BLOCKS) / 4; static void noop(void *ctxt __attribute__((unused))) { return; } static void cleanup(void *ctxt __attribute__((unused))) { size_t q; for (q = 0; q < QUEUES; ++q) { dispatch_sync_f(queues[q], NULL, noop); dispatch_release(queues[q]); } test_stop(); exit(0); } static void histogram(void) { size_t counts[QUEUES] = {}; size_t maxcount = 0; size_t q; for (q = 0; q < QUEUES; ++q) { size_t i; for (i = 0; i < BLOCKS; ++i) { if (indices[i].index == q) { ++counts[q]; } } } for (q = 0; q < QUEUES; ++q) { if (counts[q] > maxcount) { maxcount = counts[q]; } } printf("maxcount = %zd\n", maxcount); size_t x,y; for (y = 20; y > 0; --y) { for (x = 0; x < QUEUES; ++x) { double fraction = (double)counts[x] / (double)maxcount; double value = fraction * (double)20; printf("%s", (value > y) ? "*" : " "); } printf("\n"); } } static void cascade(void* context) { size_t idx, *idxptr = context; if (done) return; idx = *idxptr + 1; if (idx < QUEUES) { *idxptr = idx; dispatch_async_f(queues[idx], context, cascade); } if (__sync_sub_and_fetch(&iterations, 1) == 0) { done = 1; histogram(); dispatch_async_f(dispatch_get_main_queue(), NULL, cleanup); } } int main(int argc __attribute__((unused)), char* argv[] __attribute__((unused))) { int i; dispatch_test_start("Dispatch Cascade"); for (i = 0; i < QUEUES; ++i) { queues[i] = dispatch_queue_create(NULL, NULL); } for (i = 0; i < BLOCKS; ++i) { cascade(&indices[i].index); } dispatch_main(); return 0; }