Skip to content

Android support #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ if BUILD_OWN_KQUEUES
MAYBE_KQUEUES = libkqueue
endif

if BUILD_TESTS
MAYBE_TESTS = tests
endif

SUBDIRS= \
dispatch \
$(MAYBE_PTHREAD_WORKQUEUES) \
Expand All @@ -20,7 +24,7 @@ SUBDIRS= \
os \
private \
src \
tests
$(MAYBE_TESTS)

EXTRA_DIST= \
README.md \
Expand Down
61 changes: 59 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ AC_CONFIG_MACRO_DIR([m4])
ac_clean_files=a.out.dSYM
AM_MAINTAINER_MODE

AC_CANONICAL_BUILD
AC_CANONICAL_HOST
AC_CANONICAL_TARGET

#
# Command line argument to specify build variant (default to release).
# Impacts default value of CFLAGS et al. so must come before AC_PROG_CC
Expand Down Expand Up @@ -56,6 +60,53 @@ AC_PROG_CXX([clang++ g++ c++])
AC_PROG_OBJC([clang gcc cc])
AC_PROG_OBJCXX([clang++ g++ c++])

#
# Android cross-compilation support
#
AC_ARG_WITH([android-ndk],
[AS_HELP_STRING([--with-android-ndk],
[Android NDK location])], [
android_ndk=${withval}
])
AC_ARG_WITH([android-ndk-gcc-version],
[AS_HELP_STRING([--with-android-ndk-gcc-version],
[Android NDK GCC version [defaults=4.9]])],
[android_ndk_gcc_version=${withval}], [android_ndk_gcc_version=4.9])
AC_ARG_WITH([android-api-level],
[AS_HELP_STRING([--with-android-api-level],
[Android API level to link with])], [
android_api_level=${withval}
])
AC_ARG_ENABLE([android],
[AS_HELP_STRING([--enable-android],
[Compile for Android])], [
android=true

# Override values until there's real support for multiple Android platforms
host=armv7-none-linux-androideabi
host_alias=arm-linux-androideabi
host_cpu=armv7
host_os=linux-androideabi
host_vendor=unknown
arch=arm

sysroot=${android_ndk}/platforms/android-${android_api_level}/arch-${arch}
toolchain=${android_ndk}/toolchains/${host_alias}-${android_ndk_gcc_version}/prebuilt/linux-${build_cpu}

CFLAGS="$CFLAGS -target ${host_alias} --sysroot=${sysroot} -B${toolchain}/${host_alias}/bin"
CXXFLAGS="$CXXFLAGS -target ${host_alias} --sysroot=${sysroot} -B${toolchain}/${host_alias}/bin"
SWIFTC_FLAGS="-target ${host} -sdk ${sysroot} -L${toolchain}/lib/gcc/${host_alias}/${android_ndk_gcc_version}.x"
LIBS="$LIBS -L${toolchain}/lib/gcc/${host_alias}/${android_ndk_gcc_version}.x"
LDFLAGS="$LDFLAGS -Wc,'-target','${host_alias}','-B${toolchain}/${host_alias}/bin'"

# FIXME: empty CFLAGS and CXXFLAGS are assumed for this to work.
# FIXME: there should be a more elegant way to do this
ac_configure_args=`echo $ac_configure_args | sed -e "s/ 'CFLAGS='//" -e "s/ 'CXXFLAGS='//"`
# CFLAGS, CXXFLAGS and LIBS needs to be passed to libkqueue and libpwq
ac_configure_args="$ac_configure_args --enable-bionic-libc 'CFLAGS=$CFLAGS' 'CXXFLAGS=$CXXFLAGS' 'LIBS=$LIBS'"
], [android=false])
AM_CONDITIONAL(ANDROID, $android)

#
# On Mac OS X, some required header files come from other source packages;
# allow specifying where those are.
Expand Down Expand Up @@ -134,8 +185,6 @@ AS_IF([test "x$enable_apple_tsd_optimizations" = "xyes"],
[Define to use non-portable pthread TSD optimizations for Mac OS X)])]
)

AC_CANONICAL_TARGET

#
# Enable building Swift overlay support into libdispatch
#
Expand Down Expand Up @@ -164,6 +213,7 @@ AC_ARG_WITH([swift-toolchain],
)
AM_CONDITIONAL(HAVE_SWIFT, $have_swift)
AC_SUBST([SWIFTC])
AC_SUBST([SWIFTC_FLAGS])
AC_SUBST([SWIFT_LIBDIR])

#
Expand Down Expand Up @@ -473,6 +523,13 @@ AC_COMPILE_IFELSE(
[AC_DEFINE(HAVE_NORETURN_BUILTIN_TRAP, 1, [Define if __builtin_trap marked noreturn])]
)

#
# Add option to avoid building tests
#
AC_ARG_ENABLE([build-tests],
[AS_HELP_STRING([--disable-build-tests], [Disable tests compilation])])
AM_CONDITIONAL(BUILD_TESTS, [test "x$enable_build_tests" != "xno"])

#
# Generate Makefiles.
#
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ libdispatch_la_SOURCES= \
trace.h \
voucher_internal.h \
firehose/firehose_internal.h \
shims/android_stubs.h \
shims/atomic.h \
shims/atomic_sfb.h \
shims/getprogname.h \
Expand Down Expand Up @@ -148,7 +149,7 @@ SWIFT_SRC_FILES=\
SWIFT_ABS_SRC_FILES = $(SWIFT_SRC_FILES:%=$(abs_srcdir)/%)
SWIFT_OBJ_FILES = $(abs_builddir)/swift/swift_overlay.o

SWIFTC_FLAGS = -Xcc -fmodule-map-file=$(abs_top_srcdir)/dispatch/module.modulemap -I$(abs_top_srcdir) -Xcc -fblocks
SWIFTC_FLAGS+= -Xcc -fmodule-map-file=$(abs_top_srcdir)/dispatch/module.modulemap -I$(abs_top_srcdir) -Xcc -fblocks
if DISPATCH_ENABLE_OPTIMIZATION
SWIFTC_FLAGS+=-O
endif
Expand Down Expand Up @@ -180,4 +181,3 @@ BUILT_SOURCES=$(MIG_SOURCES) $(DTRACE_SOURCES)
nodist_libdispatch_la_SOURCES=$(BUILT_SOURCES)
CLEANFILES=$(BUILT_SOURCES) $(SWIFT_GEN_FILES)
DISTCLEANFILES=pthread_machdep.h pthread System mach objc

5 changes: 5 additions & 0 deletions src/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
#endif

/* private.h must be included last to avoid picking up installed headers. */
#include <pthread.h>
#include "os/object_private.h"
#include "queue_private.h"
#include "source_private.h"
Expand Down Expand Up @@ -245,7 +246,11 @@ DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_child(void);
#include <sys/event.h>
#include <sys/mount.h>
#include <sys/queue.h>
#ifdef __ANDROID__
#include <linux/sysctl.h>
#else
#include <sys/sysctl.h>
#endif /* __ANDROID__ */
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/mman.h>
Expand Down
4 changes: 3 additions & 1 deletion src/queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,7 @@ _dispatch_get_mach_host_port(void)
#include <unistd.h>
#include <sys/syscall.h>

#ifndef __ANDROID__
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does android already defines gettid() ? because dispatch won't work without it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MadCoder gettid is already defined in unistd.h:57 for API 21 (and lower also) as extern pid_t gettid(void) __pure2. Android declaration is not inline as src/queue.c, but it shouldn’t have a performance impact in this context, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect, I just wanted to make sure. we don't care about the performance because this is cached once per thread.

#ifdef SYS_gettid
DISPATCH_ALWAYS_INLINE
static inline pid_t
Expand All @@ -985,7 +986,8 @@ gettid(void)
}
#else
#error "SYS_gettid unavailable on this system"
#endif
#endif /* SYS_gettid */
#endif /* ! __ANDROID__ */

#define _tsd_call_cleanup(k, f) do { \
if ((f) && tsd->k) ((void(*)(void*))(f))(tsd->k); \
Expand Down
4 changes: 4 additions & 0 deletions src/shims.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ typedef unsigned long pthread_priority_t;
#include "shims/linux_stubs.h"
#endif

#ifdef __ANDROID__
#include "shims/android_stubs.h"
#endif

typedef uint32_t dispatch_priority_t;
#define DISPATCH_SATURATED_OVERRIDE ((dispatch_priority_t)UINT32_MAX)

Expand Down
34 changes: 34 additions & 0 deletions src/shims/android_stubs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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 http://swift.org/LICENSE.txt for license information
* See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
*
*/

// forward declarations for functions we are stubbing out
// in the intial android port.

#ifndef __DISPATCH__ANDROID__STUBS__INTERNAL
#define __DISPATCH__ANDROID__STUBS__INTERNAL

/*
* Missing sys/queue.h macro stubs
*/

#ifndef TAILQ_FOREACH_SAFE
# define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = TAILQ_FIRST((head)); \
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
(var) = (tvar))
#endif /* TAILQ_FOREACH_SAFE */

#ifndef TRASHIT
# define TRASHIT(x) do {(x) = (void *)-1;} while (0)
#endif /* TRASHIT */

#endif /* __DISPATCH__ANDROID__STUBS__INTERNAL */
7 changes: 7 additions & 0 deletions src/shims/getprogname.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@
#define __DISPATCH_SHIMS_GETPROGNAME__

#if !HAVE_GETPROGNAME

#ifdef __ANDROID__
extern const char *__progname;
#endif /* __ANDROID */)

static inline char *
getprogname(void)
{
# if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
return program_invocation_short_name;
# elif defined(__ANDROID__)
return __progname;
# else
# error getprogname(3) is not available on this platform
# endif
Expand Down
4 changes: 4 additions & 0 deletions src/shims/linux_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
*/

#include <stdint.h>
#ifdef __ANDROID__
#include <sys/syscall.h>
#else
#include <syscall.h>
#endif /* __ANDROID__ */

#if __has_include(<config/config_ac.h>)
#include <config/config_ac.h>
Expand Down
4 changes: 3 additions & 1 deletion src/shims/linux_stubs.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ typedef void (*dispatch_mach_msg_destructor_t)(void*);
#endif

// SIZE_T_MAX should not be hardcoded like this here.
#define SIZE_T_MAX (0x7fffffff)
#ifndef SIZE_T_MAX
#define SIZE_T_MAX (~(size_t)0)
#endif

// Define to 0 the NOTE_ values that are not present on Linux.
// Revisit this...would it be better to ifdef out the uses instead??
Expand Down
4 changes: 4 additions & 0 deletions src/shims/lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ _dispatch_unfair_lock_wake(uint32_t *uaddr, uint32_t flags)
#pragma mark - futex wrappers
#if HAVE_FUTEX
#include <sys/time.h>
#ifdef __ANDROID__
#include <sys/syscall.h>
#else
#include <syscall.h>
#endif /* __ANDROID__ */

DISPATCH_ALWAYS_INLINE
static inline int
Expand Down
4 changes: 3 additions & 1 deletion src/source.c
Original file line number Diff line number Diff line change
Expand Up @@ -2034,8 +2034,10 @@ _dispatch_kevent_qos_s _dispatch_kevent_timeout[] = {
};
#define DISPATCH_KEVENT_TIMEOUT_COUNT \
((sizeof(_dispatch_kevent_timeout) / sizeof(_dispatch_kevent_timeout[0])))
static_assert(DISPATCH_KEVENT_TIMEOUT_COUNT == DISPATCH_TIMER_INDEX_COUNT - 1,
#if __has_feature(c_static_assert)
_Static_assert(DISPATCH_KEVENT_TIMEOUT_COUNT == DISPATCH_TIMER_INDEX_COUNT - 1,
"should have a kevent for everything but disarm (ddt assumes this)");
#endif

#define DISPATCH_KEVENT_COALESCING_WINDOW_INIT(qos, ms) \
[DISPATCH_TIMER_QOS_##qos] = 2ull * (ms) * NSEC_PER_MSEC
Expand Down
14 changes: 7 additions & 7 deletions src/swift/Source.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public extension DispatchSource {
}
#endif

#if !os(Linux)
#if !os(Linux) && !os(Android)
public struct ProcessEvent : OptionSet, RawRepresentable {
public let rawValue: UInt
public init(rawValue: UInt) { self.rawValue = rawValue }
Expand Down Expand Up @@ -170,7 +170,7 @@ public extension DispatchSource {
}
#endif

#if !os(Linux)
#if !os(Linux) && !os(Android)
public class func makeProcessSource(identifier: pid_t, eventMask: ProcessEvent, queue: DispatchQueue? = nil) -> DispatchSourceProcess {
let source = dispatch_source_create(_swift_dispatch_source_type_proc(), UInt(identifier), eventMask.rawValue, queue?.__wrapped)
return DispatchSource(source: source) as DispatchSourceProcess
Expand Down Expand Up @@ -202,7 +202,7 @@ public extension DispatchSource {
return DispatchSource(source: source) as DispatchSourceUserDataOr
}

#if !os(Linux)
#if !os(Linux) && !os(Android)
public class func makeFileSystemObjectSource(fileDescriptor: Int32, eventMask: FileSystemEvent, queue: DispatchQueue? = nil) -> DispatchSourceFileSystemObject {
let source = dispatch_source_create(_swift_dispatch_source_type_vnode(), UInt(fileDescriptor), eventMask.rawValue, queue?.__wrapped)
return DispatchSource(source: source) as DispatchSourceFileSystemObject
Expand Down Expand Up @@ -255,7 +255,7 @@ public extension DispatchSourceMemoryPressure {
}
#endif

#if !os(Linux)
#if !os(Linux) && !os(Android)
public extension DispatchSourceProcess {
public var handle: pid_t {
return pid_t(dispatch_source_get_handle(self as! DispatchSource))
Expand Down Expand Up @@ -299,7 +299,7 @@ public extension DispatchSourceTimer {
}
}

#if !os(Linux)
#if !os(Linux) && !os(Android)
public extension DispatchSourceFileSystemObject {
public var handle: Int32 {
return Int32(dispatch_source_get_handle((self as! DispatchSource).__wrapped))
Expand Down Expand Up @@ -368,7 +368,7 @@ internal func _swift_dispatch_source_type_mach_recv() -> dispatch_source_type_t
internal func _swift_dispatch_source_type_memorypressure() -> dispatch_source_type_t
#endif

#if !os(Linux)
#if !os(Linux) && !os(Android)
@_silgen_name("_swift_dispatch_source_type_PROC")
internal func _swift_dispatch_source_type_proc() -> dispatch_source_type_t
#endif
Expand All @@ -382,7 +382,7 @@ internal func _swift_dispatch_source_type_signal() -> dispatch_source_type_t
@_silgen_name("_swift_dispatch_source_type_TIMER")
internal func _swift_dispatch_source_type_timer() -> dispatch_source_type_t

#if !os(Linux)
#if !os(Linux) && !os(Android)
@_silgen_name("_swift_dispatch_source_type_VNODE")
internal func _swift_dispatch_source_type_vnode() -> dispatch_source_type_t
#endif
Expand Down
6 changes: 3 additions & 3 deletions src/swift/Wrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ extension DispatchSource : DispatchSourceMachSend,
}
#endif

#if !os(Linux)
#if !os(Linux) && !os(Android)
extension DispatchSource : DispatchSourceProcess,
DispatchSourceFileSystemObject {
}
Expand Down Expand Up @@ -268,7 +268,7 @@ public protocol DispatchSourceMemoryPressure : DispatchSourceProtocol {
}
#endif

#if !os(Linux)
#if !os(Linux) && !os(Android)
public protocol DispatchSourceProcess : DispatchSourceProtocol {
var handle: pid_t { get }

Expand Down Expand Up @@ -298,7 +298,7 @@ public protocol DispatchSourceTimer : DispatchSourceProtocol {
func scheduleRepeating(wallDeadline: DispatchWallTime, interval: Double, leeway: DispatchTimeInterval)
}

#if !os(Linux)
#if !os(Linux) && !os(Android)
public protocol DispatchSourceFileSystemObject : DispatchSourceProtocol {
var handle: Int32 { get }

Expand Down
4 changes: 4 additions & 0 deletions tests/Foundation/bench.mm
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@

#include <Foundation/Foundation.h>
#include <libkern/OSAtomic.h>
#ifdef __ANDROID__
#include <linux/sysctl.h>
#else
#include <sys/sysctl.h>
#endif /* __ANDROID__ */
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <stdio.h>
Expand Down
Loading