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

Reply via email to