mirror of
https://github.com/darlinghq/darling-libdispatch.git
synced 2024-11-23 12:09:44 +00:00
5bceb4b74b
They were imported from apple/swift-corelibs-libdispatch@34f383d344, so the tests are slightly newer than the actual libdispatch code, but that shouldn't be a problem.
173 lines
3.9 KiB
C
173 lines
3.9 KiB
C
/*
|
|
* 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@
|
|
*/
|
|
|
|
|
|
#ifdef __APPLE__
|
|
#include <mach/mach.h>
|
|
#include <mach/mach_time.h>
|
|
#endif
|
|
#include <dispatch/dispatch.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#ifdef __APPLE__
|
|
#include <TargetConditionals.h>
|
|
#endif
|
|
|
|
#include <bsdtests.h>
|
|
#include "dispatch_test.h"
|
|
|
|
#define COUNT 1000ul
|
|
#define LAPS 10ul
|
|
|
|
#if LENIENT_DEADLINES
|
|
#define ACCEPTABLE_LATENCY 10000
|
|
#elif TARGET_OS_EMBEDDED
|
|
#define ACCEPTABLE_LATENCY 3000
|
|
#else
|
|
#define ACCEPTABLE_LATENCY 1000
|
|
#endif
|
|
|
|
static dispatch_queue_t queues[COUNT];
|
|
static size_t lap_count_down = LAPS;
|
|
static size_t count_down;
|
|
static uint64_t start;
|
|
static mach_timebase_info_data_t tbi;
|
|
|
|
static void do_test(void);
|
|
|
|
static void
|
|
collect(void *context __attribute__((unused)))
|
|
{
|
|
uint64_t delta;
|
|
long double math;
|
|
size_t i;
|
|
|
|
if (--count_down) {
|
|
return;
|
|
}
|
|
|
|
delta = mach_absolute_time() - start;
|
|
delta *= tbi.numer;
|
|
delta /= tbi.denom;
|
|
math = delta;
|
|
math /= COUNT * COUNT * 2ul + COUNT * 2ul;
|
|
|
|
printf("lap: %zd\n", lap_count_down);
|
|
printf("count: %lu\n", COUNT);
|
|
printf("delta: %lu ns\n", (unsigned long)delta);
|
|
printf("math: %Lf ns / lap\n", math);
|
|
|
|
for (i = 0; i < COUNT; i++) {
|
|
dispatch_release(queues[i]);
|
|
}
|
|
|
|
// our malloc could be a lot better,
|
|
// this result is really a malloc torture test
|
|
test_long_less_than("Latency" , (long)math, ACCEPTABLE_LATENCY);
|
|
|
|
if (--lap_count_down) {
|
|
return do_test();
|
|
}
|
|
|
|
// give the threads some time to settle before test_stop() runs "leaks"
|
|
// ...also note, this is a total cheat. dispatch_after lets this
|
|
// thread go idle, so dispatch cleans up the continuations cache.
|
|
// Doign the "old style" sleep left that stuff around and leaks
|
|
// took a LONG TIME to complete. Long enough that the test harness
|
|
// decided to kill us.
|
|
dispatch_after_f(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), NULL, test_stop_after_delay);
|
|
}
|
|
|
|
static void
|
|
pong(void *context)
|
|
{
|
|
dispatch_queue_t this_q = context;
|
|
size_t replies = (size_t)dispatch_get_context(this_q);
|
|
|
|
dispatch_set_context(this_q, (void *)--replies);
|
|
if (!replies) {
|
|
//printf("collect from: %s\n", dispatch_queue_get_label(dispatch_get_current_queue()));
|
|
dispatch_async_f(dispatch_get_main_queue(), NULL, collect);
|
|
}
|
|
}
|
|
|
|
static void
|
|
ping(void *context)
|
|
{
|
|
dispatch_queue_t reply_q = context;
|
|
|
|
dispatch_async_f(reply_q, reply_q, pong);
|
|
}
|
|
|
|
static void
|
|
start_node(void *context)
|
|
{
|
|
dispatch_queue_t this_q = context;
|
|
size_t i;
|
|
|
|
dispatch_set_context(this_q, (void *)COUNT);
|
|
|
|
for (i = 0; i < COUNT; i++) {
|
|
dispatch_async_f(queues[i], this_q, ping);
|
|
}
|
|
}
|
|
|
|
void
|
|
do_test(void)
|
|
{
|
|
dispatch_queue_t soup = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
|
|
kern_return_t kr;
|
|
char buf[1000];
|
|
size_t i;
|
|
|
|
count_down = COUNT;
|
|
|
|
kr = mach_timebase_info(&tbi);
|
|
assert(kr == 0);
|
|
|
|
start = mach_absolute_time();
|
|
|
|
for (i = 0; i < COUNT; i++) {
|
|
snprintf(buf, sizeof(buf), "com.example.starfish-node#%zd", i);
|
|
queues[i] = dispatch_queue_create(buf, NULL);
|
|
dispatch_suspend(queues[i]);
|
|
dispatch_set_target_queue(queues[i], soup);
|
|
}
|
|
|
|
for (i = 0; i < COUNT; i++) {
|
|
dispatch_async_f(queues[i], queues[i], start_node);
|
|
}
|
|
|
|
for (i = 0; i < COUNT; i++) {
|
|
dispatch_resume(queues[i]);
|
|
}
|
|
}
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
dispatch_test_start("Dispatch Starfish");
|
|
|
|
do_test();
|
|
|
|
dispatch_main();
|
|
}
|