From: Olivier Hainque <hain...@adacore.com> Android has many traits of Linux, reflected by the gcc port triplets composition (<cpu>-android-linux).
The Android Ada RTS was so far configured as a mostly "posix" port, which happens to be very little tested, if at all. This change reworks the Android Ada RTS to map a lot more closely to that of a regular Linux target, a natural fit and much more toroughly exercized. This expects support of pthread rwlocks in the bionic libc, which is there in the not-so-old-but-not-so-recent versions we tested (Android 11 at least). gcc/ada/ChangeLog: * Makefile.rtl: Rework the Android pairs to match those of a regular Linux port rather than a generic posix one. * libgnarl/s-osinte__android.ads: Import pcrtl and add bindings for the pthread_rwlock entry points, used by the Linux units now in the libgnat target pairs. * sysdep.c (__gnat_has_cap_sys_nice): Define for Android, conservative return 0. * adaint.c (__gnat_cpu_alloc): Define for Android as for Linux. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/Makefile.rtl | 18 ++++++-- gcc/ada/adaint.c | 2 +- gcc/ada/libgnarl/s-osinte__android.ads | 64 ++++++++++++++++++++++++-- gcc/ada/sysdep.c | 7 ++- 4 files changed, 79 insertions(+), 12 deletions(-) diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl index a26a725b3db..bd36c31a108 100644 --- a/gcc/ada/Makefile.rtl +++ b/gcc/ada/Makefile.rtl @@ -1407,24 +1407,32 @@ ifeq ($(SELECTED_PAIRS),PAIRS_NONE) ifeq ($(strip $(filter-out arm% aarch64 linux-android%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ + a-exetim.adb<libgnarl/a-exetim__posix.adb \ + a-exetim.ads<libgnarl/a-exetim__default.ads \ a-intnam.ads<libgnarl/a-intnam__linux.ads \ + a-nallfl.ads<libgnat/a-nallfl__wraplf.ads \ + a-synbar.adb<libgnarl/a-synbar__posix.adb \ + a-synbar.ads<libgnarl/a-synbar__posix.ads \ + s-dorepr.adb<libgnat/s-dorepr__fma.adb \ s-inmaop.adb<libgnarl/s-inmaop__posix.adb \ s-intman.adb<libgnarl/s-intman__android.adb \ - s-osinte.adb<libgnarl/s-osinte__android.adb \ s-osinte.ads<libgnarl/s-osinte__android.ads \ + s-osinte.adb<libgnarl/s-osinte__android.adb \ s-oslock.ads<libgnat/s-oslock__posix.ads \ s-osprim.adb<libgnat/s-osprim__posix.adb \ - s-taprop.adb<libgnarl/s-taprop__posix.adb \ + s-parame.adb<libgnat/s-parame__aarch64-linux.adb \ + s-taprop.adb<libgnarl/s-taprop__linux.adb \ + s-tasinf.ads<libgnarl/s-tasinf__linux.ads \ + s-tasinf.adb<libgnarl/s-tasinf__linux.adb \ + s-tpopsp.adb<libgnarl/s-tpopsp__tls.adb \ s-taspri.ads<libgnarl/s-taspri__posix.ads \ - s-tpopsp.adb<libgnarl/s-tpopsp__posix-foreign.adb \ - a-nallfl.ads<libgnat/a-nallfl__wraplf.ads \ $(ATOMICS_TARGET_PAIRS) \ $(ATOMICS_BUILTINS_TARGET_PAIRS) \ system.ads<libgnat/system-linux-arm.ads TOOLS_TARGET_PAIRS = indepsw.adb<indepsw-gnu.adb - EXTRA_GNATRTL_TASKING_OBJS=s-linux.o + EXTRA_GNATRTL_TASKING_OBJS=s-linux.o a-exetim.o # ARM and aarch64 rely on different unwinding mechanisms, and as # a 64bit target, aarch64 can also incorporate support for 128bit diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c index 1fcfae165a7..63130e0f2bc 100644 --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -3475,7 +3475,7 @@ __gnat_lwp_self (void) } #endif -#if defined (__linux__) +#if defined (__linux__) || defined (__ANDROID__) #include <sched.h> /* glibc versions earlier than 2.7 do not define the routines to handle diff --git a/gcc/ada/libgnarl/s-osinte__android.ads b/gcc/ada/libgnarl/s-osinte__android.ads index cd7e148933d..d74589047e7 100644 --- a/gcc/ada/libgnarl/s-osinte__android.ads +++ b/gcc/ada/libgnarl/s-osinte__android.ads @@ -258,6 +258,14 @@ package System.OS_Interface is function getpid return pid_t; pragma Import (C, getpid, "getpid"); + PR_SET_NAME : constant := 15; + PR_GET_NAME : constant := 16; + + function prctl + (option : int; + arg : unsigned_long) return int; + pragma Import (C_Variadic_1, prctl, "prctl"); + ------------- -- Threads -- ------------- @@ -276,9 +284,11 @@ package System.OS_Interface is new Ada.Unchecked_Conversion (unsigned_long, pthread_t); subtype pthread_mutex_t is System.OS_Locks.pthread_mutex_t; + type pthread_rwlock_t is limited private; type pthread_cond_t is limited private; type pthread_attr_t is limited private; type pthread_mutexattr_t is limited private; + type pthread_rwlockattr_t is limited private; type pthread_condattr_t is limited private; type pthread_key_t is private; @@ -287,11 +297,6 @@ package System.OS_Interface is PTHREAD_SCOPE_PROCESS : constant := 1; PTHREAD_SCOPE_SYSTEM : constant := 0; - -- Read/Write lock not supported on Android. - - subtype pthread_rwlock_t is pthread_mutex_t; - subtype pthread_rwlockattr_t is pthread_mutexattr_t; - ----------- -- Stack -- ----------- @@ -389,6 +394,43 @@ package System.OS_Interface is function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int; pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock"); + function pthread_rwlockattr_init + (attr : access pthread_rwlockattr_t) return int; + pragma Import (C, pthread_rwlockattr_init, "pthread_rwlockattr_init"); + + function pthread_rwlockattr_destroy + (attr : access pthread_rwlockattr_t) return int; + pragma Import (C, pthread_rwlockattr_destroy, "pthread_rwlockattr_destroy"); + + PTHREAD_RWLOCK_PREFER_READER_NP : constant := 0; + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP : constant := 1; + + -- No PTHREAD_RWLOCK_PREFER_WRITER_NP in Android's pthread.h API level 29 + + function pthread_rwlockattr_setkind_np + (attr : access pthread_rwlockattr_t; + pref : int) return int; + pragma Import + (C, pthread_rwlockattr_setkind_np, "pthread_rwlockattr_setkind_np"); + + function pthread_rwlock_init + (mutex : access pthread_rwlock_t; + attr : access pthread_rwlockattr_t) return int; + pragma Import (C, pthread_rwlock_init, "pthread_rwlock_init"); + + function pthread_rwlock_destroy + (mutex : access pthread_rwlock_t) return int; + pragma Import (C, pthread_rwlock_destroy, "pthread_rwlock_destroy"); + + function pthread_rwlock_rdlock (mutex : access pthread_rwlock_t) return int; + pragma Import (C, pthread_rwlock_rdlock, "pthread_rwlock_rdlock"); + + function pthread_rwlock_wrlock (mutex : access pthread_rwlock_t) return int; + pragma Import (C, pthread_rwlock_wrlock, "pthread_rwlock_wrlock"); + + function pthread_rwlock_unlock (mutex : access pthread_rwlock_t) return int; + pragma Import (C, pthread_rwlock_unlock, "pthread_rwlock_unlock"); + function pthread_condattr_init (attr : access pthread_condattr_t) return int; pragma Import (C, pthread_condattr_init, "pthread_condattr_init"); @@ -632,6 +674,18 @@ private pragma Convention (C, pthread_mutexattr_t); for pthread_mutexattr_t'Alignment use Interfaces.C.int'Alignment; + type pthread_rwlockattr_t is record + Data : char_array (1 .. OS_Constants.PTHREAD_RWLOCKATTR_SIZE); + end record; + pragma Convention (C, pthread_rwlockattr_t); + for pthread_rwlockattr_t'Alignment use Interfaces.C.unsigned_long'Alignment; + + type pthread_rwlock_t is record + Data : char_array (1 .. OS_Constants.PTHREAD_RWLOCK_SIZE); + end record; + pragma Convention (C, pthread_rwlock_t); + for pthread_rwlock_t'Alignment use Interfaces.C.unsigned_long'Alignment; + type pthread_cond_t is record Data : char_array (1 .. OS_Constants.PTHREAD_COND_SIZE); end record; diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c index 04ca270f085..3dc76f9ab1f 100644 --- a/gcc/ada/sysdep.c +++ b/gcc/ada/sysdep.c @@ -331,7 +331,7 @@ __gnat_ttyname (int filedes ATTRIBUTE_UNUSED) #endif /* defined (__vxworks) */ } #endif - + #if defined (__linux__) || defined (__sun__) \ || defined (WINNT) \ || defined (__MACHTEN__) || defined (__hpux__) || defined (_AIX) \ @@ -1070,6 +1070,11 @@ _getpagesize (void) { return getpagesize (); } + +int +__gnat_has_cap_sys_nice () { + return 0; +} #endif int -- 2.43.0