diff --git a/CMakeLists.txt b/CMakeLists.txt index 74b784981..a15d79fd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,7 +64,14 @@ if(ENABLE_SWIFT) set(swift_dir swift_static) endif() - set(INSTALL_TARGET_DIR "${INSTALL_LIBDIR}/${swift_dir}/${swift_os}" CACHE PATH "Path where the libraries will be installed") + if(CMAKE_SYSTEM_NAME STREQUAL Darwin) + set(INSTALL_TARGET_DIR "${INSTALL_LIBDIR}/${swift_dir}/${swift_os}" CACHE PATH "Path where the libraries will be installed") + set(INSTALL_TARGET_DIR_SWIFTMODULES "${INSTALL_LIBDIR}/${swift_dir}/${swift_os}/${swift_arch}" CACHE PATH "Path where the swiftmodules will be installed") + else() + set(INSTALL_TARGET_DIR "${INSTALL_LIBDIR}/${swift_dir}/${swift_os}/${swift_arch}" CACHE PATH "Path where the libraries will be installed") + set(INSTALL_TARGET_DIR_SWIFTMODULES "${INSTALL_LIBDIR}/${swift_dir}/${swift_os}/${swift_arch}" CACHE PATH "Path where the swiftmodules will be installed") + endif() + set(INSTALL_DISPATCH_HEADERS_DIR "${INSTALL_LIBDIR}/${swift_dir}/dispatch" CACHE PATH "Path where the headers will be installed for libdispatch") set(INSTALL_BLOCK_HEADERS_DIR "${INSTALL_LIBDIR}/${swift_dir}/Block" CACHE PATH "Path where the headers will be installed for the blocks runtime") set(INSTALL_OS_HEADERS_DIR "${INSTALL_LIBDIR}/${swift_dir}/os" CACHE PATH "Path where the os/ headers will be installed") diff --git a/cmake/modules/DispatchCompilerWarnings.cmake b/cmake/modules/DispatchCompilerWarnings.cmake index a7b31c818..081616d8d 100644 --- a/cmake/modules/DispatchCompilerWarnings.cmake +++ b/cmake/modules/DispatchCompilerWarnings.cmake @@ -5,7 +5,6 @@ if("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC") endmacro() else() macro(dispatch_common_warnings) - add_compile_options(-Werror) add_compile_options(-Wall) add_compile_options(-Wextra) diff --git a/cmake/modules/SwiftSupport.cmake b/cmake/modules/SwiftSupport.cmake index adcf42fbc..7026c967b 100644 --- a/cmake/modules/SwiftSupport.cmake +++ b/cmake/modules/SwiftSupport.cmake @@ -11,6 +11,17 @@ function(add_swift_target target) set(compile_flags ${CMAKE_SWIFT_FLAGS}) set(link_flags) + if("${CMAKE_SYSTEM_NAME}" STREQUAL "Android") + list(APPEND compile_flags "-sdk" "${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}/arch-${CMAKE_ANDROID_ARCH}") + list(APPEND compile_flags "-I" "${CMAKE_ANDROID_NDK}/sysroot/usr/include") + list(APPEND compile_flags "-I" "${CMAKE_ANDROID_NDK}/sysroot/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}") + + list(APPEND link_flags "-sdk" "${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}/arch-${CMAKE_ANDROID_ARCH}") + list(APPEND link_flags "-tools-directory" "${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}/bin") + list(APPEND link_flags "-L" "${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}/lib/gcc/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}/4.9.x") + list(APPEND link_flags "-L" "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/${CMAKE_ANDROID_ARCH_ABI}") + endif() + if(AST_TARGET) list(APPEND compile_flags -target;${AST_TARGET}) list(APPEND link_flags -target;${AST_TARGET}) @@ -234,6 +245,8 @@ function(get_swift_host_arch result_var_name) set("${result_var_name}" "armv6" PARENT_SCOPE) elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") set("${result_var_name}" "armv7" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7-a") + set("${result_var_name}" "armv7" PARENT_SCOPE) elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64") set("${result_var_name}" "x86_64" PARENT_SCOPE) elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "IA64") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8d4ea63f2..ea53f2959 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -263,7 +263,7 @@ if(ENABLE_SWIFT) ${CMAKE_CURRENT_BINARY_DIR}/swift/Dispatch.swiftmodule ${CMAKE_CURRENT_BINARY_DIR}/swift/Dispatch.swiftdoc DESTINATION - ${INSTALL_TARGET_DIR}/${swift_arch}) + ${INSTALL_TARGET_DIR_SWIFTMODULES}) if(BUILD_SHARED_LIBS) set(library_kind SHARED) diff --git a/src/internal.h b/src/internal.h index 3cc16fc03..da0e36a8f 100644 --- a/src/internal.h +++ b/src/internal.h @@ -1112,6 +1112,12 @@ extern bool _dispatch_kevent_workqueue_enabled; #include "inline_internal.h" #include "firehose/firehose_internal.h" -__END_DECLS +#if !HAVE_PTHREAD_WORKQUEUE_KEVENT +// copied from https://opensource.apple.com/source/libpthread/libpthread-301.50.1/kern/workqueue_internal.h.auto.html +#define WORKQUEUE_MAXTHREADS 512 +#define WORKQUEUE_CONSTRAINED_MAXTHREADS (WORKQUEUE_MAXTHREADS >> 3) +#define WORKQUEUE_CONSTRAINED_FACTOR 5 +#endif +__END_DECLS #endif /* __DISPATCH_INTERNAL__ */ diff --git a/src/queue.c b/src/queue.c index 90f3cfa8b..9537d6f59 100644 --- a/src/queue.c +++ b/src/queue.c @@ -6168,10 +6168,19 @@ _dispatch_root_queue_init_pthread_pool(dispatch_queue_global_t dq, int pool_size, dispatch_priority_t pri) { dispatch_pthread_root_queue_context_t pqc = dq->do_ctxt; + int32_t default_pool_size = 0; + char* default_pool_size_env = getenv("LIBDISPATCH_DEFAULT_THREAD_POOL_SIZE"); + if (default_pool_size_env) { + default_pool_size = (int32_t) atoi(default_pool_size_env); + } + if (!default_pool_size) { + default_pool_size = (int32_t) MAX(dispatch_hw_config(active_cpus) * 5, WORKQUEUE_CONSTRAINED_MAXTHREADS); + } int thread_pool_size = DISPATCH_WORKQ_MAX_PTHREAD_COUNT; if (!(pri & DISPATCH_PRIORITY_FLAG_OVERCOMMIT)) { - thread_pool_size = (int32_t)dispatch_hw_config(active_cpus); + thread_pool_size = default_pool_size; } + if (pool_size && pool_size < thread_pool_size) thread_pool_size = pool_size; dq->dgq_thread_pool_size = thread_pool_size; qos_class_t cls = _dispatch_qos_to_qos_class(_dispatch_priority_qos(pri) ?: diff --git a/src/shims/generic_sys_queue.h b/src/shims/generic_sys_queue.h index fd4ac1d48..4278b36e3 100644 --- a/src/shims/generic_sys_queue.h +++ b/src/shims/generic_sys_queue.h @@ -32,114 +32,114 @@ #define TAILQ_HEAD(list_name, elem_type) \ struct list_name { \ - struct elem_type *tq_first; \ - struct elem_type *tq_last; \ + struct elem_type *tqh_first; \ + struct elem_type **tqh_last; \ } #define TAILQ_ENTRY(elem_type) \ struct { \ - struct elem_type *te_next; \ - struct elem_type *te_prev; \ + struct elem_type *tqe_next; \ + struct elem_type **tqe_prev; \ } -#define TAILQ_INIT(list) do { \ - (list)->tq_first = NULL; \ - (list)->tq_last = NULL; \ - } while (0) - -#define TAILQ_EMPTY(list) ((list)->tq_first == NULL) - -#define TAILQ_FIRST(list) ((list)->tq_first) - -#define TAILQ_LAST(list) ((list)->tq_last) - -#define TAILQ_NEXT(elem, field) ((elem)->field.te_next) - -#define TAILQ_PREV(elem, list, field) ((elem)->field.te_prev) - -#define TAILQ_FOREACH(var, list, field) \ - for ((var) = TAILQ_FIRST(list); \ - (var) != NULL; \ - (var) = TAILQ_NEXT(var, field)) - -#define TAILQ_REMOVE(list, elem, field) do { \ - if (TAILQ_NEXT(elem, field) != NULL) { \ - TAILQ_NEXT(elem, field)->field.te_prev = (elem)->field.te_prev; \ - } else { \ - (list)->tq_last = (elem)->field.te_prev; \ - } \ - if (TAILQ_PREV(elem, list, field) != NULL) { \ - TAILQ_PREV(elem, list, field)->field.te_next = (elem)->field.te_next; \ - } else { \ - (list)->tq_first = (elem)->field.te_next; \ - } \ - TRASHIT((elem)->field.te_next); \ - TRASHIT((elem)->field.te_prev); \ - } while(0) - -#define TAILQ_INSERT_TAIL(list, elem, field) do { \ - if (TAILQ_EMPTY(list)) { \ - (list)->tq_first = (list)->tq_last = (elem); \ - (elem)->field.te_prev = (elem)->field.te_next = NULL; \ - } else { \ - (elem)->field.te_next = NULL; \ - (elem)->field.te_prev = (list)->tq_last; \ - TAILQ_LAST(list)->field.te_next = (elem); \ - (list)->tq_last = (elem); \ - } \ - } while(0) - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, (head).tq_first } - -#define TAILQ_CONCAT(head1, head2, field) do { \ - if (!TAILQ_EMPTY(head2)) { \ - (head1)->tq_last = (head2)->tq_first; \ - (head1)->tq_first->field.te_prev = (head1)->tq_last; \ - (head1)->tq_last = (head2)->tq_last; \ - TAILQ_INIT((head2)); \ - } \ - } while (0) - -#define LIST_HEAD(name, type) struct name { \ - struct type *lh_first; \ - } +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ +} while (0) -#define LIST_ENTRY(type) struct { \ - struct type *le_next; \ - struct type *le_prev; \ - } +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) -#define LIST_EMPTY(head) ((head)->lh_first == NULL) +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) -#define LIST_FIRST(head) ((head)->lh_first) +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) -#define LIST_FOREACH(var, head, field) \ - for ((var) = LIST_FIRST((head)); \ - (var); \ - (var) = LIST_NEXT((var), field)) +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = TAILQ_FIRST((head)); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) -#define LIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = LIST_FIRST((head)); \ - (var) && ((tvar) = LIST_NEXT((var), field), 1); \ - (var) = (tvar)) +#define TAILQ_REMOVE(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else { \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + } \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ +} while (0) -#define LIST_INIT(head) do { \ - LIST_FIRST((head)) = NULL; \ +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ } while (0) -#define LIST_NEXT(elm, field) ((elm)->field.le_next) +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + } \ +} while (0) + +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} -#define LIST_REMOVE(elm, field) do { \ - if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = (elm)->field.le_prev; \ - } while (0) +#define LIST_EMPTY(head) ((head)->lh_first == NULL) -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = LIST_NEXT((elm), field); \ - LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = LIST_FIRST((head)); \ - } while (0) +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) #endif // __DISPATCH_SHIMS_SYS_QUEUE__ diff --git a/src/shims/yield.c b/src/shims/yield.c index 43f0017ee..a0500fd60 100644 --- a/src/shims/yield.c +++ b/src/shims/yield.c @@ -36,7 +36,7 @@ void * _dispatch_wait_for_enqueuer(void **ptr) { #if !DISPATCH_HW_CONFIG_UP -#if defined(__arm__) || defined(__arm64__) +#if (defined(__arm__) && !defined(__ANDROID__)) || defined(__arm64__) int spins = DISPATCH_WAIT_SPINS_WFE; void *value; while (unlikely(spins-- > 0)) { diff --git a/src/swift/Queue.swift b/src/swift/Queue.swift index 377e27fdd..77e90e23b 100644 --- a/src/swift/Queue.swift +++ b/src/swift/Queue.swift @@ -116,9 +116,17 @@ extension DispatchQueue { _swift_dispatch_apply_current(iterations, work) } + #if os(Android) + private static let androidSwiftMain = DispatchQueue(label: "AndroidSwiftMain", qos: .userInteractive) + + public class var main: DispatchQueue { + return androidSwiftMain + } + #else public class var main: DispatchQueue { - return DispatchQueue(queue: _swift_dispatch_get_main_queue()) + return DispatchQueue(queue: _swift_dispatch_get_main_queue()) } + #endif @available(macOS, deprecated: 10.10, message: "") @available(iOS, deprecated: 8.0, message: "")