From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1698) id E533B3857816; Mon, 11 Oct 2021 20:35:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E533B3857816 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Iain D Sandoe To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/iains/heads/d-for-darwin)] libphobos: Add more uses of getTargetInfo(osxVersionMin). Implement posix_memalign if missing X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/users/iains/heads/d-for-darwin X-Git-Oldrev: 3ad1f9e192e579fc590ed6551ac9b3ff47db3e2e X-Git-Newrev: 203974b454a9f6698628e992f327865f3e8c6e3a Message-Id: <20211011203509.E533B3857816@sourceware.org> Date: Mon, 11 Oct 2021 20:35:09 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Oct 2021 20:35:10 -0000 https://gcc.gnu.org/g:203974b454a9f6698628e992f327865f3e8c6e3a commit 203974b454a9f6698628e992f327865f3e8c6e3a Author: Iain Buclaw 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