public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2021-04-19 18:05 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2021-04-19 18:05 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:602ec2295e4336dac4e86354ae125ee7a12247de

commit 602ec2295e4336dac4e86354ae125ee7a12247de
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |   8 ++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  18 ++-
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  35 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 8 files changed, 193 insertions(+), 49 deletions(-)

diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 2de6e579575..7f15d569d0f 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -922,6 +922,8 @@ else version (CRuntime_UClibc)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -968,7 +970,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         version (AArch64)
         {
@@ -990,14 +1000,6 @@ else version (Darwin)
             alias __isnanl = __isnan;
         }
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
index 87f3fd4dae6..a6b94eda157 100644
--- a/libphobos/libdruntime/core/sys/darwin/config.d
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -19,6 +19,14 @@ version (Darwin):
 
 public import core.sys.posix.config;
 
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
 enum __MAC_10_0    = 100000;
 enum __MAC_10_1    = 100100;
 enum __MAC_10_2    = 100200;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 6e28bfa655b..02d57433429 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,14 +28,18 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-
-void         _dyld_register_func_for_add_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
 
 int NSVersionOfRunTimeLibrary(const char* libraryPath);
 int NSVersionOfLinkTimeLibrary(const char* libraryPath);
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 456cde96cbd..9a1aaafd440 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(const scope char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
 int pthread_create_suspended_np(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
-int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
+int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index fcd9fcbc29c..2e38c0c7e2e 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -373,12 +373,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index 4c10d4e0ed5..57e369d41a5 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -119,7 +119,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2021-09-17 14:34 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2021-09-17 14:34 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:32fd4cf4a06d4a94b594a3a5fc47aaac50143306

commit 32fd4cf4a06d4a94b594a3a5fc47aaac50143306
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |   8 ++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  18 ++-
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  35 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 8 files changed, 193 insertions(+), 49 deletions(-)

diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 2de6e579575..7f15d569d0f 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -922,6 +922,8 @@ else version (CRuntime_UClibc)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -968,7 +970,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         version (AArch64)
         {
@@ -990,14 +1000,6 @@ else version (Darwin)
             alias __isnanl = __isnan;
         }
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
index 87f3fd4dae6..a6b94eda157 100644
--- a/libphobos/libdruntime/core/sys/darwin/config.d
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -19,6 +19,14 @@ version (Darwin):
 
 public import core.sys.posix.config;
 
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
 enum __MAC_10_0    = 100000;
 enum __MAC_10_1    = 100100;
 enum __MAC_10_2    = 100200;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 6e28bfa655b..02d57433429 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,14 +28,18 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-
-void         _dyld_register_func_for_add_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
 
 int NSVersionOfRunTimeLibrary(const char* libraryPath);
 int NSVersionOfLinkTimeLibrary(const char* libraryPath);
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 456cde96cbd..9a1aaafd440 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(const scope char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
 int pthread_create_suspended_np(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
-int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
+int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index fcd9fcbc29c..2e38c0c7e2e 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -373,12 +373,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index 4c10d4e0ed5..57e369d41a5 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -119,7 +119,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2021-04-10 17:00 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2021-04-10 17:00 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5cfae020518a666ed9e7be1b321622337e33dbcc

commit 5cfae020518a666ed9e7be1b321622337e33dbcc
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  26 ++--
 libphobos/libdruntime/Makefile.in                  |  37 +++---
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  18 ++-
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  35 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 10 files changed, 278 insertions(+), 80 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 02a68b10424..b28307ff91e 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -205,19 +205,19 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/fcntl.d \
-	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
-	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
-	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
-	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
-	core/sys/darwin/stdlib.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
-	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \
-	core/sys/darwin/sys/sysctl.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/fcntl.d core/sys/darwin/ifaddrs.d \
+	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
+	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
+	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
+	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
+	core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
+	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
+	core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 853a7fc1981..3601b328f00 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -254,11 +254,11 @@ am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
 	core/sys/posix/time.lo core/sys/posix/ucontext.lo \
 	core/sys/posix/unistd.lo core/sys/posix/utime.lo
 @DRUNTIME_OS_POSIX_TRUE@am__objects_4 = $(am__objects_3)
-am__objects_5 = core/sys/darwin/crt_externs.lo \
-	core/sys/darwin/dlfcn.lo core/sys/darwin/err.lo \
-	core/sys/darwin/execinfo.lo core/sys/darwin/fcntl.lo \
-	core/sys/darwin/ifaddrs.lo core/sys/darwin/mach/dyld.lo \
-	core/sys/darwin/mach/getsect.lo \
+am__objects_5 = core/sys/darwin/config.lo \
+	core/sys/darwin/crt_externs.lo core/sys/darwin/dlfcn.lo \
+	core/sys/darwin/err.lo core/sys/darwin/execinfo.lo \
+	core/sys/darwin/fcntl.lo core/sys/darwin/ifaddrs.lo \
+	core/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \
 	core/sys/darwin/mach/kern_return.lo \
 	core/sys/darwin/mach/loader.lo core/sys/darwin/mach/nlist.lo \
 	core/sys/darwin/mach/port.lo core/sys/darwin/mach/semaphore.lo \
@@ -838,19 +838,19 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/fcntl.d \
-	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
-	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
-	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
-	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
-	core/sys/darwin/stdlib.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
-	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \
-	core/sys/darwin/sys/sysctl.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/fcntl.d core/sys/darwin/ifaddrs.d \
+	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
+	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
+	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
+	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
+	core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
+	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
+	core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
@@ -1347,6 +1347,7 @@ core/sys/posix/utime.lo: core/sys/posix/$(am__dirstamp)
 core/sys/darwin/$(am__dirstamp):
 	@$(MKDIR_P) core/sys/darwin
 	@: > core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/config.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/crt_externs.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/dlfcn.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/err.lo: core/sys/darwin/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index fba78ee233a..04341017960 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -919,6 +919,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -965,7 +967,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         version (AArch64)
         {
@@ -987,14 +997,6 @@ else version (Darwin)
             alias __isnanl = __isnan;
         }
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 6e28bfa655b..02d57433429 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,14 +28,18 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-
-void         _dyld_register_func_for_add_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
 
 int NSVersionOfRunTimeLibrary(const char* libraryPath);
 int NSVersionOfLinkTimeLibrary(const char* libraryPath);
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 456cde96cbd..9a1aaafd440 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(const scope char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
 int pthread_create_suspended_np(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
-int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
+int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index b253f86b0ea..4ace0ef8945 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -373,12 +373,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index 4c10d4e0ed5..57e369d41a5 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -119,7 +119,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2021-04-10 15:04 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2021-04-10 15:04 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5505792a44241c437fa20f4beaf0dd5e0fa7e448

commit 5505792a44241c437fa20f4beaf0dd5e0fa7e448
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  26 ++--
 libphobos/libdruntime/Makefile.in                  |  37 +++---
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  18 ++-
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  35 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 10 files changed, 278 insertions(+), 80 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 02a68b10424..b28307ff91e 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -205,19 +205,19 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/fcntl.d \
-	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
-	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
-	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
-	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
-	core/sys/darwin/stdlib.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
-	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \
-	core/sys/darwin/sys/sysctl.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/fcntl.d core/sys/darwin/ifaddrs.d \
+	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
+	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
+	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
+	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
+	core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
+	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
+	core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 853a7fc1981..3601b328f00 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -254,11 +254,11 @@ am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
 	core/sys/posix/time.lo core/sys/posix/ucontext.lo \
 	core/sys/posix/unistd.lo core/sys/posix/utime.lo
 @DRUNTIME_OS_POSIX_TRUE@am__objects_4 = $(am__objects_3)
-am__objects_5 = core/sys/darwin/crt_externs.lo \
-	core/sys/darwin/dlfcn.lo core/sys/darwin/err.lo \
-	core/sys/darwin/execinfo.lo core/sys/darwin/fcntl.lo \
-	core/sys/darwin/ifaddrs.lo core/sys/darwin/mach/dyld.lo \
-	core/sys/darwin/mach/getsect.lo \
+am__objects_5 = core/sys/darwin/config.lo \
+	core/sys/darwin/crt_externs.lo core/sys/darwin/dlfcn.lo \
+	core/sys/darwin/err.lo core/sys/darwin/execinfo.lo \
+	core/sys/darwin/fcntl.lo core/sys/darwin/ifaddrs.lo \
+	core/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \
 	core/sys/darwin/mach/kern_return.lo \
 	core/sys/darwin/mach/loader.lo core/sys/darwin/mach/nlist.lo \
 	core/sys/darwin/mach/port.lo core/sys/darwin/mach/semaphore.lo \
@@ -838,19 +838,19 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/fcntl.d \
-	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
-	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
-	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
-	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
-	core/sys/darwin/stdlib.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
-	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \
-	core/sys/darwin/sys/sysctl.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/fcntl.d core/sys/darwin/ifaddrs.d \
+	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
+	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
+	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
+	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
+	core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
+	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
+	core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
@@ -1347,6 +1347,7 @@ core/sys/posix/utime.lo: core/sys/posix/$(am__dirstamp)
 core/sys/darwin/$(am__dirstamp):
 	@$(MKDIR_P) core/sys/darwin
 	@: > core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/config.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/crt_externs.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/dlfcn.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/err.lo: core/sys/darwin/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index fba78ee233a..04341017960 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -919,6 +919,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -965,7 +967,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         version (AArch64)
         {
@@ -987,14 +997,6 @@ else version (Darwin)
             alias __isnanl = __isnan;
         }
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 6e28bfa655b..02d57433429 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,14 +28,18 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-
-void         _dyld_register_func_for_add_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
 
 int NSVersionOfRunTimeLibrary(const char* libraryPath);
 int NSVersionOfLinkTimeLibrary(const char* libraryPath);
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 456cde96cbd..9a1aaafd440 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(const scope char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
 int pthread_create_suspended_np(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
-int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
+int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index b253f86b0ea..4ace0ef8945 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -373,12 +373,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index 4c10d4e0ed5..57e369d41a5 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -119,7 +119,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2021-03-14 22:00 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2021-03-14 22:00 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:83b3dcc0714eda8244d149317531b12fc4bceb3a

commit 83b3dcc0714eda8244d149317531b12fc4bceb3a
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  25 ++--
 libphobos/libdruntime/Makefile.in                  |  35 ++---
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  18 ++-
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  35 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 10 files changed, 278 insertions(+), 77 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index c332d1787df..9d66f07c19a 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -206,18 +206,19 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/ifaddrs.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
-	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \
-	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
+	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
+	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/stdlib.d core/sys/darwin/string.d \
+	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \
+	core/sys/darwin/sys/sysctl.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 23c161f96d0..1bb20559e20 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -255,10 +255,11 @@ am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
 	core/sys/posix/time.lo core/sys/posix/ucontext.lo \
 	core/sys/posix/unistd.lo core/sys/posix/utime.lo
 @DRUNTIME_OS_POSIX_TRUE@am__objects_4 = $(am__objects_3)
-am__objects_5 = core/sys/darwin/crt_externs.lo \
-	core/sys/darwin/dlfcn.lo core/sys/darwin/err.lo \
-	core/sys/darwin/execinfo.lo core/sys/darwin/ifaddrs.lo \
-	core/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \
+am__objects_5 = core/sys/darwin/config.lo \
+	core/sys/darwin/crt_externs.lo core/sys/darwin/dlfcn.lo \
+	core/sys/darwin/err.lo core/sys/darwin/execinfo.lo \
+	core/sys/darwin/ifaddrs.lo core/sys/darwin/mach/dyld.lo \
+	core/sys/darwin/mach/getsect.lo \
 	core/sys/darwin/mach/kern_return.lo \
 	core/sys/darwin/mach/loader.lo core/sys/darwin/mach/nlist.lo \
 	core/sys/darwin/mach/port.lo core/sys/darwin/mach/semaphore.lo \
@@ -833,18 +834,19 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/ifaddrs.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
-	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \
-	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
+	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
+	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/stdlib.d core/sys/darwin/string.d \
+	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \
+	core/sys/darwin/sys/sysctl.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
@@ -1341,6 +1343,7 @@ core/sys/posix/utime.lo: core/sys/posix/$(am__dirstamp)
 core/sys/darwin/$(am__dirstamp):
 	@$(MKDIR_P) core/sys/darwin
 	@: > core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/config.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/crt_externs.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/dlfcn.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/err.lo: core/sys/darwin/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index e8d1fa8e7b5..19bedd47006 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         version (AArch64)
         {
@@ -1057,14 +1067,6 @@ else version (Darwin)
             alias __isnanl = __isnan;
         }
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 6e28bfa655b..02d57433429 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,14 +28,18 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-
-void         _dyld_register_func_for_add_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
 
 int NSVersionOfRunTimeLibrary(const char* libraryPath);
 int NSVersionOfLinkTimeLibrary(const char* libraryPath);
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 456cde96cbd..9a1aaafd440 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(const scope char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
 int pthread_create_suspended_np(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
-int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
+int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index b253f86b0ea..4ace0ef8945 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -373,12 +373,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index 4c10d4e0ed5..57e369d41a5 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -119,7 +119,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2021-03-07 17:01 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2021-03-07 17:01 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a161f87230064cc01cf8de535f58f87503eec405

commit a161f87230064cc01cf8de535f58f87503eec405
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  25 ++--
 libphobos/libdruntime/Makefile.in                  |  35 ++---
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  18 ++-
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  35 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 10 files changed, 278 insertions(+), 77 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index c332d1787df..9d66f07c19a 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -206,18 +206,19 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/ifaddrs.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
-	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \
-	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
+	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
+	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/stdlib.d core/sys/darwin/string.d \
+	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \
+	core/sys/darwin/sys/sysctl.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 23c161f96d0..1bb20559e20 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -255,10 +255,11 @@ am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
 	core/sys/posix/time.lo core/sys/posix/ucontext.lo \
 	core/sys/posix/unistd.lo core/sys/posix/utime.lo
 @DRUNTIME_OS_POSIX_TRUE@am__objects_4 = $(am__objects_3)
-am__objects_5 = core/sys/darwin/crt_externs.lo \
-	core/sys/darwin/dlfcn.lo core/sys/darwin/err.lo \
-	core/sys/darwin/execinfo.lo core/sys/darwin/ifaddrs.lo \
-	core/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \
+am__objects_5 = core/sys/darwin/config.lo \
+	core/sys/darwin/crt_externs.lo core/sys/darwin/dlfcn.lo \
+	core/sys/darwin/err.lo core/sys/darwin/execinfo.lo \
+	core/sys/darwin/ifaddrs.lo core/sys/darwin/mach/dyld.lo \
+	core/sys/darwin/mach/getsect.lo \
 	core/sys/darwin/mach/kern_return.lo \
 	core/sys/darwin/mach/loader.lo core/sys/darwin/mach/nlist.lo \
 	core/sys/darwin/mach/port.lo core/sys/darwin/mach/semaphore.lo \
@@ -833,18 +834,19 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/ifaddrs.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
-	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \
-	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
+	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
+	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/stdlib.d core/sys/darwin/string.d \
+	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \
+	core/sys/darwin/sys/sysctl.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
@@ -1341,6 +1343,7 @@ core/sys/posix/utime.lo: core/sys/posix/$(am__dirstamp)
 core/sys/darwin/$(am__dirstamp):
 	@$(MKDIR_P) core/sys/darwin
 	@: > core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/config.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/crt_externs.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/dlfcn.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/err.lo: core/sys/darwin/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index e8d1fa8e7b5..19bedd47006 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         version (AArch64)
         {
@@ -1057,14 +1067,6 @@ else version (Darwin)
             alias __isnanl = __isnan;
         }
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 6e28bfa655b..02d57433429 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,14 +28,18 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-
-void         _dyld_register_func_for_add_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
 
 int NSVersionOfRunTimeLibrary(const char* libraryPath);
 int NSVersionOfLinkTimeLibrary(const char* libraryPath);
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 456cde96cbd..9a1aaafd440 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(const scope char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
 int pthread_create_suspended_np(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
-int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
+int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index b253f86b0ea..4ace0ef8945 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -373,12 +373,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index 4c10d4e0ed5..57e369d41a5 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -119,7 +119,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2021-01-30 19:08 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2021-01-30 19:08 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:e51772ca8c87426efc1a8056f8df879879d8e98b

commit e51772ca8c87426efc1a8056f8df879879d8e98b
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  23 ++--
 libphobos/libdruntime/Makefile.in                  |  33 ++---
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  19 +--
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  35 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 10 files changed, 276 insertions(+), 76 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 6402f26b1b8..9673613a98b 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -205,17 +205,18 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/string.d \
 	core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/ifaddrs.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
-	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
-	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
+	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
+	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
+	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
+	core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index c82a6e75060..31eb921ef7f 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -254,10 +254,11 @@ am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
 	core/sys/posix/time.lo core/sys/posix/ucontext.lo \
 	core/sys/posix/unistd.lo core/sys/posix/utime.lo
 @DRUNTIME_OS_POSIX_TRUE@am__objects_4 = $(am__objects_3)
-am__objects_5 = core/sys/darwin/crt_externs.lo \
-	core/sys/darwin/dlfcn.lo core/sys/darwin/err.lo \
-	core/sys/darwin/execinfo.lo core/sys/darwin/ifaddrs.lo \
-	core/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \
+am__objects_5 = core/sys/darwin/config.lo \
+	core/sys/darwin/crt_externs.lo core/sys/darwin/dlfcn.lo \
+	core/sys/darwin/err.lo core/sys/darwin/execinfo.lo \
+	core/sys/darwin/ifaddrs.lo core/sys/darwin/mach/dyld.lo \
+	core/sys/darwin/mach/getsect.lo \
 	core/sys/darwin/mach/kern_return.lo \
 	core/sys/darwin/mach/loader.lo core/sys/darwin/mach/nlist.lo \
 	core/sys/darwin/mach/port.lo core/sys/darwin/mach/semaphore.lo \
@@ -824,17 +825,18 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/string.d \
 	core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/ifaddrs.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
-	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
-	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
+	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
+	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
+	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
+	core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
@@ -1324,6 +1326,7 @@ core/sys/posix/utime.lo: core/sys/posix/$(am__dirstamp)
 core/sys/darwin/$(am__dirstamp):
 	@$(MKDIR_P) core/sys/darwin
 	@: > core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/config.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/crt_externs.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/dlfcn.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/err.lo: core/sys/darwin/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index e8d1fa8e7b5..19bedd47006 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         version (AArch64)
         {
@@ -1057,14 +1067,6 @@ else version (Darwin)
             alias __isnanl = __isnan;
         }
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 62d1a779262..cfb333559f5 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,12 +28,15 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-void         _dyld_register_func_for_add_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
-
-
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 456cde96cbd..9a1aaafd440 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(const scope char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
 int pthread_create_suspended_np(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
-int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
+int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index b253f86b0ea..4ace0ef8945 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -373,12 +373,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index 4c10d4e0ed5..57e369d41a5 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -119,7 +119,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2021-01-28 17:31 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2021-01-28 17:31 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:35bef91d219c7b101a98556870c0b3aa159f5df3

commit 35bef91d219c7b101a98556870c0b3aa159f5df3
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  23 ++--
 libphobos/libdruntime/Makefile.in                  |  33 ++---
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  19 +--
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  35 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 10 files changed, 276 insertions(+), 76 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 6402f26b1b8..9673613a98b 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -205,17 +205,18 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/string.d \
 	core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/ifaddrs.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
-	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
-	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
+	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
+	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
+	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
+	core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index c82a6e75060..31eb921ef7f 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -254,10 +254,11 @@ am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
 	core/sys/posix/time.lo core/sys/posix/ucontext.lo \
 	core/sys/posix/unistd.lo core/sys/posix/utime.lo
 @DRUNTIME_OS_POSIX_TRUE@am__objects_4 = $(am__objects_3)
-am__objects_5 = core/sys/darwin/crt_externs.lo \
-	core/sys/darwin/dlfcn.lo core/sys/darwin/err.lo \
-	core/sys/darwin/execinfo.lo core/sys/darwin/ifaddrs.lo \
-	core/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \
+am__objects_5 = core/sys/darwin/config.lo \
+	core/sys/darwin/crt_externs.lo core/sys/darwin/dlfcn.lo \
+	core/sys/darwin/err.lo core/sys/darwin/execinfo.lo \
+	core/sys/darwin/ifaddrs.lo core/sys/darwin/mach/dyld.lo \
+	core/sys/darwin/mach/getsect.lo \
 	core/sys/darwin/mach/kern_return.lo \
 	core/sys/darwin/mach/loader.lo core/sys/darwin/mach/nlist.lo \
 	core/sys/darwin/mach/port.lo core/sys/darwin/mach/semaphore.lo \
@@ -824,17 +825,18 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
 	core/sys/bionic/fcntl.d core/sys/bionic/string.d \
 	core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/err.d \
-	core/sys/darwin/execinfo.d core/sys/darwin/ifaddrs.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
-	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \
-	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+	core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \
+	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
+	core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
+	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
+	core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
@@ -1324,6 +1326,7 @@ core/sys/posix/utime.lo: core/sys/posix/$(am__dirstamp)
 core/sys/darwin/$(am__dirstamp):
 	@$(MKDIR_P) core/sys/darwin
 	@: > core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/config.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/crt_externs.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/dlfcn.lo: core/sys/darwin/$(am__dirstamp)
 core/sys/darwin/err.lo: core/sys/darwin/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index e8d1fa8e7b5..19bedd47006 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         version (AArch64)
         {
@@ -1057,14 +1067,6 @@ else version (Darwin)
             alias __isnanl = __isnan;
         }
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 62d1a779262..cfb333559f5 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,12 +28,15 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-void         _dyld_register_func_for_add_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
-
-
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 456cde96cbd..9a1aaafd440 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(const scope char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
 int pthread_create_suspended_np(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
-int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
+int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index b253f86b0ea..4ace0ef8945 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -373,12 +373,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index 4c10d4e0ed5..57e369d41a5 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -119,7 +119,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2021-01-11 11:39 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2021-01-11 11:39 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:8d7b3215105dc0235bd262f8f4c9e1460406e39a

commit 8d7b3215105dc0235bd262f8f4c9e1460406e39a
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  18 +--
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  19 +--
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  33 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 9 files changed, 254 insertions(+), 58 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 81774d92528..bbe8eaea82e 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -215,15 +215,15 @@ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
 DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/execinfo.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/execinfo.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 492978939d8..5578cfddd97 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         pure int __fpclassify(real x);
         pure int __isfinite(real x);
@@ -1046,14 +1056,6 @@ else version (Darwin)
         alias __isinfl = __isinf;
         alias __isnanl = __isnan;
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 5bf5609a203..cfb333559f5 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,12 +28,15 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-
-
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 786d9f2833d..d70ab58e54a 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(in char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, in timespec*);
 int pthread_create_suspended_np(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
 int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 0b3f8436254..932923321f9 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -372,12 +372,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index a218f958077..e7c09f640c1 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -118,7 +118,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2020-12-22 13:41 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2020-12-22 13:41 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:e2a55fdb96573c129d00e3d3a09c8a0cf206ce96

commit e2a55fdb96573c129d00e3d3a09c8a0cf206ce96
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  18 +--
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  19 +--
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  33 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 9 files changed, 254 insertions(+), 58 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 1ebc97af39d..124d5b049d0 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -215,15 +215,15 @@ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
 DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/execinfo.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/execinfo.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 492978939d8..5578cfddd97 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         pure int __fpclassify(real x);
         pure int __isfinite(real x);
@@ -1046,14 +1056,6 @@ else version (Darwin)
         alias __isinfl = __isinf;
         alias __isnanl = __isnan;
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 5bf5609a203..cfb333559f5 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,12 +28,15 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-
-
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 786d9f2833d..d70ab58e54a 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(in char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, in timespec*);
 int pthread_create_suspended_np(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
 int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 0b3f8436254..932923321f9 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -372,12 +372,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index a218f958077..e7c09f640c1 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -118,7 +118,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2020-12-09  9:51 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2020-12-09  9:51 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:2d77ec373c3cc81d5fc5be25eff3815f4b4c5716

commit 2d77ec373c3cc81d5fc5be25eff3815f4b4c5716
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  18 +--
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  19 +--
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  33 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 9 files changed, 254 insertions(+), 58 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 1ebc97af39d..124d5b049d0 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -215,15 +215,15 @@ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
 DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/execinfo.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/execinfo.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 492978939d8..5578cfddd97 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         pure int __fpclassify(real x);
         pure int __isfinite(real x);
@@ -1046,14 +1056,6 @@ else version (Darwin)
         alias __isinfl = __isinf;
         alias __isnanl = __isnan;
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 5bf5609a203..cfb333559f5 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,12 +28,15 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-
-
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 786d9f2833d..d70ab58e54a 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(in char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, in timespec*);
 int pthread_create_suspended_np(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
 int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 0b3f8436254..932923321f9 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -372,12 +372,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index a218f958077..e7c09f640c1 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -118,7 +118,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2020-12-05 23:47 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2020-12-05 23:47 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:05db5d986f274e8ecad8b42a97c2a7f4bf40d8c7

commit 05db5d986f274e8ecad8b42a97c2a7f4bf40d8c7
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  18 +--
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  19 +--
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  33 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 9 files changed, 254 insertions(+), 58 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 1ebc97af39d..124d5b049d0 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -215,15 +215,15 @@ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
 DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/execinfo.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/execinfo.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 492978939d8..5578cfddd97 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         pure int __fpclassify(real x);
         pure int __isfinite(real x);
@@ -1046,14 +1056,6 @@ else version (Darwin)
         alias __isinfl = __isinf;
         alias __isnanl = __isnan;
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 5bf5609a203..cfb333559f5 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,12 +28,15 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-
-
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 786d9f2833d..d70ab58e54a 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(in char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, in timespec*);
 int pthread_create_suspended_np(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
 int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 0b3f8436254..932923321f9 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -372,12 +372,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index a218f958077..e7c09f640c1 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -118,7 +118,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2020-12-05 23:38 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2020-12-05 23:38 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:14428cd45819980e11005a855f321d045df4bd60

commit 14428cd45819980e11005a855f321d045df4bd60
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  18 +--
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  19 +--
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  33 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 141 ++++++++++++++++++---
 9 files changed, 254 insertions(+), 58 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 1ebc97af39d..124d5b049d0 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -215,15 +215,15 @@ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
 DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/execinfo.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/execinfo.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 492978939d8..5578cfddd97 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         pure int __fpclassify(real x);
         pure int __isfinite(real x);
@@ -1046,14 +1056,6 @@ else version (Darwin)
         alias __isinfl = __isinf;
         alias __isnanl = __isnan;
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 5bf5609a203..cfb333559f5 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,12 +28,15 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-
-
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 786d9f2833d..d70ab58e54a 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(in char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, in timespec*);
 int pthread_create_suspended_np(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
 int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 0b3f8436254..932923321f9 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -372,12 +372,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index a218f958077..e7c09f640c1 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -118,7 +118,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..6e1866bc976 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,84 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+                return null;
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +304,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +349,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +375,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2020-12-05 23:29 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2020-12-05 23:29 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b7c5b7c8b71aacbaf3b6220b954df90b03e824c1

commit b7c5b7c8b71aacbaf3b6220b954df90b03e824c1
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  18 +--
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  19 +--
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  33 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 145 ++++++++++++++++++---
 9 files changed, 258 insertions(+), 58 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 1ebc97af39d..124d5b049d0 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -215,15 +215,15 @@ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
 DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/execinfo.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/execinfo.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 492978939d8..5578cfddd97 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         pure int __fpclassify(real x);
         pure int __isfinite(real x);
@@ -1046,14 +1056,6 @@ else version (Darwin)
         alias __isinfl = __isinf;
         alias __isnanl = __isnan;
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 5bf5609a203..cfb333559f5 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,12 +28,15 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-
-
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 786d9f2833d..d70ab58e54a 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(in char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, in timespec*);
 int pthread_create_suspended_np(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
 int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 0b3f8436254..932923321f9 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -372,12 +372,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index a218f958077..e7c09f640c1 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -118,7 +118,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..789f83ef975 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,88 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+            {
+                //to https://msdn.microsoft.com/en-us/library/ms235462.aspx
+                //see Return value: in this case the original block is unchanged
+                return null;
+            }
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +308,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +353,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +379,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!newSize)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, newSize, alignment);
+            if (!p) return false;
+            b = p[0 .. newSize];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2020-12-05 23:27 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2020-12-05 23:27 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:be73178f444d22aaea2c4c9898171c778b40189f

commit be73178f444d22aaea2c4c9898171c778b40189f
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  18 +--
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  19 +--
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  33 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 145 ++++++++++++++++++---
 9 files changed, 258 insertions(+), 58 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 1ebc97af39d..124d5b049d0 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -215,15 +215,15 @@ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
 DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/execinfo.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/execinfo.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 492978939d8..5578cfddd97 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         pure int __fpclassify(real x);
         pure int __isfinite(real x);
@@ -1046,14 +1056,6 @@ else version (Darwin)
         alias __isinfl = __isinf;
         alias __isnanl = __isnan;
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..347aea41f6b
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 100100;
+enum __MAC_10_2    = 100200;
+enum __MAC_10_3    = 100300;
+enum __MAC_10_4    = 100400;
+enum __MAC_10_5    = 100500;
+enum __MAC_10_6    = 100600;
+enum __MAC_10_7    = 100700;
+enum __MAC_10_8    = 100800;
+enum __MAC_10_9    = 100900;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 5bf5609a203..cfb333559f5 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,12 +28,15 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-
-
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 786d9f2833d..d70ab58e54a 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(in char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, in timespec*);
 int pthread_create_suspended_np(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
 int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 0b3f8436254..932923321f9 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -372,12 +372,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index a218f958077..e7c09f640c1 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -118,7 +118,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..ccd4ff157d7 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,88 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+            {
+                //to https://msdn.microsoft.com/en-us/library/ms235462.aspx
+                //see Return value: in this case the original block is unchanged
+                return null;
+            }
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +308,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +353,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +379,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!s)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, s, a);
+            if (!p) return false;
+            b = p[0 .. s];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing
@ 2020-12-05 23:20 Iain Buclaw
  0 siblings, 0 replies; 16+ messages in thread
From: Iain Buclaw @ 2020-12-05 23:20 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:88ee56dbbf1eeffea98688f3890cafcd8bc842d2

commit 88ee56dbbf1eeffea98688f3890cafcd8bc842d2
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sun Dec 6 00:19:39 2020 +0100

    libphobos: Add more uses of getTargetInfo(osxVersionMin).  Implement posix_memalign if missing

Diff:
---
 libphobos/libdruntime/Makefile.am                  |  18 +--
 libphobos/libdruntime/core/stdc/math.d             |  20 +--
 libphobos/libdruntime/core/sys/darwin/config.d     |  61 +++++++++
 libphobos/libdruntime/core/sys/darwin/mach/dyld.d  |  19 +--
 libphobos/libdruntime/core/sys/darwin/pthread.d    |  33 +++--
 libphobos/libdruntime/core/sys/darwin/string.d     |   8 +-
 libphobos/libdruntime/core/sys/posix/stdio.d       |   4 +-
 libphobos/libdruntime/core/sys/posix/stdlib.d      |   8 +-
 .../src/std/experimental/allocator/mallocator.d    | 145 ++++++++++++++++++---
 9 files changed, 258 insertions(+), 58 deletions(-)

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 1ebc97af39d..124d5b049d0 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -215,15 +215,15 @@ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
 DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \
 	core/sys/bionic/string.d core/sys/bionic/unistd.d
 
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
-	core/sys/darwin/dlfcn.d core/sys/darwin/execinfo.d \
-	core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
-	core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
-	core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
-	core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
-	core/sys/darwin/pthread.d core/sys/darwin/string.d \
-	core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
-	core/sys/darwin/sys/mman.d
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+	core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+	core/sys/darwin/execinfo.d core/sys/darwin/mach/dyld.d \
+	core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \
+	core/sys/darwin/mach/loader.d core/sys/darwin/mach/port.d \
+	core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/thread_act.d \
+	core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \
+	core/sys/darwin/string.d core/sys/darwin/sys/cdefs.d \
+	core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d
 
 DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
 	core/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 492978939d8..5578cfddd97 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -989,6 +989,8 @@ else version (MinGW)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum
     {
         ///
@@ -1035,7 +1037,15 @@ else version (Darwin)
     // Support of OSX < 10.8 needs legacy function names without "l" suffix
     // with exception of __signbitl.  Otherwise could use else version like
     // other Darwins
-    version (OSX)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_8)
+    {
+        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
+        pure int __fpclassifyl(real x);
+        pure int __isfinitel(real x);
+        pure int __isinfl(real x);
+        pure int __isnanl(real x);
+    }
+    else
     {
         pure int __fpclassify(real x);
         pure int __isfinite(real x);
@@ -1046,14 +1056,6 @@ else version (Darwin)
         alias __isinfl = __isinf;
         alias __isnanl = __isnan;
     }
-    else
-    {
-        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS
-        pure int __fpclassifyl(real x);
-        pure int __isfinitel(real x);
-        pure int __isinfl(real x);
-        pure int __isnanl(real x);
-    }
 
   extern (D)
   {
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 00000000000..a9514eebb5a
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,61 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2020 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+    version = Darwin;
+else version (iOS)
+    version = Darwin;
+else version (TVOS)
+    version = Darwin;
+else version (WatchOS)
+    version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+// The compiler exposes `__traits(getTargetInfo, "osxVersionMin")` as a way to
+// obtain the lower bound support OSX version. In some compilers this is
+// controlled by a command-line option:
+//  -mmacosx-version-min=   (on OSX).
+//  -miphoneos-version-min= (on iOS)
+//  -mtvos-version-min=     (on TVOS)
+//  -mwatchos-version-min=  (on WatchOS)
+
+enum __MAC_10_0    = 100000;
+enum __MAC_10_1    = 101000;
+enum __MAC_10_2    = 102000;
+enum __MAC_10_3    = 103000;
+enum __MAC_10_4    = 104000;
+enum __MAC_10_5    = 105000;
+enum __MAC_10_6    = 106000;
+enum __MAC_10_7    = 107000;
+enum __MAC_10_8    = 108000;
+enum __MAC_10_9    = 109000;
+enum __MAC_10_10   = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11   = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12   = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13   = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14   = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15   = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16   = 101501;
+enum __MAC_11_0    = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 5bf5609a203..cfb333559f5 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -28,12 +28,15 @@ nothrow:
 
 public import core.stdc.stdint; // for intptr_t
 public import core.sys.darwin.mach.loader;
+import core.sys.darwin.config;
 
-uint         _dyld_image_count();
-const(char)* _dyld_get_image_name(uint image_index);
-mach_header* _dyld_get_image_header(uint image_index);
-intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
-void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-
-
+// __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_1)
+{
+    uint         _dyld_image_count();
+    const(char)* _dyld_get_image_name(uint image_index);
+    mach_header* _dyld_get_image_header(uint image_index);
+    intptr_t     _dyld_get_image_vmaddr_slide(uint image_index);
+    void         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+    void         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 786d9f2833d..d70ab58e54a 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -29,22 +29,32 @@ nothrow:
 
 public import core.sys.posix.pthread;
 public import core.sys.darwin.mach.port;
+import core.sys.darwin.config;
 
 int pthread_is_threaded_np();
-int pthread_threadid_np(pthread_t, ulong*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_threadid_np(pthread_t, ulong*);
+}
+// __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+{
+    int pthread_rwlock_longrdlock_np(pthread_rwlock_t*);
+    int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);
+}
 int pthread_rwlock_downgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_upgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);
 int pthread_rwlock_held_np(pthread_rwlock_t*);
 int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
 int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
-int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(in char*);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+// __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+{
+    int pthread_getname_np(pthread_t, char*, size_t);
+    int pthread_setname_np(in char*);
+}
 int pthread_main_np();
 mach_port_t pthread_mach_thread_np(pthread_t);
 size_t pthread_get_stacksize_np(pthread_t);
@@ -53,8 +63,11 @@ int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
 int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, in timespec*);
 int pthread_create_suspended_np(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
 int pthread_kill(pthread_t, int);
-pthread_t pthread_from_mach_thread_np(mach_port_t);
-// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+// __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
+static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_5)
+{
+    pthread_t pthread_from_mach_thread_np(mach_port_t);
+}
 int pthread_sigmask(int, in sigset_t*, sigset_t*);
 // ^ __DARWIN_ALIAS(pthread_sigmask)
 void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..20dcd1fdc81 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -9,6 +9,7 @@ module core.sys.darwin.string;
 
 public import core.stdc.string;
 import core.sys.darwin.sys.cdefs;
+import core.sys.darwin.config;
 
 version (OSX)
     version = Darwin;
@@ -26,6 +27,9 @@ nothrow:
 
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
-    // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    // __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
+    {
+        pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    }
 }
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 0b3f8436254..932923321f9 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -372,12 +372,14 @@ else version (CRuntime_Bionic)
 }
 else version (Darwin)
 {
+    import core.sys.darwin.config;
+
     enum L_ctermid = 1024;
 
     int   fseeko(FILE*, off_t, int);
     off_t ftello(FILE*);
 
-    static if (__traits(getTargetInfo, "osxVersionMin") >= 100700)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_7)
     {
         ssize_t getdelim(char**, size_t*, int, FILE*);
         ssize_t getline(char**, size_t*, FILE*);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index a218f958077..e7c09f640c1 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -118,7 +118,13 @@ else version (Solaris)
 }
 else version (Darwin)
 {
-    int posix_memalign(void**, size_t, size_t);
+    import core.sys.darwin.config;
+
+    // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    static if (__traits(getTargetInfo, "osxVersionMin") >= __MAC_10_6)
+    {
+        int posix_memalign(void**, size_t, size_t);
+    }
 }
 else version (CRuntime_Bionic)
 {
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 2d1dec39a74..ccd4ff157d7 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -194,6 +194,88 @@ version (Windows)
     }
 }
 
+version (Posix)
+{
+    // Not all platforms have posix_memalign available, supply own implementation
+    // if this is the case.  Avoid calling it posix_memalign because it needs
+    // special handling for realloc and free cases.
+    static if (!__traits(compiles, { import core.sys.posix.stdlib : posix_memalign; }))
+    {
+        // Helper to cast the infos written before the aligned pointer
+        // this header keeps track of the size (required to realloc) and of
+        // the base ptr (required to free).
+        private struct AlignInfo
+        {
+            void* basePtr;
+            size_t size;
+
+            @nogc nothrow
+            static AlignInfo* opCall(void* ptr)
+            {
+                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
+            }
+        }
+
+        @nogc nothrow
+        private void* _aligned_malloc(size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : malloc;
+            size_t offset = alignment + size_t.sizeof * 2 - 1;
+
+            // unaligned chunk
+            void* basePtr = malloc(size + offset);
+            if (!basePtr) return null;
+
+            // get aligned location within the chunk
+            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
+                & ~(alignment - 1));
+
+            // write the header before the aligned pointer
+            AlignInfo* head = AlignInfo(alignedPtr);
+            head.basePtr = basePtr;
+            head.size = size;
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
+        {
+            import core.stdc.stdlib : free;
+            import core.stdc.string : memcpy;
+
+            if (!ptr) return _aligned_malloc(size, alignment);
+
+            // gets the header from the exising pointer
+            AlignInfo* head = AlignInfo(ptr);
+
+            // gets a new aligned pointer
+            void* alignedPtr = _aligned_malloc(size, alignment);
+            if (!alignedPtr)
+            {
+                //to https://msdn.microsoft.com/en-us/library/ms235462.aspx
+                //see Return value: in this case the original block is unchanged
+                return null;
+            }
+
+            // copy exising data
+            memcpy(alignedPtr, ptr, head.size);
+            free(head.basePtr);
+
+            return alignedPtr;
+        }
+
+        @nogc nothrow
+        private void _aligned_free(void *ptr)
+        {
+            import core.stdc.stdlib : free;
+            if (!ptr) return;
+            AlignInfo* head = AlignInfo(ptr);
+            free(head.basePtr);
+        }
+    }
+}
+
 /**
    Aligned allocator using OS-specific primitives, under a uniform API.
  */
@@ -226,24 +308,32 @@ struct AlignedMallocator
     @trusted @nogc nothrow
     void[] alignedAllocate(size_t bytes, uint a) shared
     {
-        import core.stdc.errno : ENOMEM, EINVAL;
-        import core.sys.posix.stdlib : posix_memalign;
-        assert(a.isGoodDynamicAlignment);
-        void* result;
-        auto code = posix_memalign(&result, a, bytes);
-        if (code == ENOMEM)
-            return null;
-
-        else if (code == EINVAL)
+        static if (__traits(compiles, _aligned_malloc))
         {
-            assert(0, "AlignedMallocator.alignment is not a power of two "
-                ~"multiple of (void*).sizeof, according to posix_memalign!");
+            auto result = _aligned_malloc(bytes, a);
+            return result ? result[0 .. bytes] : null;
         }
-        else if (code != 0)
-            assert(0, "posix_memalign returned an unknown code!");
-
         else
-            return result[0 .. bytes];
+        {
+            import core.stdc.errno : ENOMEM, EINVAL;
+            import core.sys.posix.stdlib : posix_memalign;
+            assert(a.isGoodDynamicAlignment);
+            void* result;
+            auto code = posix_memalign(&result, a, bytes);
+            if (code == ENOMEM)
+                return null;
+
+            else if (code == EINVAL)
+            {
+                assert(0, "AlignedMallocator.alignment is not a power of two "
+                    ~"multiple of (void*).sizeof, according to posix_memalign!");
+            }
+            else if (code != 0)
+                assert(0, "posix_memalign returned an unknown code!");
+
+            else
+                return result[0 .. bytes];
+        }
     }
     else version (Windows)
     @trusted @nogc nothrow
@@ -263,8 +353,13 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool deallocate(void[] b) shared
     {
-        import core.stdc.stdlib : free;
-        free(b.ptr);
+        static if (__traits(compiles, _aligned_free))
+            _aligned_free(b.ptr);
+        else
+        {
+            import core.stdc.stdlib : free;
+            free(b.ptr);
+        }
         return true;
     }
     else version (Windows)
@@ -284,7 +379,21 @@ struct AlignedMallocator
     @system @nogc nothrow
     bool reallocate(ref void[] b, size_t newSize) shared
     {
-        return Mallocator.instance.reallocate(b, newSize);
+        static if (__traits(compiles, _aligned_realloc))
+        {
+            if (!s)
+            {
+                deallocate(b);
+                b = null;
+                return true;
+            }
+            auto p = cast(ubyte*) _aligned_realloc(b.ptr, s, a);
+            if (!p) return false;
+            b = p[0 .. s];
+            return true;
+        }
+        else
+            return Mallocator.instance.reallocate(b, newSize);
     }
     version (Windows)
     @system @nogc nothrow


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2021-09-17 14:34 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-19 18:05 [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing Iain Buclaw
  -- strict thread matches above, loose matches on Subject: below --
2021-09-17 14:34 Iain Buclaw
2021-04-10 17:00 Iain Buclaw
2021-04-10 15:04 Iain Buclaw
2021-03-14 22:00 Iain Buclaw
2021-03-07 17:01 Iain Buclaw
2021-01-30 19:08 Iain Buclaw
2021-01-28 17:31 Iain Buclaw
2021-01-11 11:39 Iain Buclaw
2020-12-22 13:41 Iain Buclaw
2020-12-09  9:51 Iain Buclaw
2020-12-05 23:47 Iain Buclaw
2020-12-05 23:38 Iain Buclaw
2020-12-05 23:29 Iain Buclaw
2020-12-05 23:27 Iain Buclaw
2020-12-05 23:20 Iain Buclaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).