Tizen 2.1 base
[platform/upstream/gcd.git] / dispatch-1.0 / testing / dispatch_starfish.c
1 /*
2  * Copyright (c) 2008-2009 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
21 #include "config/config.h"
22
23 #include <dispatch/dispatch.h>
24 #include "src/internal.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <assert.h>
28 #if HAVE_TARGETCONDITIONALS_H
29 #include <TargetConditionals.h>
30 #endif
31
32 #include "dispatch_test.h"
33
34 #if TARGET_OS_EMBEDDED
35 #define COUNT   300ul
36 #define LAPS    10ul
37 #else
38 #define COUNT   1000ul
39 #define LAPS    10ul
40 #endif
41
42 static dispatch_queue_t queues[COUNT];
43 static size_t lap_count_down = LAPS;
44 static size_t count_down;
45 static uint64_t start;
46
47 static void do_test(void);
48
49 static void
50 collect(void *context __attribute__((unused)))
51 {
52         uint64_t delta;
53         long double math;
54         size_t i;
55
56         if (--count_down) {
57                 return;
58         }
59
60         delta = _dispatch_absolute_time() - start;
61         math = delta = _dispatch_time_mach2nano(delta);
62         math /= COUNT * COUNT * 2ul + COUNT * 2ul;
63
64         printf("lap: %ld\n", lap_count_down);
65         printf("count: %lu\n", COUNT);
66         printf("delta: %ju ns\n", (uintmax_t)delta);
67         printf("math: %Lf ns / lap\n", math);
68
69         for (i = 0; i < COUNT; i++) {
70                 dispatch_release(queues[i]);
71         }
72
73         // our malloc could be a lot better,
74         // this result is really a malloc torture test
75         test_long_less_than("Latency" , (unsigned long)math, 1000);
76
77         if (--lap_count_down) {
78                 return do_test();
79         }
80
81         // give the threads some time to settle before test_stop() runs "leaks"
82         // ...also note, this is a total cheat.   dispatch_after lets this
83         // thread go idle, so dispatch cleans up the continuations cache.
84         // Doign the "old style" sleep left that stuff around and leaks
85         // took a LONG TIME to complete.   Long enough that the test harness
86         // decided to kill us.
87         dispatch_after_f(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), NULL, test_stop_after_delay);
88 }
89
90 static void
91 pong(void *context)
92 {
93         dispatch_queue_t this_q = context;
94         size_t replies = (size_t)dispatch_get_context(this_q);
95
96         dispatch_set_context(this_q, (void *)--replies);
97         if (!replies) {
98                 //printf("collect from: %s\n", dispatch_queue_get_label(dispatch_get_current_queue()));
99                 dispatch_async_f(dispatch_get_main_queue(), NULL, collect);
100         }
101 }
102
103 static void
104 ping(void *context)
105 {
106         dispatch_queue_t reply_q = context;
107
108         dispatch_async_f(reply_q, reply_q, pong);
109 }
110
111 static void
112 start_node(void *context)
113 {
114         dispatch_queue_t this_q = context;
115         size_t i;
116
117         dispatch_set_context(this_q, (void *)COUNT);
118
119         for (i = 0; i < COUNT; i++) {
120                 dispatch_async_f(queues[i], this_q, ping);
121         }
122 }
123
124 void
125 do_test(void)
126 {
127         size_t i;
128
129         count_down = COUNT;
130
131         start = _dispatch_absolute_time();
132
133         for (i = 0; i < COUNT; i++) {
134                 char buf[1000];
135                 snprintf(buf, sizeof(buf), "com.example.starfish-node#%ld", i);
136                 queues[i] = dispatch_queue_create(buf, NULL);
137                 dispatch_suspend(queues[i]);
138         }
139
140         for (i = 0; i < COUNT; i++) {
141                 dispatch_async_f(queues[i], queues[i], start_node);
142         }
143
144         for (i = 0; i < COUNT; i++) {
145                 dispatch_resume(queues[i]);
146         }
147 }
148
149 int
150 main(void)
151 {
152     test_start("Dispatch Starfish");
153
154         do_test();
155
156         dispatch_main();
157 }