Merge pull request #382 from adierking/cmake
build: support embedding in other CMake projects
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5036c3b..80bbd54 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -54,12 +54,7 @@
shims/time.h
shims/tsd.h
shims/yield.h)
-if(UNIX)
- target_sources(dispatch
- PRIVATE
- shims/generic_unix_stubs.c
- shims/generic_unix_stubs.h)
-elseif(WIN32)
+if(WIN32)
target_sources(dispatch
PRIVATE
shims/generic_sys_queue.h
@@ -84,7 +79,7 @@
endif()
if(ENABLE_SWIFT)
set(swift_optimization_flags)
- if(CMAKE_BUILD_TYPE MATCHES Release)
+ if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
set(swift_optimization_flags -O)
endif()
add_swift_library(swiftDispatch
@@ -121,6 +116,11 @@
PRIVATE
swift/DispatchStubs.cc
${CMAKE_CURRENT_BINARY_DIR}/swiftDispatch.o)
+ if(CMAKE_BUILD_TYPE MATCHES Debug)
+ target_link_libraries(dispatch
+ PRIVATE
+ swiftSwiftOnoneSupport)
+ endif()
endif()
if(ENABLE_DTRACE)
dtrace_usdt_probe(${CMAKE_CURRENT_SOURCE_DIR}/provider.d
@@ -191,6 +191,9 @@
if(BSD_OVERLAY_FOUND)
target_link_libraries(dispatch PRIVATE ${BSD_OVERLAY_LDFLAGS})
endif()
+if(LibRT_FOUND)
+ target_link_libraries(dispatch PRIVATE RT::rt)
+endif()
target_link_libraries(dispatch
PRIVATE
Threads::Threads
diff --git a/src/shims.h b/src/shims.h
index 32d2c85..85f4026 100644
--- a/src/shims.h
+++ b/src/shims.h
@@ -33,14 +33,16 @@
#if defined(_WIN32)
#include "shims/generic_win_stubs.h"
#include "shims/generic_sys_queue.h"
-#elif defined(__unix__)
-#include "shims/generic_unix_stubs.h"
#endif
#ifdef __ANDROID__
#include "shims/android_stubs.h"
#endif
+#if !HAVE_MACH
+#include "shims/mach.h"
+#endif
+
#include "shims/hw_config.h"
#include "shims/priority.h"
@@ -79,6 +81,12 @@
#endif // HAVE_STRLCPY
+#ifndef TAILQ_FOREACH_SAFE
+#define TAILQ_FOREACH_SAFE(var, head, field, temp) \
+ for ((var) = TAILQ_FIRST((head)); \
+ (var) && ((temp) = TAILQ_NEXT((var), field), 1); (var) = (temp))
+#endif
+
#if PTHREAD_WORKQUEUE_SPI_VERSION < 20140716
static inline int
_pthread_workqueue_override_start_direct(mach_port_t thread,
diff --git a/src/shims/generic_sys_queue.h b/src/shims/generic_sys_queue.h
index 250abbf..1d9a18d 100644
--- a/src/shims/generic_sys_queue.h
+++ b/src/shims/generic_sys_queue.h
@@ -62,11 +62,6 @@
(var) != NULL; \
(var) = TAILQ_NEXT(var, field))
-#define TAILQ_FOREACH_SAFE(var, list, field, temp) \
- for ((var) = TAILQ_FIRST(list); \
- ((var) != NULL) && (temp = TAILQ_NEXT(var, field), 1); \
- (var) = (temp))
-
#define TAILQ_REMOVE(list, elem, field) do { \
if (TAILQ_NEXT(elem, field) != NULL) { \
TAILQ_NEXT(elem, field)->field.te_prev = (elem)->field.te_prev; \
diff --git a/src/shims/generic_unix_stubs.c b/src/shims/generic_unix_stubs.c
deleted file mode 100644
index 9197664..0000000
--- a/src/shims/generic_unix_stubs.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * This source file is part of the Swift.org open source project
- *
- * Copyright (c) 2015 Apple Inc. and the Swift project authors
- *
- * Licensed under Apache License v2.0 with Runtime Library Exception
- *
- * See https://swift.org/LICENSE.txt for license information
- * See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
- *
- */
-
-/*
- * This file contains stubbed out functions we are using during
- * the initial linux port. When the port is complete, this file
- * should be empty (and thus removed).
- */
-
-#include <stdint.h>
-#if defined(__ANDROID__) || defined(__FreeBSD__)
-#include <sys/syscall.h>
-#else
-#include <syscall.h>
-#endif /* __ANDROID__ || __FreeBSD__ */
-
-#if __has_include(<config/config_ac.h>)
-#include <config/config_ac.h>
-#else
-#include <config/config.h>
-#endif
-
-#include "pthread.h"
-#include "os/generic_unix_base.h"
-#include "internal.h"
-
-
-#undef LINUX_PORT_ERROR
-#define LINUX_PORT_ERROR() do { printf("LINUX_PORT_ERROR_CALLED %s:%d: %s\n",__FILE__,__LINE__,__FUNCTION__); abort(); } while (0)
-
-
-/*
- * Stubbed out static data
- */
-
-pthread_key_t dispatch_voucher_key;
-pthread_key_t dispatch_pthread_root_queue_observer_hooks_key;
-
-unsigned short dispatch_timer__program_semaphore;
-unsigned short dispatch_timer__wake_semaphore;
-unsigned short dispatch_timer__fire_semaphore;
-unsigned short dispatch_timer__configure_semaphore;
-unsigned short dispatch_queue__pop_semaphore;
-unsigned short dispatch_callout__entry_semaphore;
-unsigned short dispatch_callout__return_semaphore;
-unsigned short dispatch_queue__push_semaphore;
-void (*_dispatch_block_special_invoke)(void*);
-struct dispatch_queue_attr_s _dispatch_queue_attr_concurrent;
diff --git a/src/shims/generic_unix_stubs.h b/src/shims/generic_unix_stubs.h
deleted file mode 100644
index aca569f..0000000
--- a/src/shims/generic_unix_stubs.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This source file is part of the Swift.org open source project
- *
- * Copyright (c) 2015 Apple Inc. and the Swift project authors
- *
- * Licensed under Apache License v2.0 with Runtime Library Exception
- *
- * See https://swift.org/LICENSE.txt for license information
- * See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
- *
- */
-
-// forward declarations for functions we are stubbing out
-// in the intial linux port.
-
-#ifndef __DISPATCH__STUBS__INTERNAL
-#define __DISPATCH__STUBS__INTERNAL
-
-#ifndef TAILQ_FOREACH_SAFE
-#define TAILQ_FOREACH_SAFE(var, head, field, temp) \
- for ((var) = TAILQ_FIRST((head)); \
- (var) && ((temp) = TAILQ_NEXT((var), field), 1); (var) = (temp))
-#endif
-
-/*
- * Stub out defines for some mach types and related macros
- */
-
-typedef uint32_t mach_port_t;
-
-#define MACH_PORT_NULL (0)
-#define MACH_PORT_DEAD (-1)
-
-typedef uint32_t mach_error_t;
-
-typedef uint32_t mach_msg_return_t;
-
-typedef uint32_t mach_msg_bits_t;
-
-typedef void *dispatch_mach_msg_t;
-
-typedef uint64_t firehose_activity_id_t;
-
-typedef void *mach_msg_header_t;
-
-// Print a warning when an unported code path executes.
-#define LINUX_PORT_ERROR() do { \
- printf("LINUX_PORT_ERROR_CALLED %s:%d: %s\n",\
- __FILE__,__LINE__,__FUNCTION__); } while (0)
-
-/*
- * Stub out defines for other missing types
- */
-
-// SIZE_T_MAX should not be hardcoded like this here.
-#ifndef SIZE_T_MAX
-#define SIZE_T_MAX (~(size_t)0)
-#endif
-
-#endif
diff --git a/src/shims/generic_win_stubs.h b/src/shims/generic_win_stubs.h
index 0680112..c983cdc 100644
--- a/src/shims/generic_win_stubs.h
+++ b/src/shims/generic_win_stubs.h
@@ -11,25 +11,9 @@
#include <process.h>
/*
- * Stub out defines for some mach types and related macros
+ * Stub out defines for missing types
*/
-typedef uint32_t mach_port_t;
-
-#define MACH_PORT_NULL (0)
-
-typedef uint32_t mach_msg_bits_t;
-typedef void *mach_msg_header_t;
-
-/*
- * Stub out defines for other missing types
- */
-
-// SIZE_T_MAX should not be hardcoded like this here.
-#ifndef SIZE_T_MAX
-#define SIZE_T_MAX (~(size_t)0)
-#endif
-
typedef __typeof__(_Generic((__SIZE_TYPE__)0, \
unsigned long long int : (long long int)0, \
unsigned long int : (long int)0, \
diff --git a/src/shims/mach.h b/src/shims/mach.h
new file mode 100644
index 0000000..759f5f3
--- /dev/null
+++ b/src/shims/mach.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018 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@
+ */
+
+#ifndef __DISPATCH_SHIMS_MACH__
+#define __DISPATCH_SHIMS_MACH__
+
+/*
+ * Stub out defines for some mach types and related macros
+ */
+
+typedef uint32_t mach_port_t;
+
+#define MACH_PORT_NULL (0)
+#define MACH_PORT_DEAD (-1)
+
+typedef uint32_t mach_error_t;
+
+typedef uint32_t mach_msg_return_t;
+
+typedef uint32_t mach_msg_bits_t;
+
+typedef void *dispatch_mach_msg_t;
+
+typedef uint64_t firehose_activity_id_t;
+
+typedef void *mach_msg_header_t;
+
+#endif
diff --git a/src/swift/Data.swift b/src/swift/Data.swift
index 37b4463..3b81e68 100644
--- a/src/swift/Data.swift
+++ b/src/swift/Data.swift
@@ -117,9 +117,23 @@
return try body(contentPtr)
}
+ @available(swift 4.2)
+ public func enumerateBytes(
+ _ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Int, _ stop: inout Bool) -> Void)
+ {
+ enumerateBytesCommon(block)
+ }
+
+ @available(swift, obsoleted: 4.2, renamed: "enumerateBytes(_:)")
public func enumerateBytes(
block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Int, _ stop: inout Bool) -> Void)
{
+ enumerateBytesCommon(block)
+ }
+
+ private func enumerateBytesCommon(
+ _ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Int, _ stop: inout Bool) -> Void)
+ {
// we know that capturing block in the closure being created/passed to dispatch_data_apply
// does not cause block to escape because dispatch_data_apply does not allow its
// block argument to escape. Therefore, the usage of withoutActuallyEscaping to
diff --git a/src/swift/Queue.swift b/src/swift/Queue.swift
index 6d59766..0cfd782 100644
--- a/src/swift/Queue.swift
+++ b/src/swift/Queue.swift
@@ -161,21 +161,85 @@
return String(validatingUTF8: dispatch_queue_get_label(self.__wrapped))!
}
+ ///
+ /// Submits a block for synchronous execution on this queue.
+ ///
+ /// Submits a work item to a dispatch queue like `async(execute:)`, however
+ /// `sync(execute:)` will not return until the work item has finished.
+ ///
+ /// Work items submitted to a queue with `sync(execute:)` do not observe certain
+ /// queue attributes of that queue when invoked (such as autorelease frequency
+ /// and QoS class).
+ ///
+ /// Calls to `sync(execute:)` targeting the current queue will result
+ /// in deadlock. Use of `sync(execute:)` is also subject to the same
+ /// multi-party deadlock problems that may result from the use of a mutex.
+ /// Use of `async(execute:)` is preferred.
+ ///
+ /// As an optimization, `sync(execute:)` invokes the work item on the thread which
+ /// submitted it, except when the queue is the main queue or
+ /// a queue targetting it.
+ ///
+ /// - parameter execute: The work item to be invoked on the queue.
+ /// - SeeAlso: `async(execute:)`
+ ///
@available(macOS 10.10, iOS 8.0, *)
public func sync(execute workItem: DispatchWorkItem) {
CDispatch.dispatch_sync(self.__wrapped, workItem._block)
}
+ ///
+ /// Submits a work item for asynchronous execution on a dispatch queue.
+ ///
+ /// `async(execute:)` is the fundamental mechanism for submitting
+ /// work items to a dispatch queue.
+ ///
+ /// Calls to `async(execute:)` always return immediately after the work item has
+ /// been submitted, and never wait for the work item to be invoked.
+ ///
+ /// The target queue determines whether the work item will be invoked serially or
+ /// concurrently with respect to other work items submitted to that same queue.
+ /// Serial queues are processed concurrently with respect to each other.
+ ///
+ /// - parameter execute: The work item to be invoked on the queue.
+ /// - SeeAlso: `sync(execute:)`
+ ///
@available(macOS 10.10, iOS 8.0, *)
public func async(execute workItem: DispatchWorkItem) {
CDispatch.dispatch_async(self.__wrapped, workItem._block)
}
+ ///
+ /// Submits a work item to a dispatch queue and associates it with the given
+ /// dispatch group. The dispatch group may be used to wait for the completion
+ /// of the work items it references.
+ ///
+ /// - parameter group: the dispatch group to associate with the submitted block.
+ /// - parameter execute: The work item to be invoked on the queue.
+ /// - SeeAlso: `sync(execute:)`
+ ///
@available(macOS 10.10, iOS 8.0, *)
public func async(group: DispatchGroup, execute workItem: DispatchWorkItem) {
CDispatch.dispatch_group_async(group.__wrapped, self.__wrapped, workItem._block)
}
+ ///
+ /// Submits a work item to a dispatch queue and optionally associates it with a
+ /// dispatch group. The dispatch group may be used to wait for the completion
+ /// of the work items it references.
+ ///
+ /// - parameter group: the dispatch group to associate with the submitted
+ /// work item. If this is `nil`, the work item is not associated with a group.
+ /// - parameter flags: flags that control the execution environment of the
+ /// - parameter qos: the QoS at which the work item should be executed.
+ /// Defaults to `DispatchQoS.unspecified`.
+ /// - parameter flags: flags that control the execution environment of the
+ /// work item.
+ /// - parameter execute: The work item to be invoked on the queue.
+ /// - SeeAlso: `sync(execute:)`
+ /// - SeeAlso: `DispatchQoS`
+ /// - SeeAlso: `DispatchWorkItemFlags`
+ ///
public func async(
group: DispatchGroup? = nil,
qos: DispatchQoS = .unspecified,
@@ -257,10 +321,32 @@
}
}
+ ///
+ /// Submits a block for synchronous execution on this queue.
+ ///
+ /// Submits a work item to a dispatch queue like `sync(execute:)`, and returns
+ /// the value, of type `T`, returned by that work item.
+ ///
+ /// - parameter execute: The work item to be invoked on the queue.
+ /// - returns the value returned by the work item.
+ /// - SeeAlso: `sync(execute:)`
+ ///
public func sync<T>(execute work: () throws -> T) rethrows -> T {
return try self._syncHelper(fn: sync, execute: work, rescue: { throw $0 })
}
+ ///
+ /// Submits a block for synchronous execution on this queue.
+ ///
+ /// Submits a work item to a dispatch queue like `sync(execute:)`, and returns
+ /// the value, of type `T`, returned by that work item.
+ ///
+ /// - parameter flags: flags that control the execution environment of the
+ /// - parameter execute: The work item to be invoked on the queue.
+ /// - returns the value returned by the work item.
+ /// - SeeAlso: `sync(execute:)`
+ /// - SeeAlso: `DispatchWorkItemFlags`
+ ///
public func sync<T>(flags: DispatchWorkItemFlags, execute work: () throws -> T) rethrows -> T {
if flags == .barrier {
return try self._syncHelper(fn: _syncBarrier, execute: work, rescue: { throw $0 })
@@ -271,6 +357,23 @@
}
}
+ ///
+ /// Submits a work item to a dispatch queue for asynchronous execution after
+ /// a specified time.
+ ///
+ /// - parameter: deadline the time after which the work item should be executed,
+ /// given as a `DispatchTime`.
+ /// - parameter qos: the QoS at which the work item should be executed.
+ /// Defaults to `DispatchQoS.unspecified`.
+ /// - parameter flags: flags that control the execution environment of the
+ /// work item.
+ /// - parameter execute: The work item to be invoked on the queue.
+ /// - SeeAlso: `async(execute:)`
+ /// - SeeAlso: `asyncAfter(deadline:execute:)`
+ /// - SeeAlso: `DispatchQoS`
+ /// - SeeAlso: `DispatchWorkItemFlags`
+ /// - SeeAlso: `DispatchTime`
+ ///
public func asyncAfter(
deadline: DispatchTime,
qos: DispatchQoS = .unspecified,
@@ -285,6 +388,23 @@
}
}
+ ///
+ /// Submits a work item to a dispatch queue for asynchronous execution after
+ /// a specified time.
+ ///
+ /// - parameter: deadline the time after which the work item should be executed,
+ /// given as a `DispatchWallTime`.
+ /// - parameter qos: the QoS at which the work item should be executed.
+ /// Defaults to `DispatchQoS.unspecified`.
+ /// - parameter flags: flags that control the execution environment of the
+ /// work item.
+ /// - parameter execute: The work item to be invoked on the queue.
+ /// - SeeAlso: `async(execute:)`
+ /// - SeeAlso: `asyncAfter(wallDeadline:execute:)`
+ /// - SeeAlso: `DispatchQoS`
+ /// - SeeAlso: `DispatchWorkItemFlags`
+ /// - SeeAlso: `DispatchWallTime`
+ ///
public func asyncAfter(
wallDeadline: DispatchWallTime,
qos: DispatchQoS = .unspecified,
@@ -299,11 +419,31 @@
}
}
+ ///
+ /// Submits a work item to a dispatch queue for asynchronous execution after
+ /// a specified time.
+ ///
+ /// - parameter: deadline the time after which the work item should be executed,
+ /// given as a `DispatchTime`.
+ /// - parameter execute: The work item to be invoked on the queue.
+ /// - SeeAlso: `asyncAfter(deadline:qos:flags:execute:)`
+ /// - SeeAlso: `DispatchTime`
+ ///
@available(macOS 10.10, iOS 8.0, *)
public func asyncAfter(deadline: DispatchTime, execute: DispatchWorkItem) {
CDispatch.dispatch_after(deadline.rawValue, self.__wrapped, execute._block)
}
+ ///
+ /// Submits a work item to a dispatch queue for asynchronous execution after
+ /// a specified time.
+ ///
+ /// - parameter: deadline the time after which the work item should be executed,
+ /// given as a `DispatchWallTime`.
+ /// - parameter execute: The work item to be invoked on the queue.
+ /// - SeeAlso: `asyncAfter(wallDeadline:qos:flags:execute:)`
+ /// - SeeAlso: `DispatchTime`
+ ///
@available(macOS 10.10, iOS 8.0, *)
public func asyncAfter(wallDeadline: DispatchWallTime, execute: DispatchWorkItem) {
CDispatch.dispatch_after(wallDeadline.rawValue, self.__wrapped, execute._block)
diff --git a/src/transform.c b/src/transform.c
index 7f2c556..45d5669 100644
--- a/src/transform.c
+++ b/src/transform.c
@@ -662,7 +662,7 @@
dest_size = howmany(total, 5);
// <rdar://problem/25676583>
// os_mul_overflow(dest_size, 8, &dest_size)
- if (dest_size > SIZE_T_MAX / 8) {
+ if (dest_size > SIZE_MAX / 8) {
return NULL;
}
dest_size *= 8;
@@ -897,7 +897,7 @@
dest_size = howmany(total, 3);
// <rdar://problem/25676583>
// os_mul_overflow(dest_size, 4, &dest_size)
- if (dest_size > SIZE_T_MAX / 4) {
+ if (dest_size > SIZE_MAX / 4) {
return NULL;
}
dest_size *= 4;