From source_changes at macosforge.org Wed Aug 8 22:09:03 2012 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 08 Aug 2012 22:09:03 -0700 (PDT) Subject: [libdispatch-changes] [215] trunk Message-ID: <20120809050904.04CD978205FD@lists.macosforge.org> Revision: 215 http://trac.macosforge.org/projects/libdispatch/changeset/215 Author: dsteffen at apple.com Date: 2012-08-08 22:09:03 -0700 (Wed, 08 Aug 2012) Log Message: ----------- MountainLion macosforge testsuite Modified Paths: -------------- trunk/Makefile.am trunk/configure.ac trunk/testing/Makefile.am trunk/testing/bench.mm trunk/testing/bsdtestharness.c trunk/testing/bsdtests.c trunk/testing/bsdtests.h trunk/testing/dispatch_after.c trunk/testing/dispatch_api.c trunk/testing/dispatch_apply.c trunk/testing/dispatch_concur.c trunk/testing/dispatch_deadname.c trunk/testing/dispatch_drift.c trunk/testing/dispatch_group.c trunk/testing/dispatch_io.c trunk/testing/dispatch_priority.c trunk/testing/dispatch_queue_finalizer.c trunk/testing/dispatch_suspend_timer.c trunk/testing/dispatch_test.c trunk/testing/dispatch_test.h trunk/testing/dispatch_timer.c trunk/testing/dispatch_timer_bit31.c trunk/testing/dispatch_timer_set_time.c trunk/testing/dispatch_vm.c Added Paths: ----------- trunk/testing/dispatch_transform.c Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/Makefile.am 2012-08-09 05:09:03 UTC (rev 215) @@ -9,7 +9,8 @@ man \ os \ private \ - src + src \ + testing EXTRA_DIST= \ LICENSE \ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/configure.ac 2012-08-09 05:09:03 UTC (rev 215) @@ -295,5 +295,11 @@ # # Generate Makefiles. # -AC_CONFIG_FILES([Makefile dispatch/Makefile man/Makefile os/Makefile private/Makefile src/Makefile]) +AC_CONFIG_FILES([Makefile dispatch/Makefile man/Makefile os/Makefile private/Makefile src/Makefile testing/Makefile]) + +# +# Generate testsuite links +# +AC_CONFIG_LINKS([testing/dispatch:${x:+}private testing/bench.cc:testing/bench.mm testing/leaks-wrapper:testing/leaks-wrapper.sh]) + AC_OUTPUT Modified: trunk/testing/Makefile.am =================================================================== --- trunk/testing/Makefile.am 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/Makefile.am 2012-08-09 05:09:03 UTC (rev 215) @@ -62,17 +62,16 @@ dispatch_vnode \ dispatch_select -dispatch_c99_CFLAGS=-std=c99 +dispatch_c99_CFLAGS=$(AM_CFLAGS) -std=c99 dispatch_plusplus_SOURCES=dispatch_plusplus.cpp dispatch_priority2_SOURCES=dispatch_priority.c -dispatch_priority2_CFLAGS=-DUSE_SET_TARGET_QUEUE=1 +dispatch_priority2_CPPFLAGS=$(AM_CPPFLAGS) -DUSE_SET_TARGET_QUEUE=1 -INCLUDES=-I$(top_builddir) -I$(top_srcdir) +AM_CPPFLAGS=-I$(top_builddir) -I$(top_srcdir) -CPPFLAGS= -CFLAGS=-Wall -g $(MARCH_FLAGS) $(CBLOCKS_FLAGS) -OBJCFLAGS=-Wall -g $(MARCH_FLAGS) $(CBLOCKS_FLAGS) -CXXFLAGS=-Wall -g $(MARCH_FLAGS) $(CXXBLOCKS_FLAGS) +AM_CFLAGS=-Wall $(MARCH_FLAGS) $(CBLOCKS_FLAGS) +AM_OBJCFLAGS=-Wall $(MARCH_FLAGS) $(CBLOCKS_FLAGS) -fobjc-gc +AM_CXXFLAGS=-Wall $(MARCH_FLAGS) $(CXXBLOCKS_FLAGS) LDADD=libbsdtests.la ../src/libdispatch.la libbsdtests_la_LDFLAGS=-avoid-version @@ -83,10 +82,12 @@ if HAVE_COREFOUNDATION TESTS+= \ dispatch_cf_main \ + dispatch_transform \ dispatch_sync_on_main \ cffd dispatch_cf_main_LDFLAGS=-framework CoreFoundation +dispatch_transform_LDFLAGS=-framework CoreFoundation -framework Security dispatch_sync_on_main_LDFLAGS=-framework CoreFoundation cffd_LDFLAGS=-framework CoreFoundation endif @@ -99,14 +100,13 @@ bench dispatch_sync_gc_SOURCES=dispatch_sync_gc.m -dispatch_sync_gc_OBJCFLAGS=-fobjc-gc dispatch_sync_gc_LDFLAGS=-framework Foundation dispatch_apply_gc_SOURCES=dispatch_apply_gc.m -dispatch_apply_gc_OBJCFLAGS=-fobjc-gc dispatch_apply_gc_LDFLAGS=-framework Foundation nsoperation_SOURCES=nsoperation.m nsoperation_LDFLAGS=-framework Foundation -bench_SOURCES=bench.cc func.c +nodist_bench_SOURCES=bench.cc +bench_SOURCES=func.c bench_LDFLAGS=-framework Foundation # Workaround missing objcxx support in older autotools bench.o: bench.cc Modified: trunk/testing/bench.mm =================================================================== --- trunk/testing/bench.mm 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/bench.mm 2012-08-09 05:09:03 UTC (rev 215) @@ -416,6 +416,13 @@ s = mach_absolute_time(); for (i = cnt; i; i--) { + global = 0; + asm volatile("mfence" ::: "memory"); + } + print_result(s, "Store + mfence:"); + + s = mach_absolute_time(); + for (i = cnt; i; i--) { unsigned long _clbr; #ifdef __LP64__ asm volatile("cpuid" : "=a" (_clbr) @@ -466,9 +473,36 @@ print_result(s, "'dmb ishst' instruction:"); #endif +#ifdef _ARM_ARCH_7 s = mach_absolute_time(); for (i = cnt; i; i--) { + asm volatile("str %[_r], [%[_p], %[_o]]" : + : [_p] "p" (&global), [_o] "M" (0), [_r] "r" (0) : "memory"); + asm volatile("dmb ishst" : : : "memory"); + } + print_result(s, "'str + dmb ishst' instructions:"); +#endif + #ifdef _ARM_ARCH_7 + s = mach_absolute_time(); + for (i = cnt; i; i--) { + uintptr_t prev; + uint32_t t; + do { + asm volatile("ldrex %[_r], [%[_p], %[_o]]" + : [_r] "=&r" (prev) \ + : [_p] "p" (&global), [_o] "M" (0) : "memory"); + asm volatile("strex %[_t], %[_r], [%[_p], %[_o]]" + : [_t] "=&r" (t) \ + : [_p] "p" (&global), [_o] "M" (0), [_r] "r" (0) : "memory"); + } while (t); + } + print_result(s, "'ldrex + strex' instructions:"); +#endif + + s = mach_absolute_time(); + for (i = cnt; i; i--) { +#ifdef _ARM_ARCH_7 asm volatile("dsb ish" : : : "memory"); #else asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) : "memory"); @@ -528,6 +562,37 @@ } print_result(s, "Atomic increment:"); + { + global = 0; + volatile int32_t *g = &global; + + s = mach_absolute_time(); + for (i = cnt; i; i--) { + uint32_t result; + __sync_and_and_fetch(g, 1); + result = *g; + if (result) { + abort(); + } + } + print_result(s, "Atomic and-and-fetch, reloading result:"); + } + + { + global = 0; + volatile int32_t *g = &global; + + s = mach_absolute_time(); + for (i = cnt; i; i--) { + uint32_t result; + result = __sync_and_and_fetch(g, 1); + if (result) { + abort(); + } + } + print_result(s, "Atomic and-and-fetch, using result:"); + } + global = 0; s = mach_absolute_time(); Modified: trunk/testing/bsdtestharness.c =================================================================== --- trunk/testing/bsdtestharness.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/bsdtestharness.c 2012-08-09 05:09:03 UTC (rev 215) @@ -18,7 +18,6 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -#include #include #include #include @@ -26,7 +25,10 @@ #include #include #include +#include #include +#include +#include #include @@ -37,19 +39,31 @@ { dispatch_source_t tmp_ds; int res; - pid_t pid; + pid_t pid = 0; if (argc < 2) { fprintf(stderr, "usage: %s [...]\n", argv[0]); exit(1); } + short spawnflags = POSIX_SPAWN_START_SUSPENDED; +#if TARGET_OS_EMBEDDED + spawnflags |= POSIX_SPAWN_SETEXEC; +#endif + posix_spawnattr_t attr; res = posix_spawnattr_init(&attr); assert(res == 0); - res = posix_spawnattr_setflags(&attr, POSIX_SPAWN_START_SUSPENDED); + res = posix_spawnattr_setflags(&attr, spawnflags); assert(res == 0); + uint64_t to = 0; + char *tos = getenv("BSDTEST_TIMEOUT"); + if (tos) { + to = strtoul(tos, NULL, 0); + to *= NSEC_PER_SEC; + } + char *arch = getenv("BSDTEST_ARCH"); if (arch) { const NXArchInfo *ai = NXGetArchInfoFromName(arch); @@ -66,12 +80,21 @@ } newargv[i-1] = NULL; - res = posix_spawnp(&pid, newargv[0], NULL, &attr, newargv, environ); - if (res) { - errno = res; - perror(newargv[0]); - exit(EXIT_FAILURE); + struct timeval tv_start; + gettimeofday(&tv_start, NULL); + + if (spawnflags & POSIX_SPAWN_SETEXEC) { + pid = fork(); } + if (!pid) { + res = posix_spawnp(&pid, newargv[0], NULL, &attr, newargv, environ); + if (res) { + errno = res; + perror(newargv[0]); + exit(EXIT_FAILURE); + } + } + //fprintf(stderr, "pid = %d\n", pid); assert(pid > 0); @@ -81,23 +104,40 @@ assert(tmp_ds); dispatch_source_set_event_handler(tmp_ds, ^{ int status; - int res2 = waitpid(pid, &status, 0); + struct rusage usage; + struct timeval tv_stop, tv_wall; + + gettimeofday(&tv_stop, NULL); + tv_wall.tv_sec = tv_stop.tv_sec - tv_start.tv_sec; + tv_wall.tv_sec -= (tv_stop.tv_usec < tv_start.tv_usec); + tv_wall.tv_usec = abs(tv_stop.tv_usec - tv_start.tv_usec); + + int res2 = wait4(pid, &status, 0, &usage); assert(res2 != -1); test_long("Process exited", (WIFEXITED(status) && WEXITSTATUS(status) && WEXITSTATUS(status) != 0xff) || WIFSIGNALED(status), 0); + printf("[PERF]\twall time: %ld.%06d\n", tv_wall.tv_sec, tv_wall.tv_usec); + printf("[PERF]\tuser time: %ld.%06d\n", usage.ru_utime.tv_sec, usage.ru_utime.tv_usec); + printf("[PERF]\tsystem time: %ld.%06d\n", usage.ru_stime.tv_sec, usage.ru_stime.tv_usec); + printf("[PERF]\tmax resident set size: %ld\n", usage.ru_maxrss); + printf("[PERF]\tpage faults: %ld\n", usage.ru_majflt); + printf("[PERF]\tswaps: %ld\n", usage.ru_nswap); + printf("[PERF]\tvoluntary context switches: %ld\n", usage.ru_nvcsw); + printf("[PERF]\tinvoluntary context switches: %ld\n", usage.ru_nivcsw); exit((WIFEXITED(status) && WEXITSTATUS(status)) || WIFSIGNALED(status)); }); dispatch_resume(tmp_ds); + if (!to) { #if TARGET_OS_EMBEDDED - // Give embedded platforms a little more time. - uint64_t timeout = 300LL * NSEC_PER_SEC; + to = 180LL * NSEC_PER_SEC; #else - uint64_t timeout = 150LL * NSEC_PER_SEC; + to = 90LL * NSEC_PER_SEC; #endif + } - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeout), main_q, ^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, to), main_q, ^{ kill(pid, SIGKILL); - fprintf(stderr, "Terminating unresponsive process (%0.1lfs)\n", (double)timeout/NSEC_PER_SEC); + fprintf(stderr, "Terminating unresponsive process (%0.1lfs)\n", (double)to / NSEC_PER_SEC); }); signal(SIGINT, SIG_IGN); @@ -109,6 +149,9 @@ }); dispatch_resume(tmp_ds); + if (spawnflags & POSIX_SPAWN_SETEXEC) { + usleep(USEC_PER_SEC/10); + } kill(pid, SIGCONT); dispatch_main(); Modified: trunk/testing/bsdtests.c =================================================================== --- trunk/testing/bsdtests.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/bsdtests.c 2012-08-09 05:09:03 UTC (rev 215) @@ -127,6 +127,18 @@ _test_ptr(NULL, 0, desc, actual, expected); } +void _test_ptr_not(const char* file, long line, const char* desc, const void* actual, const void* expected) +{ + _test_print(file, line, desc, + (actual != expected), "%p", actual, "!%p", expected); +} + +void test_ptr_not_format(const void *actual, const void* expected, const char *format, ...) +{ + GENERATE_DESC + _test_ptr_not(NULL, 0, desc, actual, expected); +} + void _test_uint32(const char* file, long line, const char* desc, uint32_t actual, uint32_t expected) { @@ -211,6 +223,19 @@ } void +_test_long_less_than_or_equal(const char* file, long line, const char* desc, long actual, long expected_max) +{ + _test_print(file, line, desc, (actual <= expected_max), "%ld", actual, "<=%ld", expected_max); +} + +void +test_long_less_than_or_equal_format(long actual, long expected_max, const char* format, ...) +{ + GENERATE_DESC + _test_long_less_than_or_equal(NULL, 0, desc, actual, expected_max); +} + +void _test_long_greater_than_or_equal(const char* file, long line, const char* desc, long actual, long expected_min) { _test_print(file, line, desc, (actual >= expected_min), "%ld", actual, ">=%ld", expected_min); @@ -250,6 +275,20 @@ } void +_test_double_equal(const char* file, long line, const char* desc, double val, double expected) +{ + _test_print(file, line, desc, (val == expected), "%f", val, "%f", expected); +} + + +void +test_double_equal_format(double val, double expected, const char *format, ...) +{ + GENERATE_DESC + _test_double_equal(NULL, 0, desc, val, expected); +} + +void _test_errno(const char* file, long line, const char* desc, long actual, long expected) { char* actual_str; @@ -386,6 +425,10 @@ return; } + unsetenv("DYLD_IMAGE_SUFFIX"); + unsetenv("DYLD_INSERT_LIBRARIES"); + unsetenv("DYLD_LIBRARY_PATH"); + unsetenv("MallocStackLogging"); unsetenv("MallocStackLoggingNoCompact"); Modified: trunk/testing/bsdtests.h =================================================================== --- trunk/testing/bsdtests.h 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/bsdtests.h 2012-08-09 05:09:03 UTC (rev 215) @@ -18,10 +18,21 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ +#ifndef __BSD_TEST_H__ +#define __BSD_TEST_H__ + #include #include #include +static inline const char* +__BASENAME__(const char *_str_) +{ + const char *_s_ = strrchr(_str_, '/'); + return (_s_ ? _s_ : _str_ - 1) + 1; +} +#define __SOURCE_FILE__ __BASENAME__(__FILE__) + __BEGIN_DECLS /** @@ -47,67 +58,81 @@ * that is printed after the token. */ void _test_ptr_null(const char* file, long line, const char* desc, const void* ptr); -#define test_ptr_null(a,b) _test_ptr_null(__FILE__, __LINE__, a, b) +#define test_ptr_null(a,b) _test_ptr_null(__SOURCE_FILE__, __LINE__, a, b) void test_ptr_null_format(void *ptr, const char *format, ...); void _test_ptr_notnull(const char* file, long line, const char* desc, const void* ptr); -#define test_ptr_notnull(a,b) _test_ptr_notnull(__FILE__, __LINE__, a, b) +#define test_ptr_notnull(a,b) _test_ptr_notnull(__SOURCE_FILE__, __LINE__, a, b) void test_ptr_notnull_format(const void *ptr, const char *format, ...) __printflike(2, 3); +void _test_ptr_not(const char* file, long line, const char* desc, const void* actual, const void* expected); +#define test_ptr_not(a, b, c) _test_ptr_not(__SOURCE_FILE__, __LINE__, a, b, c) +void test_ptr_not_format(const void* actual, const void* expected, const char *format, ...); + void _test_ptr(const char* file, long line, const char* desc, const void* actual, const void* expected); -#define test_ptr(a,b,c) _test_ptr(__FILE__, __LINE__, a, b, c) +#define test_ptr(a,b,c) _test_ptr(__SOURCE_FILE__, __LINE__, a, b, c) void test_ptr_format(const void* actual, const void* expected, const char *format, ...) __printflike(3,4); void _test_uint32(const char* file, long line, const char* desc, uint32_t actual, uint32_t expected); -#define test_uint32(a,b,c) _test_uint32(__FILE__, __LINE__, a, b, c) +#define test_uint32(a,b,c) _test_uint32(__SOURCE_FILE__, __LINE__, a, b, c) void test_uint32_format(long actual, long expected, const char *format, ...) __printflike(3,4); void _test_int32(const char* file, long line, const char* desc, int32_t actual, int32_t expected); -#define test_int32(a,b,c) _test_int32(__FILE__, __LINE__, a, b, c) +#define test_int32(a,b,c) _test_int32(__SOURCE_FILE__, __LINE__, a, b, c) void test_sint32_format(int32_t actual, int32_t expected, const char* format, ...) __printflike(3,4); void _test_long(const char* file, long line, const char* desc, long actual, long expected); -#define test_long(a,b,c) _test_long(__FILE__, __LINE__, a, b, c) +#define test_long(a,b,c) _test_long(__SOURCE_FILE__, __LINE__, a, b, c) void test_long_format(long actual, long expected, const char *format, ...) __printflike(3,4); void _test_uint64(const char* file, long line, const char* desc, uint64_t actual, uint64_t expected); -#define test_uint64(a,b,c) _test_uint64(__FILE__, __LINE__, a, b, c) +#define test_uint64(a,b,c) _test_uint64(__SOURCE_FILE__, __LINE__, a, b, c) void test_uint64_format(uint64_t actual, uint64_t expected, const char* desc, ...); void _test_int64(const char* file, long line, const char* desc, int64_t actual, int64_t expected); -#define test_int64(a,b,c) _test_uint64(__FILE__, __LINE__, a, b, c) +#define test_int64(a,b,c) _test_uint64(__SOURCE_FILE__, __LINE__, a, b, c) void test_int64_format(int64_t actual, int64_t expected, const char* desc, ...); void _test_long_less_than(const char* file, long line, const char* desc, long actual, long max_expected); -#define test_long_less_than(a,b,c) _test_long_less_than(__FILE__, __LINE__, a, b, c) +#define test_long_less_than(a,b,c) _test_long_less_than(__SOURCE_FILE__, __LINE__, a, b, c) void test_long_less_than_format(long actual, long max_expected, const char *format, ...) __printflike(3,4); +void _test_long_less_than_or_equal(const char* file, long line, const char* desc, long actual, long max_expected); +#define test_long_less_than_or_equal(a,b,c) _test_long_less_than_or_equal(__SOURCE_FILE__, __LINE__, a, b, c) +void test_long_less_than_or_equal_format(long actual, long max_expected, const char *format, ...) __printflike(3,4); + void _test_long_greater_than_or_equal(const char* file, long line, const char* desc, long actual, long expected_min); -#define test_long_greater_than_or_equal(a,b,c) _test_long_greater_than_or_equal(__FILE__, __LINE__, a, b, c) +#define test_long_greater_than_or_equal(a,b,c) _test_long_greater_than_or_equal(__SOURCE_FILE__, __LINE__, a, b, c) void test_long_greater_than_or_equal_format(long actual, long expected_min, const char *format, ...) __printflike(3,4); void _test_double_less_than_or_equal(const char* file, long line, const char* desc, double val, double max_expected); -#define test_double_less_than_or_equal(d, v, m) _test_double_less_than_or_equal(__FILE__, __LINE__, d, v, m) +#define test_double_less_than_or_equal(d, v, m) _test_double_less_than_or_equal(__SOURCE_FILE__, __LINE__, d, v, m) void test_double_less_than_or_equal_format(double val, double max_expected, const char *format, ...) __printflike(3,4); void _test_double_less_than(const char* file, long line, const char* desc, double val, double max_expected); -#define test_double_less_than(d, v, m) _test_double_less_than(__FILE__, __LINE__, d, v, m) +#define test_double_less_than(d, v, m) _test_double_less_than(__SOURCE_FILE__, __LINE__, d, v, m) void test_double_less_than_format(double val, double max_expected, const char *format, ...) __printflike(3,4); +void _test_double_equal(const char* file, long line, const char* desc, double val, double expected); +#define test_double_equal(d, v, m) _test_double_equal(__SOURCE_FILE__, __LINE__, d, v, m) +void test_double_equal_format(double val, double expected, const char *format, ...) __printflike(3,4); + void _test_errno(const char* file, long line, const char* desc, long actual, long expected); -#define test_errno(a,b,c) _test_errno(__FILE__, __LINE__, a, b, c) +#define test_errno(a,b,c) _test_errno(__SOURCE_FILE__, __LINE__, a, b, c) void test_errno_format(long actual, long expected, const char *format, ...) __printflike(3,4); void _test_mach_error(const char* file, long line, const char* desc, mach_error_t actual, mach_error_t expected); -#define test_mach_error(a,b,c) _test_mach_error(__FILE__, __LINE__, a, b, c) +#define test_mach_error(a,b,c) _test_mach_error(__SOURCE_FILE__, __LINE__, a, b, c) void test_mach_error_format(mach_error_t actual, mach_error_t expected, const char *format, ...) __printflike(3,4); void test_cferror(const char* desc, CFErrorRef actual, CFIndex expectedCode); void test_cferror_format(CFErrorRef actual, CFIndex expectedCode, const char *format, ...) __printflike(3,4); void _test_skip(const char* file, long line, const char* desc); -#define test_skip(m) _test_skip(__FILE__, __LINE__, m) +#define test_skip(m) _test_skip(__SOURCE_FILE__, __LINE__, m) #define test_skip2(m) _test_skip("", 0, m) void test_skip_format(const char *format, ...) __printflike(1,2); __END_DECLS + +#endif /* __BSD_TEST_H__ */ Modified: trunk/testing/dispatch_after.c =================================================================== --- trunk/testing/dispatch_after.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_after.c 2012-08-09 05:09:03 UTC (rev 215) @@ -50,7 +50,7 @@ time_a_min = dispatch_time(0, 5.5*NSEC_PER_SEC); time_a = dispatch_time(0, 6*NSEC_PER_SEC); time_a_max = dispatch_time(0, 6.5*NSEC_PER_SEC); - dispatch_after(time_a, dispatch_get_current_queue(), ^{ + dispatch_after(time_a, dispatch_get_main_queue(), ^{ dispatch_time_t now_a = dispatch_time(0, 0); test_long_less_than("can't finish faster than 5.5s", 0, now_a - time_a_min); test_long_less_than("must finish faster than 6.5s", 0, time_a_max - now_a); @@ -58,7 +58,7 @@ time_b_min = dispatch_time(0, 1.5*NSEC_PER_SEC); time_b = dispatch_time(0, 2*NSEC_PER_SEC); time_b_max = dispatch_time(0, 2.5*NSEC_PER_SEC); - dispatch_after(time_b, dispatch_get_current_queue(), ^{ + dispatch_after(time_b, dispatch_get_main_queue(), ^{ dispatch_time_t now_b = dispatch_time(0, 0); test_long_less_than("can't finish faster than 1.5s", 0, now_b - time_b_min); test_long_less_than("must finish faster than 2.5s", 0, time_b_max - now_b); @@ -66,12 +66,12 @@ time_c_min = dispatch_time(0, 0*NSEC_PER_SEC); time_c = dispatch_time(0, 0*NSEC_PER_SEC); time_c_max = dispatch_time(0, .5*NSEC_PER_SEC); - dispatch_after(time_c, dispatch_get_current_queue(), ^{ + dispatch_after(time_c, dispatch_get_main_queue(), ^{ dispatch_time_t now_c = dispatch_time(0, 0); test_long_less_than("can't finish faster than 0s", 0, now_c - time_c_min); test_long_less_than("must finish faster than .5s", 0, time_c_max - now_c); - dispatch_async_f(dispatch_get_current_queue(), NULL, done); + dispatch_async_f(dispatch_get_main_queue(), NULL, done); }); }); }); Modified: trunk/testing/dispatch_api.c =================================================================== --- trunk/testing/dispatch_api.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_api.c 2012-08-09 05:09:03 UTC (rev 215) @@ -33,8 +33,9 @@ int main(void) { + dispatch_queue_t q; dispatch_test_start("Dispatch (Public) API"); - dispatch_queue_t q = dispatch_get_main_queue(); + q = dispatch_get_main_queue(); test_ptr_notnull("dispatch_get_main_queue", q); dispatch_async_f(dispatch_get_main_queue(), NULL, work); Modified: trunk/testing/dispatch_apply.c =================================================================== --- trunk/testing/dispatch_apply.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_apply.c 2012-08-09 05:09:03 UTC (rev 215) @@ -24,10 +24,88 @@ #include #include #include +#include +#include #include #include "dispatch_test.h" +static volatile int32_t busy_threads_started, busy_threads_finished; + +/* + * Keep a thread busy, spinning on the CPU. + */ +#if TARGET_OS_EMBEDDED +// iPhone 4 +#define ITERS_PER_SECOND 50000000UL +#else +// On a 2.7 4-core i5 iMac12,2, one thread of this loop runs at ROUGHLY: +#define ITERS_PER_SECOND 1000000000UL +#endif + +/* Fiddling with j in the middle and hitting this global will hopefully keep + * the optimizer from cutting the whole thing out as dead code. + */ +static volatile unsigned int busythread_useless; +void busythread(void *ignored) +{ + (void)ignored; + uint64_t i = 0, j = 0; + + OSAtomicIncrement32(&busy_threads_started); + + for(i = 0; i < 2*ITERS_PER_SECOND; i++) + { + if(i == 500000) { j -= busythread_useless; } + j += i; + } + + OSAtomicIncrement32(&busy_threads_finished); +} + +/* + * Test that dispatch_apply can make progress and finish, even if there are + * so many other running and unblocked workqueue threads that the apply's + * helper threads never get a chance to come up. + * + * dispatch_apply should not block waiting on other + * threads while calling thread is available + */ +void test_apply_contended(dispatch_queue_t dq) +{ + uint32_t activecpu; + size_t s = sizeof(activecpu); + sysctlbyname("hw.activecpu", &activecpu, &s, NULL, 0); + int tIndex, n_threads = activecpu; + dispatch_group_t grp = dispatch_group_create(); + + for(tIndex = 0; tIndex < n_threads; tIndex++) { + dispatch_group_async_f(grp, dq, NULL, busythread); + } + + // Spin until all the threads have actually started + while(busy_threads_started < n_threads) { + usleep(1); + } + + volatile __block int32_t count = 0; + const int32_t final = 32; + + unsigned int before = busy_threads_started; + dispatch_apply(final, dq, ^(size_t i __attribute__((unused))) { + OSAtomicIncrement32(&count); + }); + unsigned int after = busy_threads_finished; + + test_long("contended: threads started before apply", before, n_threads); + test_long("contended: count", count, final); + test_long("contended: threads finished before apply", after, 0); + + dispatch_group_wait(grp, DISPATCH_TIME_FOREVER); + dispatch_release(grp); + +} + int main(void) { @@ -54,6 +132,8 @@ }); test_long("nested count", count, final * final * final); + test_apply_contended(queue); + test_stop(); return 0; Modified: trunk/testing/dispatch_concur.c =================================================================== --- trunk/testing/dispatch_concur.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_concur.c 2012-08-09 05:09:03 UTC (rev 215) @@ -147,7 +147,7 @@ size_t c = __sync_add_and_fetch(&concur, 1), *m = ((size_t *)ctxt) + i; if (c > *m) *m = c; - usleep(10000); + usleep(100000); __sync_sub_and_fetch(&concur, 1); } Modified: trunk/testing/dispatch_deadname.c =================================================================== --- trunk/testing/dispatch_deadname.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_deadname.c 2012-08-09 05:09:03 UTC (rev 215) @@ -32,18 +32,17 @@ #if TEST_MACHPORT_DEBUG #define test_mach_assume_zero(x) ({kern_return_t _kr = (x); \ if (_kr) fprintf(stderr, "mach error 0x%x \"%s\": %s\n", \ - _kr, mach_error_string(_kr), #x); _kr; }) + _kr, mach_error_string(_kr), #x); (void)kr; }) void -test_mach_debug_port(mach_port_t name, const char *str) +test_mach_debug_port(mach_port_t name, const char *str, unsigned int line) { mach_port_type_t type; mach_msg_bits_t ns = 0, nr = 0, nso = 0, nd = 0; unsigned int dnreqs = 0, dnrsiz; kern_return_t kr = mach_port_type(mach_task_self(), name, &type); - if (kr) { - fprintf(stderr, "machport[0x%08x] = { error(0x%x) \"%s\" }: %s\n", - name, kr, mach_error_string(kr), str); + fprintf(stderr, "machport[0x%08x] = { error(0x%x) \"%s\" }: %s %u\n", + name, kr, mach_error_string(kr), str, line); return; } if (type & MACH_PORT_TYPE_SEND) { @@ -58,8 +57,7 @@ test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name, MACH_PORT_RIGHT_DEAD_NAME, &nd)); } - if (type & (MACH_PORT_TYPE_RECEIVE|MACH_PORT_TYPE_SEND| - MACH_PORT_TYPE_SEND_ONCE)) { + if (type & (MACH_PORT_TYPE_RECEIVE|MACH_PORT_TYPE_SEND)) { test_mach_assume_zero(mach_port_dnrequest_info(mach_task_self(), name, &dnrsiz, &dnreqs)); } @@ -71,24 +69,28 @@ test_mach_assume_zero(mach_port_get_attributes(mach_task_self(), name, MACH_PORT_RECEIVE_STATUS, (void*)&status, &cnt)); fprintf(stderr, "machport[0x%08x] = { R(%03u) S(%03u) SO(%03u) D(%03u) " - "dnreqs(%03u) nsreq(%s) pdreq(%s) srights(%s) sorights(%03u) " - "qlim(%03u) msgcount(%03u) mkscount(%03u) seqno(%03u) }: %s\n", - name, nr, ns, nso, nd, dnreqs, status.mps_nsrequest ? "Y":"N", - status.mps_pdrequest ? "Y":"N", status.mps_srights ? "Y":"N", - status.mps_sorights, status.mps_qlimit, status.mps_msgcount, - status.mps_mscount, status.mps_seqno, str); + "dnreqs(%03u) spreq(%s) nsreq(%s) pdreq(%s) srights(%s) " + "sorights(%03u) qlim(%03u) msgcount(%03u) mkscount(%03u) " + "seqno(%03u) }: %s %u\n", name, nr, ns, nso, nd, dnreqs, + type & MACH_PORT_TYPE_SPREQUEST ? "Y":"N", + status.mps_nsrequest ? "Y":"N", status.mps_pdrequest ? "Y":"N", + status.mps_srights ? "Y":"N", status.mps_sorights, + status.mps_qlimit, status.mps_msgcount, status.mps_mscount, + status.mps_seqno, str, line); } else if (type & (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_SEND_ONCE| MACH_PORT_TYPE_DEAD_NAME)) { fprintf(stderr, "machport[0x%08x] = { R(%03u) S(%03u) SO(%03u) D(%03u) " - "dnreqs(%03u) }: %s\n", name, nr, ns, nso, nd, dnreqs, str); + "dnreqs(%03u) spreq(%s) }: %s %u\n", name, nr, ns, nso, nd, + dnreqs, type & MACH_PORT_TYPE_SPREQUEST ? "Y":"N", str, line); } else { - fprintf(stderr, "machport[0x%08x] = { type(0x%08x) }: %s\n", name, type, - str); + fprintf(stderr, "machport[0x%08x] = { type(0x%08x) }: %s %u\n", name, + type, str, line); } + fflush(stderr); } -#define test_mach_debug_port(x) test_mach_debug_port(x, __func__) +#define test_mach_debug_port(x) test_mach_debug_port(x, __func__, __LINE__) #else -#define test_mach_debug_port(x) +#define test_mach_debug_port(x) (void)(x) #endif static dispatch_group_t g; @@ -112,6 +114,11 @@ dispatch_source_set_event_handler(ds0, ^{ test_long("DISPATCH_MACH_SEND_DEAD", dispatch_source_get_handle(ds0), mp); + dispatch_source_cancel(ds0); + }); + dispatch_source_set_cancel_handler(ds0, ^{ + kern_return_t kr = mach_port_deallocate(mach_task_self(), mp); + test_mach_error("mach_port_deallocate", kr, KERN_SUCCESS); dispatch_release(ds0); dispatch_group_leave(g); }); @@ -431,6 +438,7 @@ dispatch_source_cancel(ds); dispatch_release(ds); test_long("DISPATCH_SOURCE_TYPE_MACH_RECV", received, 0); + dispatch_group_wait(g, DISPATCH_TIME_FOREVER); } int Modified: trunk/testing/dispatch_drift.c =================================================================== --- trunk/testing/dispatch_drift.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_drift.c 2012-08-09 05:09:03 UTC (rev 215) @@ -28,19 +28,16 @@ #include #include "dispatch_test.h" -#if TARGET_OS_EMBEDDED -#define ACCEPTABLE_DRIFT 0.002 -#else #define ACCEPTABLE_DRIFT 0.001 -#endif int main(int argc __attribute__((unused)), char* argv[] __attribute__((unused))) { __block uint32_t count = 0; __block double last_jitter = 0; - // 10 times a second - uint64_t interval = 1000000000 / 10; + __block double drift_sum = 0; + // 100 times a second + uint64_t interval = 1000000000 / 100; double interval_d = interval / 1000000000.0; // for 25 seconds unsigned int target = 25 / interval_d; @@ -67,15 +64,17 @@ double goal = first + interval_d * count; double jitter = goal - now; double drift = jitter - last_jitter; + drift_sum += drift; printf("%4d: jitter %f, drift %f\n", count, jitter, drift); if (target <= ++count) { - if (drift < 0) { - drift = -drift; + drift_sum /= count - 1; + if (drift_sum < 0) { + drift_sum = -drift_sum; } double acceptable_drift = ACCEPTABLE_DRIFT; - test_double_less_than("drift", drift, acceptable_drift); + test_double_less_than("drift", drift_sum, acceptable_drift); test_stop(); } last_jitter = jitter; Modified: trunk/testing/dispatch_group.c =================================================================== --- trunk/testing/dispatch_group.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_group.c 2012-08-09 05:09:03 UTC (rev 215) @@ -33,6 +33,14 @@ #define NSEC_PER_SEC 1000000000 #endif +#if TARGET_OS_EMBEDDED +#define LOOP_COUNT 50000 +#else +#define LOOP_COUNT 200000 +#endif + +static void test_group_notify(void*); + dispatch_group_t create_group(size_t count, int delay) { @@ -57,13 +65,10 @@ return group; } -int -main(void) +static void +test_group(void *ctxt __attribute__((unused))) { long res; - - dispatch_test_start("Dispatch Group"); - dispatch_group_t group; group = create_group(100, 0); @@ -95,15 +100,95 @@ test_ptr_notnull("dispatch_group_async", group); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ - dispatch_queue_t m = dispatch_get_main_queue(); - dispatch_queue_t c = dispatch_get_current_queue(); - test_ptr("Notification Received", m, c); - test_stop(); + dispatch_test_current("Notification Received", dispatch_get_main_queue()); + dispatch_async_f(dispatch_get_main_queue(), NULL, test_group_notify); }); dispatch_release(group); group = NULL; +} +static long completed; + +static void +test_group_notify2(long cycle, dispatch_group_t tested) +{ + static dispatch_queue_t rq, nq; + static dispatch_once_t once; + dispatch_once(&once, ^{ + rq = dispatch_queue_create("release", 0); + dispatch_suspend(rq); + nq = dispatch_queue_create("notify", 0); + }); + dispatch_resume(rq); + + // n=4 works great for a 4CPU Mac Pro, this might work for a wider range of + // systems. + const int n = 1 + arc4random() % 8; + dispatch_group_t group = dispatch_group_create(); + dispatch_queue_t qa[n]; + + dispatch_group_enter(group); + for (int i = 0; i < n; i++) { + char buf[48]; + sprintf(buf, "T%ld-%d", cycle, i); + qa[i] = dispatch_queue_create(buf, 0); + } + + __block float eh = 0; + for (int i = 0; i < n; i++) { + dispatch_queue_t q = qa[i]; + dispatch_group_async(group, q, ^{ + // Seems to trigger a little more reliably with some work being + // done in this block + eh = sin(M_1_PI / cycle); + }); + } + dispatch_group_leave(group); + + dispatch_group_notify(group, nq, ^{ + completed = cycle; + dispatch_group_leave(tested); + }); + + // Releasing qa's queues here seems to avoid the race, so we are arranging + // for the current iteration's queues to be released on the next iteration. + dispatch_sync(rq, ^{}); + dispatch_suspend(rq); + for (int i = 0; i < n; i++) { + dispatch_queue_t q = qa[i]; + dispatch_async(rq, ^{ dispatch_release(q); }); + } + dispatch_release(group); +} + +static void +test_group_notify(void *ctxt __attribute__((unused))) +{ + // + dispatch_group_t tested = dispatch_group_create(); + test_ptr_notnull("dispatch_group_create", tested); + long i; + for (i = 0; i < LOOP_COUNT; i++) { + if (!((i+1) % (LOOP_COUNT/10))) { + fprintf(stderr, "#%ld\n", i+1); + } + dispatch_group_enter(tested); + test_group_notify2(i, tested); + if (dispatch_group_wait(tested, dispatch_time(DISPATCH_TIME_NOW, + NSEC_PER_SEC))) { + break; + } + } + test_long("dispatch_group_notify", i, LOOP_COUNT); + test_stop(); +} + +int +main(void) +{ + dispatch_test_start("Dispatch Group"); + dispatch_async_f(dispatch_get_main_queue(), NULL, test_group); dispatch_main(); return 0; Modified: trunk/testing/dispatch_io.c =================================================================== --- trunk/testing/dispatch_io.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_io.c 2012-08-09 05:09:03 UTC (rev 215) @@ -65,7 +65,7 @@ #endif static void -test_io_close(int with_timer) +test_io_close(int with_timer, bool from_path) { #define chunks 4 #define READSIZE (512*1024) @@ -80,8 +80,8 @@ test_errno("open", errno, 0); test_stop(); } - if (fcntl(fd, F_NOCACHE, 1)) { - test_errno("fcntl F_NOCACHE", errno, 0); + if (fcntl(fd, F_GLOBAL_NOCACHE, 1) == -1) { + test_errno("fcntl F_GLOBAL_NOCACHE", errno, 0); test_stop(); } struct stat sb; @@ -94,12 +94,21 @@ dispatch_source_t t = NULL; dispatch_group_t g = dispatch_group_create(); dispatch_group_enter(g); - dispatch_io_t io = dispatch_io_create(DISPATCH_IO_RANDOM, fd, - dispatch_get_global_queue(0, 0), ^(int error) { + void (^cleanup_handler)(int error) = ^(int error) { test_errno("create error", error, 0); dispatch_group_leave(g); close(fd); - }); + }; + dispatch_io_t io; + if (!from_path) { + io = dispatch_io_create(DISPATCH_IO_RANDOM, fd, + dispatch_get_global_queue(0, 0), cleanup_handler); + } else { +#if DISPATCHTEST_IO_PATH + io = dispatch_io_create_with_path(DISPATCH_IO_RANDOM, path, O_RDONLY, 0, + dispatch_get_global_queue(0, 0), cleanup_handler); +#endif + } dispatch_io_set_high_water(io, READSIZE); if (with_timer == 1) { dispatch_io_set_low_water(io, READSIZE); @@ -147,7 +156,8 @@ } }); } - dispatch_io_close(io, /* NO STOP */ 0); + dispatch_io_close(io, 0); + dispatch_io_close(io, 0); dispatch_io_read(io, 0, 1, dispatch_get_global_queue(0,0), ^(bool done, dispatch_data_t d, int error) { test_long("closed done", done, true); @@ -332,8 +342,8 @@ test_stop(); } // disable caching also for extra fd opened by dispatch_io_create_with_path - if (fcntl(fd, F_GLOBAL_NOCACHE, 1)) { - test_errno("fcntl F_GLOBAL_NOCACHE failed", errno, 0); + if (fcntl(fd, F_GLOBAL_NOCACHE, 1) == -1) { + test_errno("fcntl F_GLOBAL_NOCACHE", errno, 0); test_stop(); } switch (option) { @@ -476,7 +486,7 @@ static void test_read_many_files(void) { - char *paths[] = {"/usr/include", NULL}; + char *paths[] = {"/usr/lib", NULL}; dispatch_group_t g = dispatch_group_create(); dispatch_semaphore_t s = dispatch_semaphore_create(maxopenfiles); uint64_t start; @@ -664,9 +674,15 @@ dispatch_test_start("Dispatch IO"); dispatch_async(dispatch_get_main_queue(), ^{ #if DISPATCHTEST_IO - test_io_close(0 /* without timer */ ); - test_io_close(1 /* with channel interval */); - test_io_close(2 /* with external timer */); + int i; bool from_path = false; + do { + for (i = 0; i < 3; i++) { + test_io_close(i, from_path); + } +#if DISPATCHTEST_IO_PATH + from_path = !from_path; +#endif + } while (from_path); test_io_stop(); test_io_from_io(); test_io_read_write(); Modified: trunk/testing/dispatch_priority.c =================================================================== --- trunk/testing/dispatch_priority.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_priority.c 2012-08-09 05:09:03 UTC (rev 215) @@ -34,32 +34,40 @@ static volatile int done; #ifdef DISPATCH_QUEUE_PRIORITY_BACKGROUND // - -#define PRIORITIES 4 -char *labels[PRIORITIES] = { "BACKGROUND", "LOW", "DEFAULT", "HIGH" }; -int priorities[PRIORITIES] = { DISPATCH_QUEUE_PRIORITY_BACKGROUND, DISPATCH_QUEUE_PRIORITY_LOW, DISPATCH_QUEUE_PRIORITY_DEFAULT, DISPATCH_QUEUE_PRIORITY_HIGH }; - +#define USE_BACKGROUND_PRIORITY 1 #else +#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN +#endif -#define PRIORITIES 3 -char *labels[PRIORITIES] = { "LOW", "DEFAULT", "HIGH" }; -int priorities[PRIORITIES] = { DISPATCH_QUEUE_PRIORITY_LOW, DISPATCH_QUEUE_PRIORITY_DEFAULT, DISPATCH_QUEUE_PRIORITY_HIGH }; +#define QUEUE_PRIORITY_PTHREAD INT_MAX +#if DISPATCH_API_VERSION < 20100518 // +#define DISPATCH_QUEUE_CONCURRENT NULL #endif #if TARGET_OS_EMBEDDED -#define LOOP_COUNT 2000000 +#define LOOP_COUNT 5000000 +const int importance = 24; // priority 55 #else #define LOOP_COUNT 100000000 +const int importance = 4; // priority 35 #endif +char *labels[] = { "BACKGROUND", "LOW", "DEFAULT", "HIGH", }; +int levels[] = { + DISPATCH_QUEUE_PRIORITY_BACKGROUND, DISPATCH_QUEUE_PRIORITY_LOW, + DISPATCH_QUEUE_PRIORITY_DEFAULT, DISPATCH_QUEUE_PRIORITY_HIGH, +}; +#define PRIORITIES (sizeof(levels)/sizeof(*levels)) + static union { long count; char padding[64]; } counts[PRIORITIES]; -#define ITERATIONS (long)(PRIORITIES * n_blocks() * 0.50) static volatile long iterations; +static long total; +static size_t prio0, priorities = PRIORITIES; int n_blocks(void) @@ -78,11 +86,12 @@ void histogram(void) { - long total = 0; - size_t x,y; - for (y = 0; y < PRIORITIES; ++y) { + long completed = 0; + size_t x, y, i; + printf("\n"); + for (y = prio0; y < prio0 + priorities; ++y) { printf("%s: %ld\n", labels[y], counts[y].count); - total += counts[y].count; + completed += counts[y].count; double fraction = (double)counts[y].count / (double)n_blocks(); double value = fraction * (double)80; @@ -92,9 +101,19 @@ printf("\n"); } - test_long("blocks completed", total, ITERATIONS); - test_long_less_than("high priority precedence", counts[0].count, - counts[PRIORITIES-1].count); + test_long("blocks completed", completed, total); + for (i = prio0; i < prio0 + priorities; i++) { + if (levels[i] == DISPATCH_QUEUE_PRIORITY_HIGH) { + test_long_less_than_or_equal("high priority precedence", + counts[i-2].count, counts[i].count); + } +#if USE_BACKGROUND_PRIORITY + if (levels[i] == DISPATCH_QUEUE_PRIORITY_BACKGROUND) { + test_long_less_than_or_equal("background priority precedence", + counts[i].count, counts[i+2].count); + } +#endif + } } void @@ -115,8 +134,10 @@ __sync_add_and_fetch(&done, 1); usleep(100000); histogram(); - test_stop(); - exit(0); + dispatch_time_t delay = DISPATCH_TIME_NOW; + dispatch_after(delay, dispatch_get_main_queue(), ^{ + test_stop(); + }); } } } @@ -136,43 +157,46 @@ main(int argc __attribute__((unused)), char* argv[] __attribute__((unused))) { dispatch_queue_t q[PRIORITIES]; - int i; + size_t i; - iterations = ITERATIONS; +#if !USE_BACKGROUND_PRIORITY + prio0++; + priorities--; +#endif + iterations = total = (priorities * n_blocks()) * 0.50; + #if USE_SET_TARGET_QUEUE dispatch_test_start("Dispatch Priority (Set Target Queue)"); - for(i = 0; i < PRIORITIES; i++) { -#if DISPATCH_API_VERSION < 20100518 // - q[i] = dispatch_queue_create(labels[i], NULL); #else + dispatch_test_start("Dispatch Priority"); +#endif + + for (i = prio0; i < prio0 + priorities; i++) { + dispatch_queue_t rq = dispatch_get_global_queue(levels[i], 0); +#if USE_SET_TARGET_QUEUE q[i] = dispatch_queue_create(labels[i], DISPATCH_QUEUE_CONCURRENT); -#endif test_ptr_notnull("q[i]", q[i]); assert(q[i]); dispatch_suspend(q[i]); - dispatch_set_target_queue(q[i], dispatch_get_global_queue(priorities[i], 0)); -#if DISPATCH_API_VERSION < 20100518 // - dispatch_queue_set_width(q[i], LONG_MAX); + dispatch_set_target_queue(q[i], rq); + if (DISPATCH_QUEUE_CONCURRENT != NULL) { + dispatch_queue_set_width(q[i], LONG_MAX); + } + dispatch_release(rq); +#else + q[i] = rq; #endif } -#else - dispatch_test_start("Dispatch Priority"); - for(i = 0; i < PRIORITIES; i++) { - q[i] = dispatch_get_global_queue(priorities[i], 0); - } -#endif - for(i = 0; i < PRIORITIES; i++) { + for (i = prio0; i < prio0 + priorities; i++) { submit_work(q[i], &counts[i].count); } -#if USE_SET_TARGET_QUEUE - for(i = 0; i < PRIORITIES; i++) { + for (i = prio0; i < prio0 + priorities; i++) { dispatch_resume(q[i]); dispatch_release(q[i]); } -#endif dispatch_main(); Modified: trunk/testing/dispatch_queue_finalizer.c =================================================================== --- trunk/testing/dispatch_queue_finalizer.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_queue_finalizer.c 2012-08-09 05:09:03 UTC (rev 215) @@ -69,6 +69,7 @@ dispatch_queue_t q_null_context = dispatch_queue_create("com.apple.testing.finalizer.context_null", NULL); dispatch_set_context(q_null_context, NULL); + dispatch_set_finalizer_f(q_null_context, never_call); dispatch_release(q_null_context); // Don't test k Modified: trunk/testing/dispatch_suspend_timer.c =================================================================== --- trunk/testing/dispatch_suspend_timer.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_suspend_timer.c 2012-08-09 05:09:03 UTC (rev 215) @@ -45,7 +45,7 @@ dispatch_test_start("Dispatch Suspend Timer"); dispatch_queue_t main_q = dispatch_get_main_queue(); - test_ptr("dispatch_get_main_queue", main_q, dispatch_get_current_queue()); + //test_ptr("dispatch_get_main_queue", main_q, dispatch_get_current_queue()); __block int i = 0, i_prime = 0; __block int j = 0; Modified: trunk/testing/dispatch_test.c =================================================================== --- trunk/testing/dispatch_test.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_test.c 2012-08-09 05:09:03 UTC (rev 215) @@ -19,15 +19,20 @@ */ #include "dispatch_test.h" +#include "bsdtests.h" #ifdef __OBJC_GC__ #include #endif +#include +#include #include #include #include +#include + void test_start(const char* desc); void @@ -56,3 +61,10 @@ close(kq); return r > 0; } + +void +_dispatch_test_current(const char* file, long line, const char* desc, dispatch_queue_t expected) +{ + dispatch_queue_t actual = dispatch_get_current_queue(); + _test_ptr(file, line, desc, actual, expected); +} Modified: trunk/testing/dispatch_test.h =================================================================== --- trunk/testing/dispatch_test.h 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_test.h 2012-08-09 05:09:03 UTC (rev 215) @@ -20,6 +20,7 @@ #include #include +#include #define test_group_wait(g) do { \ if (dispatch_group_wait(g, dispatch_time(DISPATCH_TIME_NOW, \ @@ -34,4 +35,7 @@ bool dispatch_test_check_evfilt_read_for_fd(int fd); +void _dispatch_test_current(const char* file, long line, const char* desc, dispatch_queue_t expected); +#define dispatch_test_current(a,b) _dispatch_test_current(__SOURCE_FILE__, __LINE__, a, b) + __END_DECLS Modified: trunk/testing/dispatch_timer.c =================================================================== --- trunk/testing/dispatch_timer.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_timer.c 2012-08-09 05:09:03 UTC (rev 215) @@ -46,7 +46,7 @@ const int stop_at = 3; dispatch_queue_t main_q = dispatch_get_main_queue(); - test_ptr("dispatch_get_main_queue", main_q, dispatch_get_current_queue()); + //test_ptr("dispatch_get_main_queue", main_q, dispatch_get_current_queue()); uint64_t j; @@ -73,16 +73,13 @@ __block int i = 0; dispatch_source_t s = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, main_q); - dispatch_debug(s, "fresh timer:"); test_ptr_notnull("dispatch_source_create", s); dispatch_source_set_timer(s, dispatch_time(DISPATCH_TIME_NOW, 0), NSEC_PER_SEC, 0); dispatch_source_set_cancel_handler(s, ^{ test_ptr_notnull("cancel handler run", s); - dispatch_debug(s, "pre release timer:"); dispatch_release(s); - dispatch_debug(s, "post release timer:"); }); dispatch_source_set_event_handler(s, ^{ Modified: trunk/testing/dispatch_timer_bit31.c =================================================================== --- trunk/testing/dispatch_timer_bit31.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_timer_bit31.c 2012-08-09 05:09:03 UTC (rev 215) @@ -34,7 +34,7 @@ dispatch_test_start("Dispatch Source Timer, bit 31"); dispatch_queue_t main_q = dispatch_get_main_queue(); - test_ptr("dispatch_get_main_queue", main_q, dispatch_get_current_queue()); + //test_ptr("dispatch_get_main_queue", main_q, dispatch_get_current_queue()); struct timeval start_time; Modified: trunk/testing/dispatch_timer_set_time.c =================================================================== --- trunk/testing/dispatch_timer_set_time.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_timer_set_time.c 2012-08-09 05:09:03 UTC (rev 215) @@ -35,7 +35,7 @@ dispatch_test_start("Dispatch Update Timer"); dispatch_queue_t main_q = dispatch_get_main_queue(); - test_ptr("dispatch_get_main_queue", main_q, dispatch_get_current_queue()); + //test_ptr("dispatch_get_main_queue", main_q, dispatch_get_current_queue()); __block int i = 0; struct timeval start_time; Added: trunk/testing/dispatch_transform.c =================================================================== --- trunk/testing/dispatch_transform.c (rev 0) +++ trunk/testing/dispatch_transform.c 2012-08-09 05:09:03 UTC (rev 215) @@ -0,0 +1,875 @@ +/* + * Copyright (c) 2011-2012 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 + +#if DISPATCH_API_VERSION >= 20111008 && !TARGET_OS_EMBEDDED + +#include + +#include +#include +#include + +#define printf_data(p, s) ({ \ + typeof(s) _i; \ + for (_i=0; _i UTF16LE)", transformed); + + dispatch_release(utf8_data); + + (void)context; +} + +void +truncated_utf8_test(void * context) +{ + dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8) - 3, NULL, ^{}); + + dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF8, DISPATCH_DATA_FORMAT_TYPE_UTF16LE); + test_ptr_null("dispatch_data_create_with_transform (UTF8 (truncated) -> UTF16LE)", transformed); + + dispatch_release(utf8_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, invalid_utf8_test); +} + +void +invalid_utf16le_surrogate_test(void * context) +{ + dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); + dispatch_data_t utf16_data = dispatch_data_create(utf16le_invalid, sizeof(utf16le_invalid), NULL, ^{}); + + dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16LE, DISPATCH_DATA_FORMAT_TYPE_UTF8); + test_ptr_null("dispatch_data_create_with_transform (UTF16LE (missing surrogate) -> UTF8)", transformed); + + dispatch_release(utf16_data); + dispatch_release(utf8_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, truncated_utf8_test); +} + +void +invalid_utf16le_test(void * context) +{ + dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); + dispatch_data_t utf16_data = dispatch_data_create(utf16, (sizeof(utf16) % 2) + 1, NULL, ^{}); + + dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16LE, DISPATCH_DATA_FORMAT_TYPE_UTF8); + test_ptr_null("dispatch_data_create_with_transform (UTF16LE (invalid) -> UTF8)", transformed); + + dispatch_release(utf16_data); + dispatch_release(utf8_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, invalid_utf16le_surrogate_test); +} + +void +utf16le_bytes_to_utf8_test(void * context) +{ + dispatch_data_t utf16_data = dispatch_data_empty; + dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); + + size_t i; + for (i=0; i UTF8)", transformed); + test_data_equal("utf16le_bytes_to_utf8_test", transformed, utf8_data); + + dispatch_release(transformed); + dispatch_release(utf8_data); + dispatch_release(utf16_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, invalid_utf16le_test); +} + +void +utf8_bytes_to_utf16le_test(void * context) +{ + dispatch_data_t utf8_data = dispatch_data_empty; + dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{}); + + size_t i; + for (i=0; i UTF16LE)", transformed); + test_data_equal("utf8_bytes_to_utf16le_test", transformed, utf16_data); + + dispatch_release(transformed); + dispatch_release(utf8_data); + dispatch_release(utf16_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16le_bytes_to_utf8_test); +} + +void +utf16be_detect_to_utf16le_test(void * context) +{ + dispatch_data_t utf16be_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{}); + dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{}); + + dispatch_data_t transformed = dispatch_data_create_with_transform(utf16be_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF16LE); + test_ptr_notnull("dispatch_data_create_with_transform (UTF16BE (any) -> UTF16LE)", transformed); + test_data_equal("utf16be_detect_to_utf16le_test", transformed, utf16_data); + + dispatch_release(transformed); + dispatch_release(utf16be_data); + dispatch_release(utf16_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf8_bytes_to_utf16le_test); +} + +void +utf16be_detect_to_utf8_test(void * context) +{ + dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); + dispatch_data_t utf16_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{}); + + dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF8); + test_ptr_notnull("dispatch_data_create_with_transform (UTF16BE (any) -> UTF8)", transformed); + test_data_equal("utf16be_detect_to_utf8_test", transformed, utf8_data); + + dispatch_release(transformed); + dispatch_release(utf16_data); + dispatch_release(utf8_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16be_detect_to_utf16le_test); +} + +void +utf16le_detect_to_utf8_test(void * context) +{ + dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); + dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{}); + + dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF8); + test_ptr_notnull("dispatch_data_create_with_transform (UTF16LE (any) -> UTF8)", transformed); + test_data_equal("utf16le_detect_to_utf8_test", transformed, utf8_data); + + dispatch_release(transformed); + dispatch_release(utf16_data); + dispatch_release(utf8_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16be_detect_to_utf8_test); +} + +void +utf16be_to_utf8_test(void * context) +{ + dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); + dispatch_data_t utf16_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{}); + + dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16BE, DISPATCH_DATA_FORMAT_TYPE_UTF8); + test_ptr_notnull("dispatch_data_create_with_transform (UTF16BE -> UTF8)", transformed); + test_data_equal("utf16be_to_utf8_test", transformed, utf8_data); + + dispatch_release(transformed); + dispatch_release(utf16_data); + dispatch_release(utf8_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16le_detect_to_utf8_test); +} + +void +utf16le_to_utf8_test(void * context) +{ + dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); + dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{}); + + dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16LE, DISPATCH_DATA_FORMAT_TYPE_UTF8); + test_ptr_notnull("dispatch_data_create_with_transform (UTF16LE -> UTF8)", transformed); + test_data_equal("utf16le_to_utf8_test", transformed, utf8_data); + + dispatch_release(transformed); + dispatch_release(utf16_data); + dispatch_release(utf8_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16be_to_utf8_test); +} + +void +utf8_to_utf16be_test(void * context) +{ + dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); + dispatch_data_t utf16_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{}); + + dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF8, DISPATCH_DATA_FORMAT_TYPE_UTF16BE); + test_ptr_notnull("dispatch_data_create_with_transform (UTF8 -> UTF16BE)", transformed); + test_data_equal("utf8_to_utf16be_test", transformed, utf16_data); + + dispatch_release(transformed); + dispatch_release(utf16_data); + dispatch_release(utf8_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16le_to_utf8_test); +} + +void +utf8_to_utf16le_test(void * context) +{ + dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); + dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{}); + + dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF8, DISPATCH_DATA_FORMAT_TYPE_UTF16LE); + test_ptr_notnull("dispatch_data_create_with_transform (UTF8 -> UTF16LE)", transformed); + test_data_equal("utf8_to_utf16le_test", transformed, utf16_data); + + dispatch_release(transformed); + dispatch_release(utf16_data); + dispatch_release(utf8_data); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf8_to_utf16be_test); +} + +#pragma mark - base32 tests + +void +decode32_corrupt_test(void * context) +{ + dispatch_group_enter((dispatch_group_t)context); + + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { + assert(error == 0); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + void * corrupt_buffer = malloc(dispatch_data_get_size(sectransform_data)); + const void * source; + size_t size; + + dispatch_data_t map = dispatch_data_create_map(sectransform_data, &source, &size); + memcpy(corrupt_buffer, source, size); + + size_t i; + for (i=0; i= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x >= '0' && x <= '9') || x == '/' || x == '+' || x == '=') { + x = arc4random() & 0xff; + } + + ((char*)corrupt_buffer)[i] = x; + } + + dispatch_release(map); + dispatch_release(sectransform_data); + + dispatch_data_t corrupt_data = dispatch_data_create(corrupt_buffer, size, dispatch_get_main_queue(), DISPATCH_DATA_DESTRUCTOR_FREE); + + dispatch_data_t transform_data = dispatch_data_create_with_transform(corrupt_data, DISPATCH_DATA_FORMAT_TYPE_BASE32, DISPATCH_DATA_FORMAT_TYPE_NONE); + test_ptr_null("decode32_corrupt_test: dispatch_data_create_with_transform", transform_data); + + dispatch_release(corrupt_data); + + close(fd); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf8_to_utf16le_test); + dispatch_group_leave((dispatch_group_t)context); + }); +} + +void +chunking_decode32_test(void * context) +{ + (void)context; + + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_data_t __block data = dispatch_data_empty; + + int i; + dispatch_group_t group = dispatch_group_create(); + dispatch_queue_t queue = dispatch_queue_create("read", 0); + for (i=0; i<4096; i++) { + dispatch_group_enter(group); + + dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) { + assert(error == 0); + + dispatch_data_t concat = dispatch_data_create_concat(data, d); + dispatch_release(data); + data = concat; + dispatch_group_leave(group); + }); + } + dispatch_group_wait(group, DISPATCH_TIME_FOREVER); + dispatch_release(queue); + dispatch_release(group); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + dispatch_data_t transformed_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE32, DISPATCH_DATA_FORMAT_TYPE_NONE); + test_ptr_notnull("chunking_decode32_test: dispatch_data_create_with_transform", transformed_data); + test_data_equal("chunking_decode32_test", transformed_data, data); + + dispatch_release(sectransform_data); + dispatch_release(transformed_data); + dispatch_release(data); + + close(fd); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, decode32_corrupt_test); +} + +void +chunking_encode32_test(void * context) +{ + (void)context; + + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_data_t __block data = dispatch_data_empty; + + int i; + dispatch_group_t group = dispatch_group_create(); + dispatch_queue_t queue = dispatch_queue_create("read", 0); + for (i=0; i<4096; i++) { + dispatch_group_enter(group); + + dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) { + assert(error == 0); + + dispatch_data_t concat = dispatch_data_create_concat(data, d); + dispatch_release(data); + data = concat; + dispatch_group_leave(group); + }); + } + dispatch_group_wait(group, DISPATCH_TIME_FOREVER); + dispatch_release(queue); + dispatch_release(group); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE32); + test_ptr_notnull("chunking_encode32_test: dispatch_data_create_with_transform", transformed_data); + test_data_equal("chunking_encode32_test", transformed_data, sectransform_data); + + dispatch_release(sectransform_data); + dispatch_release(transformed_data); + dispatch_release(data); + + close(fd); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, chunking_decode32_test); +} + +void +decode32_test(void * context) +{ + dispatch_group_enter((dispatch_group_t)context); + + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { + assert(error == 0); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + dispatch_data_t transform_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE32, DISPATCH_DATA_FORMAT_TYPE_NONE); + test_ptr_notnull("decode32_test: dispatch_data_create_with_transform", transform_data); + test_data_equal("decode32_test", transform_data, data); + + dispatch_release(sectransform_data); + dispatch_release(transform_data); + + close(fd); + + dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, chunking_encode32_test); + dispatch_group_leave((dispatch_group_t)context); + }); +} + +void +encode32_test(void * context) +{ + dispatch_group_enter((dispatch_group_t)context); + + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { + assert(error == 0); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE32); + test_ptr_notnull("encode32_test: dispatch_data_create_with_transform", transformed_data); + test_data_equal("encode32_test", transformed_data, sectransform_data); + + dispatch_release(sectransform_data); + dispatch_release(transformed_data); + + close(fd); + + dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, decode32_test); + dispatch_group_leave((dispatch_group_t)context); + }); +} + +#pragma mark - base64 tests + +void +decode64_loop_test(void * context) +{ + if (getenv("LOOP_SKIP") == NULL) + { + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + size_t i, __block tests = 0; + + for (i=1; i<4097; i++) { + dispatch_read(fd, i, dispatch_get_global_queue(0, 0), ^(dispatch_data_t data, int error) { + assert(error == 0); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + dispatch_data_t transform_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE); + if (dispatch_data_equal(transform_data, data)) { + tests++; + } + + dispatch_release(sectransform_data); + dispatch_release(transform_data); + + dispatch_semaphore_signal(sema); + }); + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + } + dispatch_release(sema); + close(fd); + test_long("decode64_loop_test", tests, 4096); + } + dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, encode32_test); +} + +void +decode64_corrupt_test(void * context) +{ + dispatch_group_enter((dispatch_group_t)context); + + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { + assert(error == 0); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + void * corrupt_buffer = malloc(dispatch_data_get_size(sectransform_data)); + const void * source; + size_t size; + + dispatch_data_t map = dispatch_data_create_map(sectransform_data, &source, &size); + memcpy(corrupt_buffer, source, size); + + size_t i; + for (i=0; i= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x >= '0' && x <= '9') || x == '/' || x == '+' || x == '=') { + x = arc4random() & 0xff; + } + + ((char*)corrupt_buffer)[i] = x; + } + + dispatch_release(map); + dispatch_release(sectransform_data); + + dispatch_data_t corrupt_data = dispatch_data_create(corrupt_buffer, size, dispatch_get_main_queue(), DISPATCH_DATA_DESTRUCTOR_FREE); + + dispatch_data_t transform_data = dispatch_data_create_with_transform(corrupt_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE); + test_ptr_null("decode64_corrupt_test: dispatch_data_create_with_transform", transform_data); + + dispatch_release(corrupt_data); + + close(fd); + + dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, decode64_loop_test); + dispatch_group_leave((dispatch_group_t)context); + }); +} + +void +chunking_decode64_test(void * context) +{ + (void)context; + + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_data_t __block data = dispatch_data_empty; + + int i; + dispatch_group_t group = dispatch_group_create(); + dispatch_queue_t queue = dispatch_queue_create("read", 0); + for (i=0; i<4096; i++) { + dispatch_group_enter(group); + + dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) { + assert(error == 0); + + dispatch_data_t concat = dispatch_data_create_concat(data, d); + dispatch_release(data); + data = concat; + dispatch_group_leave(group); + }); + } + dispatch_group_wait(group, DISPATCH_TIME_FOREVER); + dispatch_release(queue); + dispatch_release(group); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + dispatch_data_t transformed_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE); + test_ptr_notnull("chunking_decode64_test: dispatch_data_create_with_transform", transformed_data); + test_data_equal("chunking_decode64_test", transformed_data, data); + + dispatch_release(sectransform_data); + dispatch_release(transformed_data); + dispatch_release(data); + + close(fd); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, decode64_corrupt_test); +} + +void +chunking_encode64_test(void * context) +{ + (void)context; + + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_data_t __block data = dispatch_data_empty; + + int i; + dispatch_group_t group = dispatch_group_create(); + dispatch_queue_t queue = dispatch_queue_create("read", 0); + for (i=0; i<4097; i++) { + dispatch_group_enter(group); + + dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) { + assert(error == 0); + + dispatch_data_t concat = dispatch_data_create_concat(data, d); + dispatch_release(data); + data = concat; + dispatch_group_leave(group); + }); + } + dispatch_group_wait(group, DISPATCH_TIME_FOREVER); + dispatch_release(queue); + dispatch_release(group); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE64); + test_ptr_notnull("chunking_encode64_test: dispatch_data_create_with_transform", transformed_data); + test_data_equal("chunking_encode64_test", transformed_data, sectransform_data); + + dispatch_release(sectransform_data); + dispatch_release(transformed_data); + dispatch_release(data); + + close(fd); + + dispatch_group_async_f(context, dispatch_get_main_queue(), context, chunking_decode64_test); +} + +void +decode64_test(void * context) +{ + dispatch_group_enter((dispatch_group_t)context); + + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { + assert(error == 0); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + dispatch_data_t transform_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE); + test_ptr_notnull("decode64_test: dispatch_data_create_with_transform", transform_data); + test_data_equal("decode64_test", transform_data, data); + + dispatch_release(sectransform_data); + dispatch_release(transform_data); + + close(fd); + + dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, chunking_encode64_test); + dispatch_group_leave((dispatch_group_t)context); + }); +} + +void +encode64_test(void * context) +{ + dispatch_group_enter((dispatch_group_t)context); + + int fd = open("/dev/random", O_RDONLY); + assert(fd >= 0); + + dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { + assert(error == 0); + + SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); + assert(transformRef); + + dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); + assert(sectransform_data); + CFRelease(transformRef); + + dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE64); + test_ptr_notnull("encode64_test: dispatch_data_create_with_transform", transformed_data); + test_data_equal("encode64_test", transformed_data, sectransform_data); + + dispatch_release(sectransform_data); + dispatch_release(transformed_data); + + close(fd); + + dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, decode64_test); + dispatch_group_leave((dispatch_group_t)context); + }); +} + +#pragma mark - main + +int +main(void) +{ + test_start("Dispatch data transforms test"); + + dispatch_group_t group = dispatch_group_create(); + dispatch_group_async_f(group, dispatch_get_main_queue(), group, encode64_test); + + dispatch_group_notify(group, dispatch_get_main_queue(), ^{ + dispatch_release(group); + test_stop(); + exit(0); + }); + + dispatch_main(); + return 0; +} + +#else + +int +main(void) +{ + test_skip("Dispatch data transforms test"); + return 0; +} + +#endif + Modified: trunk/testing/dispatch_vm.c =================================================================== --- trunk/testing/dispatch_vm.c 2012-08-09 05:08:56 UTC (rev 214) +++ trunk/testing/dispatch_vm.c 2012-08-09 05:09:03 UTC (rev 215) @@ -29,6 +29,7 @@ #include #include +#include #include #include "dispatch_test.h" @@ -36,7 +37,7 @@ #if defined(DISPATCH_SOURCE_TYPE_VM) && defined(NOTE_VM_PRESSURE) #if TARGET_OS_EMBEDDED -#define ALLOC_SIZE ((size_t)(1024*1024*5ul)) // 5MB +#define ALLOC_SIZE ((size_t)(1024*1024*1ul)) // 1MB #define NOTIFICATIONS 1 #else #define ALLOC_SIZE ((size_t)(1024*1024*20ul)) // 20MB @@ -60,7 +61,7 @@ #define log_msg(msg, ...) \ do { \ - fprintf(stderr, "[%2ds] " msg, (int)(time(NULL) - initial), ## __VA_ARGS__);\ + fprintf(stderr, "[%2ds] " msg, (int)(time(NULL) - initial), ##__VA_ARGS__);\ } while (0) static bool @@ -102,7 +103,7 @@ int main(void) { - dispatch_test_start("Dispatch VM Pressure test"); // + dispatch_test_start("Dispatch VM Pressure test"); // rdar://problem/7000945 if (!dispatch_test_check_evfilt_vm()) { test_skip("EVFILT_VM not supported"); test_stop(); @@ -142,7 +143,8 @@ dispatch_resume(vm_source); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - while (handler_call_count < NOTIFICATIONS && page_count < max_page_count) { + while (handler_call_count < NOTIFICATIONS && + page_count < max_page_count) { void *p = valloc(ALLOC_SIZE); if (!p) { break; @@ -163,9 +165,12 @@ dispatch_async(vm_queue, ^{cleanup();}); return; } - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), vm_queue, ^{ - test_long_less_than("VM Pressure fired", NOTIFICATIONS - 1, handler_call_count); - test_long_less_than("VM Pressure stopped firing", handler_call_count, 4); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), + vm_queue, ^{ + test_long_greater_than_or_equal("VM Pressure fired", + handler_call_count, NOTIFICATIONS); + test_long_less_than("VM Pressure stopped firing", + handler_call_count, 4); cleanup(); }); }); @@ -176,7 +181,8 @@ int main(void) { - dispatch_test_start("Dispatch VM Pressure test - No DISPATCH_SOURCE_TYPE_VM"); + dispatch_test_start("Dispatch VM Pressure test" + " - No DISPATCH_SOURCE_TYPE_VM"); test_stop(); return 0; } -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Wed Aug 8 22:08:50 2012 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 08 Aug 2012 22:08:50 -0700 (PDT) Subject: [libdispatch-changes] [213] trunk/src/semaphore.c Message-ID: <20120809050850.EFD6A7820543@lists.macosforge.org> Revision: 213 http://trac.macosforge.org/projects/libdispatch/changeset/213 Author: dsteffen at apple.com Date: 2012-08-08 22:08:50 -0700 (Wed, 08 Aug 2012) Log Message: ----------- Modified Paths: -------------- trunk/src/semaphore.c Modified: trunk/src/semaphore.c =================================================================== --- trunk/src/semaphore.c 2012-08-09 05:08:47 UTC (rev 212) +++ trunk/src/semaphore.c 2012-08-09 05:08:50 UTC (rev 213) @@ -188,8 +188,7 @@ return 0; } if (slowpath(value == LONG_MIN)) { - DISPATCH_CLIENT_CRASH("Unbalanced call to dispatch_group_leave() or " - "dispatch_semaphore_signal()"); + DISPATCH_CLIENT_CRASH("Unbalanced call to dispatch_semaphore_signal()"); } return _dispatch_semaphore_signal_slow(dsema); } @@ -377,9 +376,12 @@ dispatch_group_leave(dispatch_group_t dg) { dispatch_semaphore_t dsema = (dispatch_semaphore_t)dg; - - dispatch_semaphore_signal(dsema); - if (dsema->dsema_value == dsema->dsema_orig) { + dispatch_atomic_release_barrier(); + long value = dispatch_atomic_inc2o(dsema, dsema_value); + if (slowpath(value == LONG_MIN)) { + DISPATCH_CLIENT_CRASH("Unbalanced call to dispatch_group_leave()"); + } + if (slowpath(value == dsema->dsema_orig)) { (void)_dispatch_group_wake(dsema); } } @@ -534,7 +536,7 @@ prev->dsn_next = dsn; } else { _dispatch_retain(dg); - dsema->dsema_notify_head = dsn; + (void)dispatch_atomic_xchg2o(dsema, dsema_notify_head, dsn); if (dsema->dsema_value == dsema->dsema_orig) { _dispatch_group_wake(dsema); } -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Wed Aug 8 22:08:56 2012 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 08 Aug 2012 22:08:56 -0700 (PDT) Subject: [libdispatch-changes] [214] trunk Message-ID: <20120809050856.73B167820585@lists.macosforge.org> Revision: 214 http://trac.macosforge.org/projects/libdispatch/changeset/214 Author: dsteffen at apple.com Date: 2012-08-08 22:08:56 -0700 (Wed, 08 Aug 2012) Log Message: ----------- autotools buildsystem and portability changes for MountainLion source Modified Paths: -------------- trunk/INSTALL trunk/Makefile.am trunk/config/config.h trunk/configure.ac trunk/man/Makefile.am trunk/os/object.h trunk/private/Makefile.am trunk/src/Makefile.am trunk/src/init.c trunk/src/transform.c Added Paths: ----------- trunk/os/Makefile.am Modified: trunk/INSTALL =================================================================== --- trunk/INSTALL 2012-08-09 05:08:50 UTC (rev 213) +++ trunk/INSTALL 2012-08-09 05:08:56 UTC (rev 214) @@ -45,6 +45,16 @@ The following options are likely to only be useful when building libdispatch on Mac OS X as a replacement for /usr/lib/system/libdispatch.dylib: +--with-apple-objc4-source + + Specify the path to Apple's objc4 package, so that appropriate headers can + be found and used. + +--with-apple-libauto-source + + Specify the path to Apple's libauto package, so that appropriate headers + can be found and used. + --disable-libdispatch-init-constructor Do not tag libdispatch's init routine as __constructor, in which case it @@ -61,16 +71,19 @@ Typical configuration commands The following command lines create the configuration required to build -libdispatch for /usr/lib/system on Mac OS X Lion: +libdispatch for /usr/lib/system on OS X MountainLion: sh autogen.sh - ./configure CFLAGS='-arch x86_64 -arch i386 -g -Os' \ + cflags='-arch x86_64 -arch i386 -g -Os' + ./configure CFLAGS="$cflags" OBJCFLAGS="$cflags" CXXFLAGS="$cflags" \ --prefix=/usr --libdir=/usr/lib/system \ --disable-dependency-tracking --disable-static \ --enable-apple-tsd-optimizations \ - --with-apple-libc-source=/path/to/10.7.0/Libc-763.11 \ - --with-apple-libclosure-source=/path/to/10.7.0/libclosure-53 \ - --with-apple-xnu-source=/path/to/10.7.0/xnu-1699.22.73 + --with-apple-libc-source=/path/to/10.8.0/Libc-825.24 \ + --with-apple-libclosure-source=/path/to/10.8.0/libclosure-59 \ + --with-apple-xnu-source=/path/to/10.8.0/xnu-2050.7.9 \ + --with-apple-objc4-source=/path/to/10.8.0/objc4-532 \ + --with-apple-libauto-source=/path/to/10.8.0/libauto-185.1 make check Typical configuration line for FreeBSD 8.x and 9.x to build libdispatch with Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2012-08-09 05:08:50 UTC (rev 213) +++ trunk/Makefile.am 2012-08-09 05:08:56 UTC (rev 214) @@ -7,6 +7,7 @@ SUBDIRS= \ dispatch \ man \ + os \ private \ src Modified: trunk/config/config.h =================================================================== --- trunk/config/config.h 2012-08-09 05:08:50 UTC (rev 213) +++ trunk/config/config.h 2012-08-09 05:08:56 UTC (rev 214) @@ -143,13 +143,13 @@ #define PACKAGE_NAME "libdispatch" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libdispatch 1.1" +#define PACKAGE_STRING "libdispatch 1.2" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libdispatch" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.1" +#define PACKAGE_VERSION "1.2" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 @@ -170,7 +170,7 @@ /* #undef USE_POSIX_SEM */ /* Version number of package */ -#define VERSION "1.1" +#define VERSION "1.2" /* Define to 1 if on AIX 3. System headers sometimes define this. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2012-08-09 05:08:50 UTC (rev 213) +++ trunk/configure.ac 2012-08-09 05:08:56 UTC (rev 214) @@ -3,7 +3,7 @@ # AC_PREREQ(2.59) -AC_INIT([libdispatch], [1.1], [libdispatch at macosforge.org], [libdispatch]) +AC_INIT([libdispatch], [1.2], [libdispatch at macosforge.org], [libdispatch]) AC_REVISION([$$]) AC_CONFIG_AUX_DIR(config) AC_CONFIG_HEADER([config/config.h]) @@ -37,10 +37,24 @@ [AS_HELP_STRING([--with-apple-xnu-source], [Specify path to Apple XNU source])], [ apple_xnu_source_libkern_path=${withval}/libkern + apple_xnu_source_bsd_path=${withval}/bsd apple_xnu_source_osfmk_path=${withval}/osfmk - CPPFLAGS="$CPPFLAGS -I$apple_xnu_source_libkern_path" + CPPFLAGS="$CPPFLAGS -idirafter $apple_xnu_source_libkern_path -isystem $apple_xnu_source_bsd_path" ]) +AC_ARG_WITH([apple-objc4-source], + [AS_HELP_STRING([--with-apple-objc4-source], + [Specify path to Apple objc4 source])], [ + apple_objc4_source_runtime_path=${withval}/runtime +]) + +AC_ARG_WITH([apple-libauto-source], + [AS_HELP_STRING([--with-apple-libauto-source], + [Specify path to Apple libauto source])], [ + apple_libauto_source_path=${withval} + CPPFLAGS="$CPPFLAGS -I$apple_libauto_source_path" +]) + AC_CACHE_CHECK([for System.framework/PrivateHeaders], dispatch_cv_system_privateheaders, [AS_IF([test -d /System/Library/Frameworks/System.framework/PrivateHeaders], [dispatch_cv_system_privateheaders=yes], [dispatch_cv_system_privateheaders=no])] @@ -78,17 +92,16 @@ ) AC_USE_SYSTEM_EXTENSIONS +AM_INIT_AUTOMAKE([foreign no-dependencies]) +LT_INIT([disable-static]) + AC_PROG_INSTALL -AC_PROG_LIBTOOL AC_PATH_PROGS(MIG, mig) - AC_PATH_PROG(LEAKS, leaks) AS_IF([test "x$LEAKS" != "x"], [AC_DEFINE(HAVE_LEAKS, 1, [Define if Apple leaks program is present])] ) -AM_INIT_AUTOMAKE([foreign]) - DISPATCH_C_ATOMIC_BUILTINS case $dispatch_cv_atomic in @@ -131,20 +144,43 @@ [ln -fsh "$apple_xnu_source_osfmk_path" src/System], [apple_xnu_source_osfmk_path="$apple_xnu_source_osfmk_path"]) ]) +# hack for xnu/bsd/sys/event.h EVFILT_SOCK declaration +AS_IF([test -n "$apple_xnu_source_bsd_path"], [ + CPPFLAGS="$CPPFLAGS -DPRIVATE=1" +]) # -# Parts of the testsuite use CoreFoundation and Foundation +# Check for CoreFoundation, Foundation and objc # AC_CHECK_HEADER([CoreFoundation/CoreFoundation.h], [have_corefoundation=true], [have_corefoundation=false] ) AM_CONDITIONAL(HAVE_COREFOUNDATION, $have_corefoundation) + AC_LANG_PUSH([Objective C]) -AC_CHECK_HEADER([Foundation/Foundation.h], [ - AC_DEFINE(USE_OBJC, 1, [Define to use Objective-C runtime]) - have_foundation=true], [have_foundation=false] +AC_CHECK_HEADER([Foundation/Foundation.h], + [have_foundation=true], [have_foundation=false] ) AM_CONDITIONAL(HAVE_FOUNDATION, $have_foundation) +# hack for objc4/runtime/objc-internal.h +AS_IF([test -n "$apple_objc4_source_runtime_path"], [ + saveCPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -I." + ln -fsh "$apple_objc4_source_runtime_path" objc +]) +AC_CHECK_HEADER([objc/objc-internal.h], [ + AC_DEFINE(USE_OBJC, 1, [Define to use Objective-C runtime]) + have_objc=true], [have_objc=false], + [#include ] +) +AS_IF([test -n "$apple_objc4_source_runtime_path"], [ + rm -f objc + CPPFLAGS="$saveCPPFLAGS" + AC_CONFIG_COMMANDS([src/objc], + [ln -fsh "$apple_objc4_source_runtime_path" src/objc], + [apple_objc4_source_runtime_path="$apple_objc4_source_runtime_path"]) +]) +AM_CONDITIONAL(USE_OBJC, $have_objc) AC_LANG_POP([Objective C]) # @@ -152,9 +188,9 @@ # of Machisms, including using Mach ports as event sources, etc. # AC_CHECK_HEADER([mach/mach.h], [ - AC_DEFINE(HAVE_MACH, 1, [Define if mach is present]) - AC_DEFINE(__DARWIN_NON_CANCELABLE, 1, [Define if using Darwin $NOCANCEL]) - have_mach=true], [have_mach=false] + AC_DEFINE(HAVE_MACH, 1, [Define if mach is present]) + AC_DEFINE(__DARWIN_NON_CANCELABLE, 1, [Define if using Darwin $NOCANCEL]) + have_mach=true], [have_mach=false] ) AM_CONDITIONAL(USE_MIG, $have_mach) @@ -239,7 +275,7 @@ AC_CACHE_CHECK([for darwin linker], [dispatch_cv_ld_darwin], [ saveLDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -dynamiclib -compatibility_version 1.2.3 -current_version 4.5.6" + LDFLAGS="$LDFLAGS -dynamiclib -compatibility_version 1.2.3 -current_version 4.5.6 -dead_strip" AC_LINK_IFELSE([AC_LANG_PROGRAM([ extern int foo; int foo;], [foo = 0;])], [dispatch_cv_ld_darwin="yes"], [dispatch_cv_ld_darwin="no"]) @@ -259,5 +295,5 @@ # # Generate Makefiles. # -AC_CONFIG_FILES([Makefile dispatch/Makefile man/Makefile private/Makefile src/Makefile]) +AC_CONFIG_FILES([Makefile dispatch/Makefile man/Makefile os/Makefile private/Makefile src/Makefile]) AC_OUTPUT Modified: trunk/man/Makefile.am =================================================================== --- trunk/man/Makefile.am 2012-08-09 05:08:50 UTC (rev 213) +++ trunk/man/Makefile.am 2012-08-09 05:08:56 UTC (rev 214) @@ -77,10 +77,8 @@ $(LN) -f dispatch_data_create.3 dispatch_data_create_subrange.3 && \ $(LN) -f dispatch_data_create.3 dispatch_data_create_map.3 && \ $(LN) -f dispatch_data_create.3 dispatch_data_apply.3 && \ - $(LN) -f dispatch_data_create.3 dispatch_data_copy_subrange.3 && \ $(LN) -f dispatch_data_create.3 dispatch_data_copy_region.3 && \ $(LN) -f dispatch_data_create.3 dispatch_data_get_size.3 && \ - $(LN) -f dispatch_data_create.3 dispatch_data_copy_subrange.3 && \ $(LN) -f dispatch_data_create.3 dispatch_data_empty.3 && \ $(LN) -f dispatch_io_create.3 dispatch_io_create_with_path.3 && \ $(LN) -f dispatch_io_create.3 dispatch_io_set_high_water.3 && \ @@ -139,10 +137,8 @@ dispatch_data_create_subrange.3 \ dispatch_data_create_map.3 \ dispatch_data_apply.3 \ - dispatch_data_copy_subrange.3 \ dispatch_data_copy_region.3 \ dispatch_data_get_size.3 \ - dispatch_data_copy_subrange.3 \ dispatch_data_empty.3 \ dispatch_io_create_with_path.3 \ dispatch_io_set_high_water.3 \ Added: trunk/os/Makefile.am =================================================================== --- trunk/os/Makefile.am (rev 0) +++ trunk/os/Makefile.am 2012-08-09 05:08:56 UTC (rev 214) @@ -0,0 +1,11 @@ +# +# +# + +osdir=$(includedir)/os + +os_HEADERS= \ + object.h + +noinst_HEADERS= \ + object_private.h Modified: trunk/os/object.h =================================================================== --- trunk/os/object.h 2012-08-09 05:08:50 UTC (rev 213) +++ trunk/os/object.h 2012-08-09 05:08:56 UTC (rev 214) @@ -49,7 +49,7 @@ */ #ifndef OS_OBJECT_HAVE_OBJC_SUPPORT -#if defined(__OBJC2__) && !defined(__OBJC_GC__) && ( \ +#if defined(__OBJC__) && defined(__OBJC2__) && !defined(__OBJC_GC__) && ( \ __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8 || \ __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0) #define OS_OBJECT_HAVE_OBJC_SUPPORT 1 Modified: trunk/private/Makefile.am =================================================================== --- trunk/private/Makefile.am 2012-08-09 05:08:50 UTC (rev 213) +++ trunk/private/Makefile.am 2012-08-09 05:08:56 UTC (rev 214) @@ -4,6 +4,8 @@ noinst_HEADERS= \ benchmark.h \ + data_private.h \ + dispatch.h \ private.h \ queue_private.h \ source_private.h Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2012-08-09 05:08:50 UTC (rev 213) +++ trunk/src/Makefile.am 2012-08-09 05:08:56 UTC (rev 214) @@ -16,6 +16,7 @@ semaphore.c \ source.c \ time.c \ + transform.c \ protocol.defs \ provider.d \ data_internal.h \ @@ -35,19 +36,30 @@ shims/time.h \ shims/tsd.h -INCLUDES=-I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/private +AM_CPPFLAGS=-I$(top_builddir) -I$(top_srcdir) \ + -I$(top_srcdir)/private -I$(top_srcdir)/os -libdispatch_la_CFLAGS=-Wall $(VISIBILITY_FLAGS) $(OMIT_LEAF_FP_FLAGS) -libdispatch_la_CFLAGS+=$(MARCH_FLAGS) $(CBLOCKS_FLAGS) $(KQUEUE_CFLAGS) +AM_CFLAGS=-Wall $(VISIBILITY_FLAGS) $(OMIT_LEAF_FP_FLAGS) \ + $(MARCH_FLAGS) $(CBLOCKS_FLAGS) $(KQUEUE_CFLAGS) libdispatch_la_LDFLAGS=-avoid-version if HAVE_DARWIN_LD -libdispatch_la_LDFLAGS+=-Wl,-compatibility_version,1 -Wl,-current_version,$(VERSION) +libdispatch_la_LDFLAGS+=-Wl,-compatibility_version,1 \ + -Wl,-current_version,$(VERSION) -Wl,-dead_strip endif +if USE_OBJC +libdispatch_la_SOURCES+=object.m +libdispatch_la_OBJCFLAGS=$(AM_CFLAGS) -fobjc-gc +libdispatch_la_LDFLAGS+=-Wl,-upward-lobjc -Wl,-upward-lauto \ + -Wl,-order_file,$(top_srcdir)/xcodeconfig/libdispatch.order \ + -Wl,-alias_list,$(top_srcdir)/xcodeconfig/libdispatch.aliases \ + -Wl,-unexported_symbols_list,$(top_srcdir)/xcodeconfig/libdispatch.unexport +endif + CLEANFILES= -DISTCLEANFILES=System +DISTCLEANFILES=System objc if USE_MIG BUILT_SOURCES= \ Modified: trunk/src/init.c =================================================================== --- trunk/src/init.c 2012-08-09 05:08:50 UTC (rev 213) +++ trunk/src/init.c 2012-08-09 05:08:56 UTC (rev 214) @@ -780,6 +780,7 @@ }; const struct dispatch_source_type_s _dispatch_source_type_sock = { +#ifdef EVFILT_SOCK .ke = { .filter = EVFILT_SOCK, .flags = EV_CLEAR, @@ -787,6 +788,7 @@ .mask = NOTE_CONNRESET | NOTE_READCLOSED | NOTE_WRITECLOSED | NOTE_TIMEOUT | NOTE_NOSRCADDR | NOTE_IFDENIED | NOTE_SUSPEND | NOTE_RESUME | NOTE_KEEPALIVE, +#endif }; #pragma mark - Modified: trunk/src/transform.c =================================================================== --- trunk/src/transform.c 2012-08-09 05:08:50 UTC (rev 213) +++ trunk/src/transform.c 2012-08-09 05:08:56 UTC (rev 214) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Apple Inc. All rights reserved. + * Copyright (c) 2011-2012 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * @@ -352,6 +352,7 @@ }); if (!success) { + (void)_dispatch_transform_buffer_new(&buffer, 0, 0); dispatch_release(buffer.data); return NULL; } @@ -491,6 +492,7 @@ }); if (!success) { + (void)_dispatch_transform_buffer_new(&buffer, 0, 0); dispatch_release(buffer.data); return NULL; } @@ -910,6 +912,9 @@ { if (input->type == _DISPATCH_DATA_FORMAT_UTF_ANY) { input = _dispatch_transform_detect_utf(data); + if (input == NULL) { + return NULL; + } } if ((input->type & ~output->input_mask) != 0) { -------------- next part -------------- An HTML attachment was scrubbed... URL: