From: Iain Buclaw Date: Thu, 28 Jan 2021 10:18:42 +0000 (+0100) Subject: libphobos: Synchronize libdruntime bindings with upstream druntime X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=92dd3e71f957c7818f4ce4189bd187b59af20d9b;p=gcc.git libphobos: Synchronize libdruntime bindings with upstream druntime Reviewed-on: https://github.com/dlang/druntime/pull/3348 gcc/d/ChangeLog: * typeinfo.cc (TypeInfoVisitor::visit (TypeInfoDeclaration *)): Don't layout m_arg1 and m_arg2 fields. libphobos/ChangeLog: * Makefile.in: Regenerate. * configure: Regenerate. * libdruntime/MERGE: Merge upstream druntime e4aae28e. * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Refresh module list. (DRUNTIME_DSOURCES_BIONIC): Add core/sys/bionic/err.d. (DRUNTIME_DSOURCES_DARWIN): Add core/sys/darwin/err.d, core/sys/darwin/ifaddrs.d, core/sys/darwin/mach/nlist.d, core/sys/darwin/mach/stab.d, and core/sys/darwin/sys/attr.d. (DRUNTIME_DSOURCES_DRAGONFLYBSD): Add core/sys/dragonflybsd/err.d. (DRUNTIME_DSOURCES_FREEBSD): Add core/sys/freebsd/err.d. (DRUNTIME_DSOURCES_LINUX): Add core/sys/linux/err.d. (DRUNTIME_DSOURCES_NETBSD): Add core/sys/netbsd/err.d. (DRUNTIME_DSOURCES_OPENBSD): Add core/sys/openbsd/err.d. (DRUNTIME_DSOURCES_POSIX): Add core/sys/posix/locale.d, core/sys/posix/stdc/time.d, core/sys/posix/string.d, and core/sys/posix/strings.d. (DRUNTIME_DSOURCES_SOLARIS): Add core/sys/solaris/err.d. (DRUNTIME_DSOURCES_WINDOWS): Add core/sys/windows/sdkddkver.d, and core/sys/windows/stdc/time.d * libdruntime/Makefile.in: Regenerate. * libdruntime/gcc/sections/elf_shared.d (sizeofTLS): New function. * testsuite/libphobos.thread/fiber_guard_page.d: Use __traits(getMember) to get internal fields. --- diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc index 4e31127b1a1..ec8539deb45 100644 --- a/gcc/d/typeinfo.cc +++ b/gcc/d/typeinfo.cc @@ -1013,9 +1013,6 @@ public: void function(void*) xdtor; void function(void*) xpostblit; uint m_align; - version (X86_64) - TypeInfo m_arg1; - TypeInfo m_arg2; immutable(void)* xgetRTInfo; */ void visit (TypeInfoStructDeclaration *d) @@ -1091,19 +1088,6 @@ public: /* uint m_align; */ this->layout_field (build_integer_cst (ti->alignsize (), d_uint_type)); - if (global.params.is64bit) - { - /* TypeInfo m_arg1; */ - tree arg1type = (sd->arg1type) ? build_typeinfo (d->loc, sd->arg1type) - : null_pointer_node; - this->layout_field (arg1type); - - /* TypeInfo m_arg2; */ - tree arg2type = (sd->arg2type) ? build_typeinfo (d->loc, sd->arg2type) - : null_pointer_node; - this->layout_field (arg2type); - } - /* immutable(void)* xgetRTInfo; */ if (sd->getRTInfo) this->layout_field (build_expr (sd->getRTInfo, true)); diff --git a/libphobos/Makefile.in b/libphobos/Makefile.in index a1395929819..d42248405a2 100644 --- a/libphobos/Makefile.in +++ b/libphobos/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # Makefile for the toplevel directory of the D Standard library. -# Copyright (C) 2006-2020 Free Software Foundation, Inc. +# Copyright (C) 2006-2021 Free Software Foundation, Inc. # # GCC is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/libphobos/configure b/libphobos/configure index 1c32a552d40..c940a404be4 100755 --- a/libphobos/configure +++ b/libphobos/configure @@ -11746,7 +11746,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11759 "configure" +#line 11749 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11852,7 +11852,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11865 "configure" +#line 11855 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 7162844b9b6..4654e58e2d9 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -0fe7974cf53b75db59461de2a3d6e53ce933d297 +e4aae28e36c118f13e346a61af6c413aadd8e838 The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository. diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am index 34d3b41df82..57de872862b 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -178,8 +178,10 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ core/stdc/tgmath.d core/stdc/time.d core/stdc/wchar_.d \ core/stdc/wctype.d core/sync/barrier.d core/sync/condition.d \ core/sync/config.d core/sync/exception.d core/sync/mutex.d \ - core/sync/rwmutex.d core/sync/semaphore.d core/thread.d core/time.d \ - core/vararg.d gc/bits.d gc/config.d gc/gcinterface.d \ + core/sync/rwmutex.d core/sync/semaphore.d core/thread/context.d \ + core/thread/fiber.d core/thread/osthread.d core/thread/package.d \ + core/thread/threadbase.d core/thread/threadgroup.d core/thread/types.d \ + core/time.d core/vararg.d gc/bits.d gc/config.d gc/gcinterface.d \ gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.d gc/pooltable.d \ gc/proxy.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \ gcc/emutls.d gcc/gthread.d gcc/sections/android.d \ @@ -191,20 +193,6 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ rt/cast_.d rt/config.d rt/critical_.d rt/deh.d rt/dmain2.d \ rt/invariant.d rt/lifetime.d rt/memory.d rt/minfo.d rt/monitor_.d \ rt/obj.d rt/qsort.d rt/sections.d rt/switch_.d rt/tlsgc.d \ - rt/typeinfo/ti_Acdouble.d rt/typeinfo/ti_Acfloat.d \ - rt/typeinfo/ti_Acreal.d rt/typeinfo/ti_Adouble.d \ - rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d rt/typeinfo/ti_Aint.d \ - rt/typeinfo/ti_Along.d rt/typeinfo/ti_Areal.d rt/typeinfo/ti_Ashort.d \ - rt/typeinfo/ti_C.d rt/typeinfo/ti_byte.d rt/typeinfo/ti_cdouble.d \ - rt/typeinfo/ti_cent.d rt/typeinfo/ti_cfloat.d rt/typeinfo/ti_char.d \ - rt/typeinfo/ti_creal.d rt/typeinfo/ti_dchar.d \ - rt/typeinfo/ti_delegate.d rt/typeinfo/ti_double.d \ - rt/typeinfo/ti_float.d rt/typeinfo/ti_idouble.d \ - rt/typeinfo/ti_ifloat.d rt/typeinfo/ti_int.d rt/typeinfo/ti_ireal.d \ - rt/typeinfo/ti_long.d rt/typeinfo/ti_n.d rt/typeinfo/ti_ptr.d \ - rt/typeinfo/ti_real.d rt/typeinfo/ti_short.d rt/typeinfo/ti_ubyte.d \ - rt/typeinfo/ti_ucent.d rt/typeinfo/ti_uint.d rt/typeinfo/ti_ulong.d \ - rt/typeinfo/ti_ushort.d rt/typeinfo/ti_void.d rt/typeinfo/ti_wchar.d \ rt/util/array.d rt/util/container/array.d rt/util/container/common.d \ rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \ rt/util/typeinfo.d rt/util/utf.d @@ -212,23 +200,26 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \ core/stdcpp/typeinfo.d -DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \ - core/sys/bionic/string.d core/sys/bionic/unistd.d +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/execinfo.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/port.d core/sys/darwin/mach/semaphore.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/cdefs.d core/sys/darwin/sys/event.d \ - core/sys/darwin/sys/mman.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/execinfo.d core/sys/dragonflybsd/netinet/in_.d \ - core/sys/dragonflybsd/pthread_np.d core/sys/dragonflybsd/string.d \ - core/sys/dragonflybsd/sys/_bitset.d \ + core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \ + core/sys/dragonflybsd/netinet/in_.d core/sys/dragonflybsd/pthread_np.d \ + core/sys/dragonflybsd/string.d core/sys/dragonflybsd/sys/_bitset.d \ core/sys/dragonflybsd/sys/_cpuset.d core/sys/dragonflybsd/sys/cdefs.d \ core/sys/dragonflybsd/sys/elf.d core/sys/dragonflybsd/sys/elf32.d \ core/sys/dragonflybsd/sys/elf64.d \ @@ -238,19 +229,20 @@ DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \ core/sys/dragonflybsd/time.d DRUNTIME_DSOURCES_FREEBSD = core/sys/freebsd/config.d \ - core/sys/freebsd/dlfcn.d core/sys/freebsd/execinfo.d \ - core/sys/freebsd/netinet/in_.d core/sys/freebsd/pthread_np.d \ - core/sys/freebsd/string.d core/sys/freebsd/sys/_bitset.d \ - core/sys/freebsd/sys/_cpuset.d core/sys/freebsd/sys/cdefs.d \ - core/sys/freebsd/sys/elf.d core/sys/freebsd/sys/elf32.d \ - core/sys/freebsd/sys/elf64.d core/sys/freebsd/sys/elf_common.d \ - core/sys/freebsd/sys/event.d core/sys/freebsd/sys/link_elf.d \ - core/sys/freebsd/sys/mman.d core/sys/freebsd/sys/mount.d \ - core/sys/freebsd/time.d core/sys/freebsd/unistd.d + core/sys/freebsd/dlfcn.d core/sys/freebsd/err.d \ + core/sys/freebsd/execinfo.d core/sys/freebsd/netinet/in_.d \ + core/sys/freebsd/pthread_np.d core/sys/freebsd/string.d \ + core/sys/freebsd/sys/_bitset.d core/sys/freebsd/sys/_cpuset.d \ + core/sys/freebsd/sys/cdefs.d core/sys/freebsd/sys/elf.d \ + core/sys/freebsd/sys/elf32.d core/sys/freebsd/sys/elf64.d \ + core/sys/freebsd/sys/elf_common.d core/sys/freebsd/sys/event.d \ + core/sys/freebsd/sys/link_elf.d core/sys/freebsd/sys/mman.d \ + core/sys/freebsd/sys/mount.d core/sys/freebsd/time.d \ + core/sys/freebsd/unistd.d DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \ core/sys/linux/dlfcn.d core/sys/linux/elf.d core/sys/linux/epoll.d \ - core/sys/linux/errno.d core/sys/linux/execinfo.d \ + core/sys/linux/err.d core/sys/linux/errno.d core/sys/linux/execinfo.d \ core/sys/linux/fcntl.d core/sys/linux/ifaddrs.d core/sys/linux/link.d \ core/sys/linux/netinet/in_.d core/sys/linux/netinet/tcp.d \ core/sys/linux/sched.d core/sys/linux/stdio.d core/sys/linux/string.d \ @@ -264,54 +256,56 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \ core/sys/linux/unistd.d DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \ - core/sys/netbsd/execinfo.d core/sys/netbsd/string.d \ - core/sys/netbsd/sys/elf.d core/sys/netbsd/sys/elf32.d \ - core/sys/netbsd/sys/elf64.d core/sys/netbsd/sys/elf_common.d \ - core/sys/netbsd/sys/event.d core/sys/netbsd/sys/featuretest.d \ - core/sys/netbsd/sys/link_elf.d core/sys/netbsd/sys/mman.d \ - core/sys/netbsd/time.d + core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \ + core/sys/netbsd/string.d core/sys/netbsd/sys/elf.d \ + core/sys/netbsd/sys/elf32.d core/sys/netbsd/sys/elf64.d \ + core/sys/netbsd/sys/elf_common.d core/sys/netbsd/sys/event.d \ + core/sys/netbsd/sys/featuretest.d core/sys/netbsd/sys/link_elf.d \ + core/sys/netbsd/sys/mman.d core/sys/netbsd/time.d DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \ - core/sys/openbsd/string.d core/sys/openbsd/sys/cdefs.d \ - core/sys/openbsd/sys/elf.d core/sys/openbsd/sys/elf32.d \ - core/sys/openbsd/sys/elf64.d core/sys/openbsd/sys/elf_common.d \ - core/sys/openbsd/sys/link_elf.d core/sys/openbsd/sys/mman.d \ - core/sys/openbsd/time.d + core/sys/openbsd/err.d core/sys/openbsd/string.d \ + core/sys/openbsd/sys/cdefs.d core/sys/openbsd/sys/elf.d \ + core/sys/openbsd/sys/elf32.d core/sys/openbsd/sys/elf64.d \ + core/sys/openbsd/sys/elf_common.d core/sys/openbsd/sys/link_elf.d \ + core/sys/openbsd/sys/mman.d core/sys/openbsd/time.d DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \ core/sys/posix/arpa/inet.d core/sys/posix/config.d \ core/sys/posix/dirent.d core/sys/posix/dlfcn.d core/sys/posix/fcntl.d \ core/sys/posix/grp.d core/sys/posix/iconv.d core/sys/posix/inttypes.d \ - core/sys/posix/libgen.d core/sys/posix/mqueue.d \ - core/sys/posix/net/if_.d core/sys/posix/netdb.d \ - core/sys/posix/netinet/in_.d core/sys/posix/netinet/tcp.d \ - core/sys/posix/poll.d core/sys/posix/pthread.d core/sys/posix/pwd.d \ - core/sys/posix/sched.d core/sys/posix/semaphore.d \ - core/sys/posix/setjmp.d core/sys/posix/signal.d core/sys/posix/spawn.d \ - core/sys/posix/stdio.d core/sys/posix/stdlib.d \ - core/sys/posix/sys/filio.d core/sys/posix/sys/ioccom.d \ - core/sys/posix/sys/ioctl.d core/sys/posix/sys/ipc.d \ - core/sys/posix/sys/mman.d core/sys/posix/sys/msg.d \ - core/sys/posix/sys/resource.d core/sys/posix/sys/select.d \ - core/sys/posix/sys/shm.d core/sys/posix/sys/socket.d \ - core/sys/posix/sys/stat.d core/sys/posix/sys/statvfs.d \ - core/sys/posix/sys/time.d core/sys/posix/sys/ttycom.d \ - core/sys/posix/sys/types.d core/sys/posix/sys/uio.d \ - core/sys/posix/sys/un.d core/sys/posix/sys/utsname.d \ - core/sys/posix/sys/wait.d core/sys/posix/syslog.d \ - core/sys/posix/termios.d core/sys/posix/time.d \ + core/sys/posix/libgen.d core/sys/posix/locale.d \ + core/sys/posix/mqueue.d core/sys/posix/net/if_.d \ + core/sys/posix/netdb.d core/sys/posix/netinet/in_.d \ + core/sys/posix/netinet/tcp.d core/sys/posix/poll.d \ + core/sys/posix/pthread.d core/sys/posix/pwd.d core/sys/posix/sched.d \ + core/sys/posix/semaphore.d core/sys/posix/setjmp.d \ + core/sys/posix/signal.d core/sys/posix/spawn.d \ + core/sys/posix/stdc/time.d core/sys/posix/stdio.d \ + core/sys/posix/stdlib.d core/sys/posix/string.d \ + core/sys/posix/strings.d core/sys/posix/sys/filio.d \ + core/sys/posix/sys/ioccom.d core/sys/posix/sys/ioctl.d \ + core/sys/posix/sys/ipc.d core/sys/posix/sys/mman.d \ + core/sys/posix/sys/msg.d core/sys/posix/sys/resource.d \ + core/sys/posix/sys/select.d core/sys/posix/sys/shm.d \ + core/sys/posix/sys/socket.d core/sys/posix/sys/stat.d \ + core/sys/posix/sys/statvfs.d core/sys/posix/sys/time.d \ + core/sys/posix/sys/ttycom.d core/sys/posix/sys/types.d \ + core/sys/posix/sys/uio.d core/sys/posix/sys/un.d \ + core/sys/posix/sys/utsname.d core/sys/posix/sys/wait.d \ + core/sys/posix/syslog.d core/sys/posix/termios.d core/sys/posix/time.d \ core/sys/posix/ucontext.d core/sys/posix/unistd.d \ core/sys/posix/utime.d DRUNTIME_DSOURCES_SOLARIS = core/sys/solaris/dlfcn.d \ - core/sys/solaris/elf.d core/sys/solaris/execinfo.d \ - core/sys/solaris/libelf.d core/sys/solaris/link.d \ - core/sys/solaris/sys/elf.d core/sys/solaris/sys/elf_386.d \ - core/sys/solaris/sys/elf_SPARC.d core/sys/solaris/sys/elf_amd64.d \ - core/sys/solaris/sys/elf_notes.d core/sys/solaris/sys/elftypes.d \ - core/sys/solaris/sys/link.d core/sys/solaris/sys/priocntl.d \ - core/sys/solaris/sys/procset.d core/sys/solaris/sys/types.d \ - core/sys/solaris/time.d + core/sys/solaris/elf.d core/sys/solaris/err.d \ + core/sys/solaris/execinfo.d core/sys/solaris/libelf.d \ + core/sys/solaris/link.d core/sys/solaris/sys/elf.d \ + core/sys/solaris/sys/elf_386.d core/sys/solaris/sys/elf_SPARC.d \ + core/sys/solaris/sys/elf_amd64.d core/sys/solaris/sys/elf_notes.d \ + core/sys/solaris/sys/elftypes.d core/sys/solaris/sys/link.d \ + core/sys/solaris/sys/priocntl.d core/sys/solaris/sys/procset.d \ + core/sys/solaris/sys/types.d core/sys/solaris/time.d DRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \ core/sys/windows/aclapi.d core/sys/windows/aclui.d \ @@ -371,15 +365,16 @@ DRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \ core/sys/windows/rpcdcep.d core/sys/windows/rpcndr.d \ core/sys/windows/rpcnsi.d core/sys/windows/rpcnsip.d \ core/sys/windows/rpcnterr.d core/sys/windows/schannel.d \ - core/sys/windows/secext.d core/sys/windows/security.d \ - core/sys/windows/servprov.d core/sys/windows/setupapi.d \ - core/sys/windows/shellapi.d core/sys/windows/shldisp.d \ - core/sys/windows/shlguid.d core/sys/windows/shlobj.d \ - core/sys/windows/shlwapi.d core/sys/windows/snmp.d \ - core/sys/windows/sql.d core/sys/windows/sqlext.d \ - core/sys/windows/sqltypes.d core/sys/windows/sqlucode.d \ - core/sys/windows/sspi.d core/sys/windows/stacktrace.d \ - core/sys/windows/stat.d core/sys/windows/subauth.d \ + core/sys/windows/sdkddkver.d core/sys/windows/secext.d \ + core/sys/windows/security.d core/sys/windows/servprov.d \ + core/sys/windows/setupapi.d core/sys/windows/shellapi.d \ + core/sys/windows/shldisp.d core/sys/windows/shlguid.d \ + core/sys/windows/shlobj.d core/sys/windows/shlwapi.d \ + core/sys/windows/snmp.d core/sys/windows/sql.d \ + core/sys/windows/sqlext.d core/sys/windows/sqltypes.d \ + core/sys/windows/sqlucode.d core/sys/windows/sspi.d \ + core/sys/windows/stacktrace.d core/sys/windows/stat.d \ + core/sys/windows/stdc/time.d core/sys/windows/subauth.d \ core/sys/windows/threadaux.d core/sys/windows/tlhelp32.d \ core/sys/windows/tmschema.d core/sys/windows/unknwn.d \ core/sys/windows/uuid.d core/sys/windows/vfw.d \ diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 99ee8b92afa..e1b0a851b67 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # Makefile for the D runtime library. -# Copyright (C) 2012-2020 Free Software Foundation, Inc. +# Copyright (C) 2012-2021 Free Software Foundation, Inc. # # GCC is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -202,7 +202,10 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \ core/stdc/wctype.lo core/sync/barrier.lo \ core/sync/condition.lo core/sync/config.lo \ core/sync/exception.lo core/sync/mutex.lo core/sync/rwmutex.lo \ - core/sync/semaphore.lo core/thread.lo core/time.lo \ + core/sync/semaphore.lo core/thread/context.lo \ + core/thread/fiber.lo core/thread/osthread.lo \ + core/thread/package.lo core/thread/threadbase.lo \ + core/thread/threadgroup.lo core/thread/types.lo core/time.lo \ core/vararg.lo gc/bits.lo gc/config.lo gc/gcinterface.lo \ gc/impl/conservative/gc.lo gc/impl/manual/gc.lo gc/os.lo \ gc/pooltable.lo gc/proxy.lo gcc/attribute.lo gcc/backtrace.lo \ @@ -217,43 +220,26 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \ rt/config.lo rt/critical_.lo rt/deh.lo rt/dmain2.lo \ rt/invariant.lo rt/lifetime.lo rt/memory.lo rt/minfo.lo \ rt/monitor_.lo rt/obj.lo rt/qsort.lo rt/sections.lo \ - rt/switch_.lo rt/tlsgc.lo rt/typeinfo/ti_Acdouble.lo \ - rt/typeinfo/ti_Acfloat.lo rt/typeinfo/ti_Acreal.lo \ - rt/typeinfo/ti_Adouble.lo rt/typeinfo/ti_Afloat.lo \ - rt/typeinfo/ti_Ag.lo rt/typeinfo/ti_Aint.lo \ - rt/typeinfo/ti_Along.lo rt/typeinfo/ti_Areal.lo \ - rt/typeinfo/ti_Ashort.lo rt/typeinfo/ti_C.lo \ - rt/typeinfo/ti_byte.lo rt/typeinfo/ti_cdouble.lo \ - rt/typeinfo/ti_cent.lo rt/typeinfo/ti_cfloat.lo \ - rt/typeinfo/ti_char.lo rt/typeinfo/ti_creal.lo \ - rt/typeinfo/ti_dchar.lo rt/typeinfo/ti_delegate.lo \ - rt/typeinfo/ti_double.lo rt/typeinfo/ti_float.lo \ - rt/typeinfo/ti_idouble.lo rt/typeinfo/ti_ifloat.lo \ - rt/typeinfo/ti_int.lo rt/typeinfo/ti_ireal.lo \ - rt/typeinfo/ti_long.lo rt/typeinfo/ti_n.lo \ - rt/typeinfo/ti_ptr.lo rt/typeinfo/ti_real.lo \ - rt/typeinfo/ti_short.lo rt/typeinfo/ti_ubyte.lo \ - rt/typeinfo/ti_ucent.lo rt/typeinfo/ti_uint.lo \ - rt/typeinfo/ti_ulong.lo rt/typeinfo/ti_ushort.lo \ - rt/typeinfo/ti_void.lo rt/typeinfo/ti_wchar.lo \ - rt/util/array.lo rt/util/container/array.lo \ - rt/util/container/common.lo rt/util/container/hashtab.lo \ - rt/util/container/treap.lo rt/util/random.lo \ - rt/util/typeinfo.lo rt/util/utf.lo + rt/switch_.lo rt/tlsgc.lo rt/util/array.lo \ + rt/util/container/array.lo rt/util/container/common.lo \ + rt/util/container/hashtab.lo rt/util/container/treap.lo \ + rt/util/random.lo rt/util/typeinfo.lo rt/util/utf.lo am__objects_2 = core/stdc/libgdruntime_la-errno_.lo am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \ core/sys/posix/config.lo core/sys/posix/dirent.lo \ core/sys/posix/dlfcn.lo core/sys/posix/fcntl.lo \ core/sys/posix/grp.lo core/sys/posix/iconv.lo \ core/sys/posix/inttypes.lo core/sys/posix/libgen.lo \ - core/sys/posix/mqueue.lo core/sys/posix/net/if_.lo \ - core/sys/posix/netdb.lo core/sys/posix/netinet/in_.lo \ - core/sys/posix/netinet/tcp.lo core/sys/posix/poll.lo \ - core/sys/posix/pthread.lo core/sys/posix/pwd.lo \ - core/sys/posix/sched.lo core/sys/posix/semaphore.lo \ - core/sys/posix/setjmp.lo core/sys/posix/signal.lo \ - core/sys/posix/spawn.lo core/sys/posix/stdio.lo \ - core/sys/posix/stdlib.lo core/sys/posix/sys/filio.lo \ + core/sys/posix/locale.lo core/sys/posix/mqueue.lo \ + core/sys/posix/net/if_.lo core/sys/posix/netdb.lo \ + core/sys/posix/netinet/in_.lo core/sys/posix/netinet/tcp.lo \ + core/sys/posix/poll.lo core/sys/posix/pthread.lo \ + core/sys/posix/pwd.lo core/sys/posix/sched.lo \ + core/sys/posix/semaphore.lo core/sys/posix/setjmp.lo \ + core/sys/posix/signal.lo core/sys/posix/spawn.lo \ + core/sys/posix/stdc/time.lo core/sys/posix/stdio.lo \ + core/sys/posix/stdlib.lo core/sys/posix/string.lo \ + core/sys/posix/strings.lo core/sys/posix/sys/filio.lo \ core/sys/posix/sys/ioccom.lo core/sys/posix/sys/ioctl.lo \ core/sys/posix/sys/ipc.lo core/sys/posix/sys/mman.lo \ core/sys/posix/sys/msg.lo core/sys/posix/sys/resource.lo \ @@ -268,18 +254,21 @@ am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.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/execinfo.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/port.lo \ - core/sys/darwin/mach/semaphore.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 \ + core/sys/darwin/mach/stab.lo \ core/sys/darwin/mach/thread_act.lo \ core/sys/darwin/netinet/in_.lo core/sys/darwin/pthread.lo \ - core/sys/darwin/string.lo core/sys/darwin/sys/cdefs.lo \ - core/sys/darwin/sys/event.lo core/sys/darwin/sys/mman.lo + core/sys/darwin/string.lo core/sys/darwin/sys/attr.lo \ + core/sys/darwin/sys/cdefs.lo core/sys/darwin/sys/event.lo \ + core/sys/darwin/sys/mman.lo @DRUNTIME_OS_DARWIN_TRUE@am__objects_6 = $(am__objects_5) am__objects_7 = core/sys/dragonflybsd/dlfcn.lo \ - core/sys/dragonflybsd/execinfo.lo \ + core/sys/dragonflybsd/err.lo core/sys/dragonflybsd/execinfo.lo \ core/sys/dragonflybsd/netinet/in_.lo \ core/sys/dragonflybsd/pthread_np.lo \ core/sys/dragonflybsd/string.lo \ @@ -296,13 +285,13 @@ am__objects_7 = core/sys/dragonflybsd/dlfcn.lo \ core/sys/dragonflybsd/sys/socket.lo \ core/sys/dragonflybsd/time.lo @DRUNTIME_OS_DRAGONFLYBSD_TRUE@am__objects_8 = $(am__objects_7) -am__objects_9 = core/sys/bionic/fcntl.lo core/sys/bionic/string.lo \ - core/sys/bionic/unistd.lo +am__objects_9 = core/sys/bionic/err.lo core/sys/bionic/fcntl.lo \ + core/sys/bionic/string.lo core/sys/bionic/unistd.lo @DRUNTIME_OS_ANDROID_TRUE@am__objects_10 = $(am__objects_9) am__objects_11 = core/sys/freebsd/config.lo core/sys/freebsd/dlfcn.lo \ - core/sys/freebsd/execinfo.lo core/sys/freebsd/netinet/in_.lo \ - core/sys/freebsd/pthread_np.lo core/sys/freebsd/string.lo \ - core/sys/freebsd/sys/_bitset.lo \ + core/sys/freebsd/err.lo core/sys/freebsd/execinfo.lo \ + core/sys/freebsd/netinet/in_.lo core/sys/freebsd/pthread_np.lo \ + core/sys/freebsd/string.lo core/sys/freebsd/sys/_bitset.lo \ core/sys/freebsd/sys/_cpuset.lo core/sys/freebsd/sys/cdefs.lo \ core/sys/freebsd/sys/elf.lo core/sys/freebsd/sys/elf32.lo \ core/sys/freebsd/sys/elf64.lo \ @@ -311,36 +300,39 @@ am__objects_11 = core/sys/freebsd/config.lo core/sys/freebsd/dlfcn.lo \ core/sys/freebsd/sys/mman.lo core/sys/freebsd/sys/mount.lo \ core/sys/freebsd/time.lo core/sys/freebsd/unistd.lo @DRUNTIME_OS_FREEBSD_TRUE@am__objects_12 = $(am__objects_11) -am__objects_13 = core/sys/netbsd/dlfcn.lo core/sys/netbsd/execinfo.lo \ - core/sys/netbsd/string.lo core/sys/netbsd/sys/elf.lo \ - core/sys/netbsd/sys/elf32.lo core/sys/netbsd/sys/elf64.lo \ - core/sys/netbsd/sys/elf_common.lo core/sys/netbsd/sys/event.lo \ +am__objects_13 = core/sys/netbsd/dlfcn.lo core/sys/netbsd/err.lo \ + core/sys/netbsd/execinfo.lo core/sys/netbsd/string.lo \ + core/sys/netbsd/sys/elf.lo core/sys/netbsd/sys/elf32.lo \ + core/sys/netbsd/sys/elf64.lo core/sys/netbsd/sys/elf_common.lo \ + core/sys/netbsd/sys/event.lo \ core/sys/netbsd/sys/featuretest.lo \ core/sys/netbsd/sys/link_elf.lo core/sys/netbsd/sys/mman.lo \ core/sys/netbsd/time.lo @DRUNTIME_OS_NETBSD_TRUE@am__objects_14 = $(am__objects_13) -am__objects_15 = core/sys/openbsd/dlfcn.lo core/sys/openbsd/string.lo \ - core/sys/openbsd/sys/cdefs.lo core/sys/openbsd/sys/elf.lo \ - core/sys/openbsd/sys/elf32.lo core/sys/openbsd/sys/elf64.lo \ +am__objects_15 = core/sys/openbsd/dlfcn.lo core/sys/openbsd/err.lo \ + core/sys/openbsd/string.lo core/sys/openbsd/sys/cdefs.lo \ + core/sys/openbsd/sys/elf.lo core/sys/openbsd/sys/elf32.lo \ + core/sys/openbsd/sys/elf64.lo \ core/sys/openbsd/sys/elf_common.lo \ core/sys/openbsd/sys/link_elf.lo core/sys/openbsd/sys/mman.lo \ core/sys/openbsd/time.lo @DRUNTIME_OS_OPENBSD_TRUE@am__objects_16 = $(am__objects_15) am__objects_17 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \ core/sys/linux/elf.lo core/sys/linux/epoll.lo \ - core/sys/linux/errno.lo core/sys/linux/execinfo.lo \ - core/sys/linux/fcntl.lo core/sys/linux/ifaddrs.lo \ - core/sys/linux/link.lo core/sys/linux/netinet/in_.lo \ - core/sys/linux/netinet/tcp.lo core/sys/linux/sched.lo \ - core/sys/linux/stdio.lo core/sys/linux/string.lo \ - core/sys/linux/sys/auxv.lo core/sys/linux/sys/eventfd.lo \ - core/sys/linux/sys/file.lo core/sys/linux/sys/inotify.lo \ - core/sys/linux/sys/mman.lo core/sys/linux/sys/prctl.lo \ - core/sys/linux/sys/signalfd.lo core/sys/linux/sys/socket.lo \ - core/sys/linux/sys/sysinfo.lo core/sys/linux/sys/time.lo \ - core/sys/linux/sys/xattr.lo core/sys/linux/termios.lo \ - core/sys/linux/time.lo core/sys/linux/timerfd.lo \ - core/sys/linux/tipc.lo core/sys/linux/unistd.lo + core/sys/linux/err.lo core/sys/linux/errno.lo \ + core/sys/linux/execinfo.lo core/sys/linux/fcntl.lo \ + core/sys/linux/ifaddrs.lo core/sys/linux/link.lo \ + core/sys/linux/netinet/in_.lo core/sys/linux/netinet/tcp.lo \ + core/sys/linux/sched.lo core/sys/linux/stdio.lo \ + core/sys/linux/string.lo core/sys/linux/sys/auxv.lo \ + core/sys/linux/sys/eventfd.lo core/sys/linux/sys/file.lo \ + core/sys/linux/sys/inotify.lo core/sys/linux/sys/mman.lo \ + core/sys/linux/sys/prctl.lo core/sys/linux/sys/signalfd.lo \ + core/sys/linux/sys/socket.lo core/sys/linux/sys/sysinfo.lo \ + core/sys/linux/sys/time.lo core/sys/linux/sys/xattr.lo \ + core/sys/linux/termios.lo core/sys/linux/time.lo \ + core/sys/linux/timerfd.lo core/sys/linux/tipc.lo \ + core/sys/linux/unistd.lo @DRUNTIME_OS_LINUX_TRUE@am__objects_18 = $(am__objects_17) am__objects_19 = core/sys/windows/accctrl.lo \ core/sys/windows/aclapi.lo core/sys/windows/aclui.lo \ @@ -400,15 +392,16 @@ am__objects_19 = core/sys/windows/accctrl.lo \ core/sys/windows/rpcdce2.lo core/sys/windows/rpcdcep.lo \ core/sys/windows/rpcndr.lo core/sys/windows/rpcnsi.lo \ core/sys/windows/rpcnsip.lo core/sys/windows/rpcnterr.lo \ - core/sys/windows/schannel.lo core/sys/windows/secext.lo \ - core/sys/windows/security.lo core/sys/windows/servprov.lo \ - core/sys/windows/setupapi.lo core/sys/windows/shellapi.lo \ - core/sys/windows/shldisp.lo core/sys/windows/shlguid.lo \ - core/sys/windows/shlobj.lo core/sys/windows/shlwapi.lo \ - core/sys/windows/snmp.lo core/sys/windows/sql.lo \ - core/sys/windows/sqlext.lo core/sys/windows/sqltypes.lo \ - core/sys/windows/sqlucode.lo core/sys/windows/sspi.lo \ - core/sys/windows/stacktrace.lo core/sys/windows/stat.lo \ + core/sys/windows/schannel.lo core/sys/windows/sdkddkver.lo \ + core/sys/windows/secext.lo core/sys/windows/security.lo \ + core/sys/windows/servprov.lo core/sys/windows/setupapi.lo \ + core/sys/windows/shellapi.lo core/sys/windows/shldisp.lo \ + core/sys/windows/shlguid.lo core/sys/windows/shlobj.lo \ + core/sys/windows/shlwapi.lo core/sys/windows/snmp.lo \ + core/sys/windows/sql.lo core/sys/windows/sqlext.lo \ + core/sys/windows/sqltypes.lo core/sys/windows/sqlucode.lo \ + core/sys/windows/sspi.lo core/sys/windows/stacktrace.lo \ + core/sys/windows/stat.lo core/sys/windows/stdc/time.lo \ core/sys/windows/subauth.lo core/sys/windows/threadaux.lo \ core/sys/windows/tlhelp32.lo core/sys/windows/tmschema.lo \ core/sys/windows/unknwn.lo core/sys/windows/uuid.lo \ @@ -427,9 +420,9 @@ am__objects_19 = core/sys/windows/accctrl.lo \ core/sys/windows/wtsapi32.lo core/sys/windows/wtypes.lo @DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19) am__objects_21 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \ - core/sys/solaris/execinfo.lo core/sys/solaris/libelf.lo \ - core/sys/solaris/link.lo core/sys/solaris/sys/elf.lo \ - core/sys/solaris/sys/elf_386.lo \ + core/sys/solaris/err.lo core/sys/solaris/execinfo.lo \ + core/sys/solaris/libelf.lo core/sys/solaris/link.lo \ + core/sys/solaris/sys/elf.lo core/sys/solaris/sys/elf_386.lo \ core/sys/solaris/sys/elf_SPARC.lo \ core/sys/solaris/sys/elf_amd64.lo \ core/sys/solaris/sys/elf_notes.lo \ @@ -803,8 +796,10 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ core/stdc/tgmath.d core/stdc/time.d core/stdc/wchar_.d \ core/stdc/wctype.d core/sync/barrier.d core/sync/condition.d \ core/sync/config.d core/sync/exception.d core/sync/mutex.d \ - core/sync/rwmutex.d core/sync/semaphore.d core/thread.d core/time.d \ - core/vararg.d gc/bits.d gc/config.d gc/gcinterface.d \ + core/sync/rwmutex.d core/sync/semaphore.d core/thread/context.d \ + core/thread/fiber.d core/thread/osthread.d core/thread/package.d \ + core/thread/threadbase.d core/thread/threadgroup.d core/thread/types.d \ + core/time.d core/vararg.d gc/bits.d gc/config.d gc/gcinterface.d \ gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.d gc/pooltable.d \ gc/proxy.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \ gcc/emutls.d gcc/gthread.d gcc/sections/android.d \ @@ -816,20 +811,6 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ rt/cast_.d rt/config.d rt/critical_.d rt/deh.d rt/dmain2.d \ rt/invariant.d rt/lifetime.d rt/memory.d rt/minfo.d rt/monitor_.d \ rt/obj.d rt/qsort.d rt/sections.d rt/switch_.d rt/tlsgc.d \ - rt/typeinfo/ti_Acdouble.d rt/typeinfo/ti_Acfloat.d \ - rt/typeinfo/ti_Acreal.d rt/typeinfo/ti_Adouble.d \ - rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d rt/typeinfo/ti_Aint.d \ - rt/typeinfo/ti_Along.d rt/typeinfo/ti_Areal.d rt/typeinfo/ti_Ashort.d \ - rt/typeinfo/ti_C.d rt/typeinfo/ti_byte.d rt/typeinfo/ti_cdouble.d \ - rt/typeinfo/ti_cent.d rt/typeinfo/ti_cfloat.d rt/typeinfo/ti_char.d \ - rt/typeinfo/ti_creal.d rt/typeinfo/ti_dchar.d \ - rt/typeinfo/ti_delegate.d rt/typeinfo/ti_double.d \ - rt/typeinfo/ti_float.d rt/typeinfo/ti_idouble.d \ - rt/typeinfo/ti_ifloat.d rt/typeinfo/ti_int.d rt/typeinfo/ti_ireal.d \ - rt/typeinfo/ti_long.d rt/typeinfo/ti_n.d rt/typeinfo/ti_ptr.d \ - rt/typeinfo/ti_real.d rt/typeinfo/ti_short.d rt/typeinfo/ti_ubyte.d \ - rt/typeinfo/ti_ucent.d rt/typeinfo/ti_uint.d rt/typeinfo/ti_ulong.d \ - rt/typeinfo/ti_ushort.d rt/typeinfo/ti_void.d rt/typeinfo/ti_wchar.d \ rt/util/array.d rt/util/container/array.d rt/util/container/common.d \ rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \ rt/util/typeinfo.d rt/util/utf.d @@ -837,23 +818,26 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \ core/stdcpp/typeinfo.d -DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \ - core/sys/bionic/string.d core/sys/bionic/unistd.d +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/execinfo.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/port.d core/sys/darwin/mach/semaphore.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/cdefs.d core/sys/darwin/sys/event.d \ - core/sys/darwin/sys/mman.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/execinfo.d core/sys/dragonflybsd/netinet/in_.d \ - core/sys/dragonflybsd/pthread_np.d core/sys/dragonflybsd/string.d \ - core/sys/dragonflybsd/sys/_bitset.d \ + core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \ + core/sys/dragonflybsd/netinet/in_.d core/sys/dragonflybsd/pthread_np.d \ + core/sys/dragonflybsd/string.d core/sys/dragonflybsd/sys/_bitset.d \ core/sys/dragonflybsd/sys/_cpuset.d core/sys/dragonflybsd/sys/cdefs.d \ core/sys/dragonflybsd/sys/elf.d core/sys/dragonflybsd/sys/elf32.d \ core/sys/dragonflybsd/sys/elf64.d \ @@ -863,19 +847,20 @@ DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \ core/sys/dragonflybsd/time.d DRUNTIME_DSOURCES_FREEBSD = core/sys/freebsd/config.d \ - core/sys/freebsd/dlfcn.d core/sys/freebsd/execinfo.d \ - core/sys/freebsd/netinet/in_.d core/sys/freebsd/pthread_np.d \ - core/sys/freebsd/string.d core/sys/freebsd/sys/_bitset.d \ - core/sys/freebsd/sys/_cpuset.d core/sys/freebsd/sys/cdefs.d \ - core/sys/freebsd/sys/elf.d core/sys/freebsd/sys/elf32.d \ - core/sys/freebsd/sys/elf64.d core/sys/freebsd/sys/elf_common.d \ - core/sys/freebsd/sys/event.d core/sys/freebsd/sys/link_elf.d \ - core/sys/freebsd/sys/mman.d core/sys/freebsd/sys/mount.d \ - core/sys/freebsd/time.d core/sys/freebsd/unistd.d + core/sys/freebsd/dlfcn.d core/sys/freebsd/err.d \ + core/sys/freebsd/execinfo.d core/sys/freebsd/netinet/in_.d \ + core/sys/freebsd/pthread_np.d core/sys/freebsd/string.d \ + core/sys/freebsd/sys/_bitset.d core/sys/freebsd/sys/_cpuset.d \ + core/sys/freebsd/sys/cdefs.d core/sys/freebsd/sys/elf.d \ + core/sys/freebsd/sys/elf32.d core/sys/freebsd/sys/elf64.d \ + core/sys/freebsd/sys/elf_common.d core/sys/freebsd/sys/event.d \ + core/sys/freebsd/sys/link_elf.d core/sys/freebsd/sys/mman.d \ + core/sys/freebsd/sys/mount.d core/sys/freebsd/time.d \ + core/sys/freebsd/unistd.d DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \ core/sys/linux/dlfcn.d core/sys/linux/elf.d core/sys/linux/epoll.d \ - core/sys/linux/errno.d core/sys/linux/execinfo.d \ + core/sys/linux/err.d core/sys/linux/errno.d core/sys/linux/execinfo.d \ core/sys/linux/fcntl.d core/sys/linux/ifaddrs.d core/sys/linux/link.d \ core/sys/linux/netinet/in_.d core/sys/linux/netinet/tcp.d \ core/sys/linux/sched.d core/sys/linux/stdio.d core/sys/linux/string.d \ @@ -889,54 +874,56 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \ core/sys/linux/unistd.d DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \ - core/sys/netbsd/execinfo.d core/sys/netbsd/string.d \ - core/sys/netbsd/sys/elf.d core/sys/netbsd/sys/elf32.d \ - core/sys/netbsd/sys/elf64.d core/sys/netbsd/sys/elf_common.d \ - core/sys/netbsd/sys/event.d core/sys/netbsd/sys/featuretest.d \ - core/sys/netbsd/sys/link_elf.d core/sys/netbsd/sys/mman.d \ - core/sys/netbsd/time.d + core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \ + core/sys/netbsd/string.d core/sys/netbsd/sys/elf.d \ + core/sys/netbsd/sys/elf32.d core/sys/netbsd/sys/elf64.d \ + core/sys/netbsd/sys/elf_common.d core/sys/netbsd/sys/event.d \ + core/sys/netbsd/sys/featuretest.d core/sys/netbsd/sys/link_elf.d \ + core/sys/netbsd/sys/mman.d core/sys/netbsd/time.d DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \ - core/sys/openbsd/string.d core/sys/openbsd/sys/cdefs.d \ - core/sys/openbsd/sys/elf.d core/sys/openbsd/sys/elf32.d \ - core/sys/openbsd/sys/elf64.d core/sys/openbsd/sys/elf_common.d \ - core/sys/openbsd/sys/link_elf.d core/sys/openbsd/sys/mman.d \ - core/sys/openbsd/time.d + core/sys/openbsd/err.d core/sys/openbsd/string.d \ + core/sys/openbsd/sys/cdefs.d core/sys/openbsd/sys/elf.d \ + core/sys/openbsd/sys/elf32.d core/sys/openbsd/sys/elf64.d \ + core/sys/openbsd/sys/elf_common.d core/sys/openbsd/sys/link_elf.d \ + core/sys/openbsd/sys/mman.d core/sys/openbsd/time.d DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \ core/sys/posix/arpa/inet.d core/sys/posix/config.d \ core/sys/posix/dirent.d core/sys/posix/dlfcn.d core/sys/posix/fcntl.d \ core/sys/posix/grp.d core/sys/posix/iconv.d core/sys/posix/inttypes.d \ - core/sys/posix/libgen.d core/sys/posix/mqueue.d \ - core/sys/posix/net/if_.d core/sys/posix/netdb.d \ - core/sys/posix/netinet/in_.d core/sys/posix/netinet/tcp.d \ - core/sys/posix/poll.d core/sys/posix/pthread.d core/sys/posix/pwd.d \ - core/sys/posix/sched.d core/sys/posix/semaphore.d \ - core/sys/posix/setjmp.d core/sys/posix/signal.d core/sys/posix/spawn.d \ - core/sys/posix/stdio.d core/sys/posix/stdlib.d \ - core/sys/posix/sys/filio.d core/sys/posix/sys/ioccom.d \ - core/sys/posix/sys/ioctl.d core/sys/posix/sys/ipc.d \ - core/sys/posix/sys/mman.d core/sys/posix/sys/msg.d \ - core/sys/posix/sys/resource.d core/sys/posix/sys/select.d \ - core/sys/posix/sys/shm.d core/sys/posix/sys/socket.d \ - core/sys/posix/sys/stat.d core/sys/posix/sys/statvfs.d \ - core/sys/posix/sys/time.d core/sys/posix/sys/ttycom.d \ - core/sys/posix/sys/types.d core/sys/posix/sys/uio.d \ - core/sys/posix/sys/un.d core/sys/posix/sys/utsname.d \ - core/sys/posix/sys/wait.d core/sys/posix/syslog.d \ - core/sys/posix/termios.d core/sys/posix/time.d \ + core/sys/posix/libgen.d core/sys/posix/locale.d \ + core/sys/posix/mqueue.d core/sys/posix/net/if_.d \ + core/sys/posix/netdb.d core/sys/posix/netinet/in_.d \ + core/sys/posix/netinet/tcp.d core/sys/posix/poll.d \ + core/sys/posix/pthread.d core/sys/posix/pwd.d core/sys/posix/sched.d \ + core/sys/posix/semaphore.d core/sys/posix/setjmp.d \ + core/sys/posix/signal.d core/sys/posix/spawn.d \ + core/sys/posix/stdc/time.d core/sys/posix/stdio.d \ + core/sys/posix/stdlib.d core/sys/posix/string.d \ + core/sys/posix/strings.d core/sys/posix/sys/filio.d \ + core/sys/posix/sys/ioccom.d core/sys/posix/sys/ioctl.d \ + core/sys/posix/sys/ipc.d core/sys/posix/sys/mman.d \ + core/sys/posix/sys/msg.d core/sys/posix/sys/resource.d \ + core/sys/posix/sys/select.d core/sys/posix/sys/shm.d \ + core/sys/posix/sys/socket.d core/sys/posix/sys/stat.d \ + core/sys/posix/sys/statvfs.d core/sys/posix/sys/time.d \ + core/sys/posix/sys/ttycom.d core/sys/posix/sys/types.d \ + core/sys/posix/sys/uio.d core/sys/posix/sys/un.d \ + core/sys/posix/sys/utsname.d core/sys/posix/sys/wait.d \ + core/sys/posix/syslog.d core/sys/posix/termios.d core/sys/posix/time.d \ core/sys/posix/ucontext.d core/sys/posix/unistd.d \ core/sys/posix/utime.d DRUNTIME_DSOURCES_SOLARIS = core/sys/solaris/dlfcn.d \ - core/sys/solaris/elf.d core/sys/solaris/execinfo.d \ - core/sys/solaris/libelf.d core/sys/solaris/link.d \ - core/sys/solaris/sys/elf.d core/sys/solaris/sys/elf_386.d \ - core/sys/solaris/sys/elf_SPARC.d core/sys/solaris/sys/elf_amd64.d \ - core/sys/solaris/sys/elf_notes.d core/sys/solaris/sys/elftypes.d \ - core/sys/solaris/sys/link.d core/sys/solaris/sys/priocntl.d \ - core/sys/solaris/sys/procset.d core/sys/solaris/sys/types.d \ - core/sys/solaris/time.d + core/sys/solaris/elf.d core/sys/solaris/err.d \ + core/sys/solaris/execinfo.d core/sys/solaris/libelf.d \ + core/sys/solaris/link.d core/sys/solaris/sys/elf.d \ + core/sys/solaris/sys/elf_386.d core/sys/solaris/sys/elf_SPARC.d \ + core/sys/solaris/sys/elf_amd64.d core/sys/solaris/sys/elf_notes.d \ + core/sys/solaris/sys/elftypes.d core/sys/solaris/sys/link.d \ + core/sys/solaris/sys/priocntl.d core/sys/solaris/sys/procset.d \ + core/sys/solaris/sys/types.d core/sys/solaris/time.d DRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \ core/sys/windows/aclapi.d core/sys/windows/aclui.d \ @@ -996,15 +983,16 @@ DRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \ core/sys/windows/rpcdcep.d core/sys/windows/rpcndr.d \ core/sys/windows/rpcnsi.d core/sys/windows/rpcnsip.d \ core/sys/windows/rpcnterr.d core/sys/windows/schannel.d \ - core/sys/windows/secext.d core/sys/windows/security.d \ - core/sys/windows/servprov.d core/sys/windows/setupapi.d \ - core/sys/windows/shellapi.d core/sys/windows/shldisp.d \ - core/sys/windows/shlguid.d core/sys/windows/shlobj.d \ - core/sys/windows/shlwapi.d core/sys/windows/snmp.d \ - core/sys/windows/sql.d core/sys/windows/sqlext.d \ - core/sys/windows/sqltypes.d core/sys/windows/sqlucode.d \ - core/sys/windows/sspi.d core/sys/windows/stacktrace.d \ - core/sys/windows/stat.d core/sys/windows/subauth.d \ + core/sys/windows/sdkddkver.d core/sys/windows/secext.d \ + core/sys/windows/security.d core/sys/windows/servprov.d \ + core/sys/windows/setupapi.d core/sys/windows/shellapi.d \ + core/sys/windows/shldisp.d core/sys/windows/shlguid.d \ + core/sys/windows/shlobj.d core/sys/windows/shlwapi.d \ + core/sys/windows/snmp.d core/sys/windows/sql.d \ + core/sys/windows/sqlext.d core/sys/windows/sqltypes.d \ + core/sys/windows/sqlucode.d core/sys/windows/sspi.d \ + core/sys/windows/stacktrace.d core/sys/windows/stat.d \ + core/sys/windows/stdc/time.d core/sys/windows/subauth.d \ core/sys/windows/threadaux.d core/sys/windows/tlhelp32.d \ core/sys/windows/tmschema.d core/sys/windows/unknwn.d \ core/sys/windows/uuid.d core/sys/windows/vfw.d \ @@ -1162,7 +1150,16 @@ core/sync/exception.lo: core/sync/$(am__dirstamp) core/sync/mutex.lo: core/sync/$(am__dirstamp) core/sync/rwmutex.lo: core/sync/$(am__dirstamp) core/sync/semaphore.lo: core/sync/$(am__dirstamp) -core/thread.lo: core/$(am__dirstamp) +core/thread/$(am__dirstamp): + @$(MKDIR_P) core/thread + @: > core/thread/$(am__dirstamp) +core/thread/context.lo: core/thread/$(am__dirstamp) +core/thread/fiber.lo: core/thread/$(am__dirstamp) +core/thread/osthread.lo: core/thread/$(am__dirstamp) +core/thread/package.lo: core/thread/$(am__dirstamp) +core/thread/threadbase.lo: core/thread/$(am__dirstamp) +core/thread/threadgroup.lo: core/thread/$(am__dirstamp) +core/thread/types.lo: core/thread/$(am__dirstamp) core/time.lo: core/$(am__dirstamp) core/vararg.lo: core/$(am__dirstamp) gc/$(am__dirstamp): @@ -1234,46 +1231,6 @@ rt/qsort.lo: rt/$(am__dirstamp) rt/sections.lo: rt/$(am__dirstamp) rt/switch_.lo: rt/$(am__dirstamp) rt/tlsgc.lo: rt/$(am__dirstamp) -rt/typeinfo/$(am__dirstamp): - @$(MKDIR_P) rt/typeinfo - @: > rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_Acdouble.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_Acfloat.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_Acreal.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_Adouble.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_Afloat.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_Ag.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_Aint.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_Along.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_Areal.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_Ashort.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_C.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_byte.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_cdouble.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_cent.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_cfloat.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_char.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_creal.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_dchar.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_delegate.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_double.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_float.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_idouble.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_ifloat.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_int.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_ireal.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_long.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_n.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_ptr.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_real.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_short.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_ubyte.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_ucent.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_uint.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_ulong.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_ushort.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_void.lo: rt/typeinfo/$(am__dirstamp) -rt/typeinfo/ti_wchar.lo: rt/typeinfo/$(am__dirstamp) rt/util/$(am__dirstamp): @$(MKDIR_P) rt/util @: > rt/util/$(am__dirstamp) @@ -1305,6 +1262,7 @@ core/sys/posix/grp.lo: core/sys/posix/$(am__dirstamp) core/sys/posix/iconv.lo: core/sys/posix/$(am__dirstamp) core/sys/posix/inttypes.lo: core/sys/posix/$(am__dirstamp) core/sys/posix/libgen.lo: core/sys/posix/$(am__dirstamp) +core/sys/posix/locale.lo: core/sys/posix/$(am__dirstamp) core/sys/posix/mqueue.lo: core/sys/posix/$(am__dirstamp) core/sys/posix/net/$(am__dirstamp): @$(MKDIR_P) core/sys/posix/net @@ -1324,8 +1282,14 @@ core/sys/posix/semaphore.lo: core/sys/posix/$(am__dirstamp) core/sys/posix/setjmp.lo: core/sys/posix/$(am__dirstamp) core/sys/posix/signal.lo: core/sys/posix/$(am__dirstamp) core/sys/posix/spawn.lo: core/sys/posix/$(am__dirstamp) +core/sys/posix/stdc/$(am__dirstamp): + @$(MKDIR_P) core/sys/posix/stdc + @: > core/sys/posix/stdc/$(am__dirstamp) +core/sys/posix/stdc/time.lo: core/sys/posix/stdc/$(am__dirstamp) core/sys/posix/stdio.lo: core/sys/posix/$(am__dirstamp) core/sys/posix/stdlib.lo: core/sys/posix/$(am__dirstamp) +core/sys/posix/string.lo: core/sys/posix/$(am__dirstamp) +core/sys/posix/strings.lo: core/sys/posix/$(am__dirstamp) core/sys/posix/sys/$(am__dirstamp): @$(MKDIR_P) core/sys/posix/sys @: > core/sys/posix/sys/$(am__dirstamp) @@ -1359,7 +1323,9 @@ core/sys/darwin/$(am__dirstamp): @: > 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) core/sys/darwin/execinfo.lo: core/sys/darwin/$(am__dirstamp) +core/sys/darwin/ifaddrs.lo: core/sys/darwin/$(am__dirstamp) core/sys/darwin/mach/$(am__dirstamp): @$(MKDIR_P) core/sys/darwin/mach @: > core/sys/darwin/mach/$(am__dirstamp) @@ -1368,9 +1334,11 @@ core/sys/darwin/mach/getsect.lo: core/sys/darwin/mach/$(am__dirstamp) core/sys/darwin/mach/kern_return.lo: \ core/sys/darwin/mach/$(am__dirstamp) core/sys/darwin/mach/loader.lo: core/sys/darwin/mach/$(am__dirstamp) +core/sys/darwin/mach/nlist.lo: core/sys/darwin/mach/$(am__dirstamp) core/sys/darwin/mach/port.lo: core/sys/darwin/mach/$(am__dirstamp) core/sys/darwin/mach/semaphore.lo: \ core/sys/darwin/mach/$(am__dirstamp) +core/sys/darwin/mach/stab.lo: core/sys/darwin/mach/$(am__dirstamp) core/sys/darwin/mach/thread_act.lo: \ core/sys/darwin/mach/$(am__dirstamp) core/sys/darwin/netinet/$(am__dirstamp): @@ -1383,6 +1351,7 @@ core/sys/darwin/string.lo: core/sys/darwin/$(am__dirstamp) core/sys/darwin/sys/$(am__dirstamp): @$(MKDIR_P) core/sys/darwin/sys @: > core/sys/darwin/sys/$(am__dirstamp) +core/sys/darwin/sys/attr.lo: core/sys/darwin/sys/$(am__dirstamp) core/sys/darwin/sys/cdefs.lo: core/sys/darwin/sys/$(am__dirstamp) core/sys/darwin/sys/event.lo: core/sys/darwin/sys/$(am__dirstamp) core/sys/darwin/sys/mman.lo: core/sys/darwin/sys/$(am__dirstamp) @@ -1390,6 +1359,7 @@ core/sys/dragonflybsd/$(am__dirstamp): @$(MKDIR_P) core/sys/dragonflybsd @: > core/sys/dragonflybsd/$(am__dirstamp) core/sys/dragonflybsd/dlfcn.lo: core/sys/dragonflybsd/$(am__dirstamp) +core/sys/dragonflybsd/err.lo: core/sys/dragonflybsd/$(am__dirstamp) core/sys/dragonflybsd/execinfo.lo: \ core/sys/dragonflybsd/$(am__dirstamp) core/sys/dragonflybsd/netinet/$(am__dirstamp): @@ -1430,6 +1400,7 @@ core/sys/dragonflybsd/time.lo: core/sys/dragonflybsd/$(am__dirstamp) core/sys/bionic/$(am__dirstamp): @$(MKDIR_P) core/sys/bionic @: > core/sys/bionic/$(am__dirstamp) +core/sys/bionic/err.lo: core/sys/bionic/$(am__dirstamp) core/sys/bionic/fcntl.lo: core/sys/bionic/$(am__dirstamp) core/sys/bionic/string.lo: core/sys/bionic/$(am__dirstamp) core/sys/bionic/unistd.lo: core/sys/bionic/$(am__dirstamp) @@ -1438,6 +1409,7 @@ core/sys/freebsd/$(am__dirstamp): @: > core/sys/freebsd/$(am__dirstamp) core/sys/freebsd/config.lo: core/sys/freebsd/$(am__dirstamp) core/sys/freebsd/dlfcn.lo: core/sys/freebsd/$(am__dirstamp) +core/sys/freebsd/err.lo: core/sys/freebsd/$(am__dirstamp) core/sys/freebsd/execinfo.lo: core/sys/freebsd/$(am__dirstamp) core/sys/freebsd/netinet/$(am__dirstamp): @$(MKDIR_P) core/sys/freebsd/netinet @@ -1468,6 +1440,7 @@ core/sys/netbsd/$(am__dirstamp): @$(MKDIR_P) core/sys/netbsd @: > core/sys/netbsd/$(am__dirstamp) core/sys/netbsd/dlfcn.lo: core/sys/netbsd/$(am__dirstamp) +core/sys/netbsd/err.lo: core/sys/netbsd/$(am__dirstamp) core/sys/netbsd/execinfo.lo: core/sys/netbsd/$(am__dirstamp) core/sys/netbsd/string.lo: core/sys/netbsd/$(am__dirstamp) core/sys/netbsd/sys/$(am__dirstamp): @@ -1488,6 +1461,7 @@ core/sys/openbsd/$(am__dirstamp): @$(MKDIR_P) core/sys/openbsd @: > core/sys/openbsd/$(am__dirstamp) core/sys/openbsd/dlfcn.lo: core/sys/openbsd/$(am__dirstamp) +core/sys/openbsd/err.lo: core/sys/openbsd/$(am__dirstamp) core/sys/openbsd/string.lo: core/sys/openbsd/$(am__dirstamp) core/sys/openbsd/sys/$(am__dirstamp): @$(MKDIR_P) core/sys/openbsd/sys @@ -1509,6 +1483,7 @@ core/sys/linux/config.lo: core/sys/linux/$(am__dirstamp) core/sys/linux/dlfcn.lo: core/sys/linux/$(am__dirstamp) core/sys/linux/elf.lo: core/sys/linux/$(am__dirstamp) core/sys/linux/epoll.lo: core/sys/linux/$(am__dirstamp) +core/sys/linux/err.lo: core/sys/linux/$(am__dirstamp) core/sys/linux/errno.lo: core/sys/linux/$(am__dirstamp) core/sys/linux/execinfo.lo: core/sys/linux/$(am__dirstamp) core/sys/linux/fcntl.lo: core/sys/linux/$(am__dirstamp) @@ -1660,6 +1635,7 @@ core/sys/windows/rpcnsi.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/rpcnsip.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/rpcnterr.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/schannel.lo: core/sys/windows/$(am__dirstamp) +core/sys/windows/sdkddkver.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/secext.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/security.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/servprov.lo: core/sys/windows/$(am__dirstamp) @@ -1677,6 +1653,10 @@ core/sys/windows/sqlucode.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/sspi.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/stacktrace.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/stat.lo: core/sys/windows/$(am__dirstamp) +core/sys/windows/stdc/$(am__dirstamp): + @$(MKDIR_P) core/sys/windows/stdc + @: > core/sys/windows/stdc/$(am__dirstamp) +core/sys/windows/stdc/time.lo: core/sys/windows/stdc/$(am__dirstamp) core/sys/windows/subauth.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/threadaux.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/tlhelp32.lo: core/sys/windows/$(am__dirstamp) @@ -1714,6 +1694,7 @@ core/sys/solaris/$(am__dirstamp): @: > core/sys/solaris/$(am__dirstamp) core/sys/solaris/dlfcn.lo: core/sys/solaris/$(am__dirstamp) core/sys/solaris/elf.lo: core/sys/solaris/$(am__dirstamp) +core/sys/solaris/err.lo: core/sys/solaris/$(am__dirstamp) core/sys/solaris/execinfo.lo: core/sys/solaris/$(am__dirstamp) core/sys/solaris/libelf.lo: core/sys/solaris/$(am__dirstamp) core/sys/solaris/link.lo: core/sys/solaris/$(am__dirstamp) @@ -1873,6 +1854,8 @@ mostlyclean-compile: -rm -f core/sys/posix/net/*.lo -rm -f core/sys/posix/netinet/*.$(OBJEXT) -rm -f core/sys/posix/netinet/*.lo + -rm -f core/sys/posix/stdc/*.$(OBJEXT) + -rm -f core/sys/posix/stdc/*.lo -rm -f core/sys/posix/sys/*.$(OBJEXT) -rm -f core/sys/posix/sys/*.lo -rm -f core/sys/solaris/*.$(OBJEXT) @@ -1881,6 +1864,10 @@ mostlyclean-compile: -rm -f core/sys/solaris/sys/*.lo -rm -f core/sys/windows/*.$(OBJEXT) -rm -f core/sys/windows/*.lo + -rm -f core/sys/windows/stdc/*.$(OBJEXT) + -rm -f core/sys/windows/stdc/*.lo + -rm -f core/thread/*.$(OBJEXT) + -rm -f core/thread/*.lo -rm -f gc/*.$(OBJEXT) -rm -f gc/*.lo -rm -f gc/impl/conservative/*.$(OBJEXT) @@ -1895,8 +1882,6 @@ mostlyclean-compile: -rm -f gcc/unwind/*.lo -rm -f rt/*.$(OBJEXT) -rm -f rt/*.lo - -rm -f rt/typeinfo/*.$(OBJEXT) - -rm -f rt/typeinfo/*.lo -rm -f rt/util/*.$(OBJEXT) -rm -f rt/util/*.lo -rm -f rt/util/container/*.$(OBJEXT) @@ -2016,10 +2001,13 @@ clean-libtool: -rm -rf core/sys/posix/arpa/.libs core/sys/posix/arpa/_libs -rm -rf core/sys/posix/net/.libs core/sys/posix/net/_libs -rm -rf core/sys/posix/netinet/.libs core/sys/posix/netinet/_libs + -rm -rf core/sys/posix/stdc/.libs core/sys/posix/stdc/_libs -rm -rf core/sys/posix/sys/.libs core/sys/posix/sys/_libs -rm -rf core/sys/solaris/.libs core/sys/solaris/_libs -rm -rf core/sys/solaris/sys/.libs core/sys/solaris/sys/_libs -rm -rf core/sys/windows/.libs core/sys/windows/_libs + -rm -rf core/sys/windows/stdc/.libs core/sys/windows/stdc/_libs + -rm -rf core/thread/.libs core/thread/_libs -rm -rf gc/.libs gc/_libs -rm -rf gc/impl/conservative/.libs gc/impl/conservative/_libs -rm -rf gc/impl/manual/.libs gc/impl/manual/_libs @@ -2027,7 +2015,6 @@ clean-libtool: -rm -rf gcc/sections/.libs gcc/sections/_libs -rm -rf gcc/unwind/.libs gcc/unwind/_libs -rm -rf rt/.libs rt/_libs - -rm -rf rt/typeinfo/.libs rt/typeinfo/_libs -rm -rf rt/util/.libs rt/util/_libs -rm -rf rt/util/container/.libs rt/util/container/_libs install-toolexeclibDATA: $(toolexeclib_DATA) @@ -2170,10 +2157,13 @@ distclean-generic: -rm -f core/sys/posix/arpa/$(am__dirstamp) -rm -f core/sys/posix/net/$(am__dirstamp) -rm -f core/sys/posix/netinet/$(am__dirstamp) + -rm -f core/sys/posix/stdc/$(am__dirstamp) -rm -f core/sys/posix/sys/$(am__dirstamp) -rm -f core/sys/solaris/$(am__dirstamp) -rm -f core/sys/solaris/sys/$(am__dirstamp) -rm -f core/sys/windows/$(am__dirstamp) + -rm -f core/sys/windows/stdc/$(am__dirstamp) + -rm -f core/thread/$(am__dirstamp) -rm -f gc/$(am__dirstamp) -rm -f gc/impl/conservative/$(am__dirstamp) -rm -f gc/impl/manual/$(am__dirstamp) @@ -2181,7 +2171,6 @@ distclean-generic: -rm -f gcc/sections/$(am__dirstamp) -rm -f gcc/unwind/$(am__dirstamp) -rm -f rt/$(am__dirstamp) - -rm -f rt/typeinfo/$(am__dirstamp) -rm -f rt/util/$(am__dirstamp) -rm -f rt/util/container/$(am__dirstamp) diff --git a/libphobos/libdruntime/core/internal/abort.d b/libphobos/libdruntime/core/internal/abort.d index dfa3496c92c..8ee1684d146 100644 --- a/libphobos/libdruntime/core/internal/abort.d +++ b/libphobos/libdruntime/core/internal/abort.d @@ -4,7 +4,7 @@ module core.internal.abort; * Use instead of assert(0, msg), since this does not print a message for -release compiled * code, and druntime is -release compiled. */ -void abort(string msg, string filename = __FILE__, size_t line = __LINE__) @nogc nothrow @safe +void abort(scope string msg, scope string filename = __FILE__, size_t line = __LINE__) @nogc nothrow @safe { import core.stdc.stdlib: c_abort = abort; // use available OS system calls to print the message to stderr diff --git a/libphobos/libdruntime/core/stdc/complex.d b/libphobos/libdruntime/core/stdc/complex.d index dae35f2725c..d878366b3bd 100644 --- a/libphobos/libdruntime/core/stdc/complex.d +++ b/libphobos/libdruntime/core/stdc/complex.d @@ -149,14 +149,14 @@ creal csqrtl(creal z); /// real cargl(creal z); - /// - double cimag(cdouble z); - /// - float cimagf(cfloat z); - /// - real cimagl(creal z); +/// +pragma(inline, true) double cimag(cdouble z) { return z.im; } +/// +pragma(inline, true) float cimagf(cfloat z) { return z.im; } +/// +pragma(inline, true) real cimagl(creal z) { return z.im; } - /// +/// cdouble conj(cdouble z); /// cfloat conjf(cfloat z); @@ -170,8 +170,12 @@ cfloat cprojf(cfloat z); /// creal cprojl(creal z); -// double creal(cdouble z); +// Note: `creal` is a keyword in D and so this function is inaccessible, use `creald` instead +//pragma(inline, true) double creal(cdouble z) { return z.re; } + /// - float crealf(cfloat z); - /// - real creall(creal z); +pragma(inline, true) double creald(cdouble z) { return z.re; } +/// +pragma(inline, true) float crealf(cfloat z) { return z.re; } +/// +pragma(inline, true) real creall(creal z) { return z.re; } diff --git a/libphobos/libdruntime/core/stdc/errno.d b/libphobos/libdruntime/core/stdc/errno.d index 767ed242472..31f7d11c762 100644 --- a/libphobos/libdruntime/core/stdc/errno.d +++ b/libphobos/libdruntime/core/stdc/errno.d @@ -1639,128 +1639,128 @@ else version (DragonFlyBSD) } else version (Solaris) { - enum EPERM = 1 /** Not super-user */; - enum ENOENT = 2 /** No such file or directory */; - enum ESRCH = 3 /** No such process */; - enum EINTR = 4 /** interrupted system call */; - enum EIO = 5 /** I/O error */; - enum ENXIO = 6 /** No such device or address */; - enum E2BIG = 7 /** Arg list too long */; - enum ENOEXEC = 8 /** Exec format error */; - enum EBADF = 9 /** Bad file number */; - enum ECHILD = 10 /** No children */; - enum EAGAIN = 11 /** Resource temporarily unavailable */; - enum ENOMEM = 12 /** Not enough core */; - enum EACCES = 13 /** Permission denied */; - enum EFAULT = 14 /** Bad address */; - enum ENOTBLK = 15 /** Block device required */; - enum EBUSY = 16 /** Mount device busy */; - enum EEXIST = 17 /** File exists */; - enum EXDEV = 18 /** Cross-device link */; - enum ENODEV = 19 /** No such device */; - enum ENOTDIR = 20 /** Not a directory */; - enum EISDIR = 21 /** Is a directory */; - enum EINVAL = 22 /** Invalid argument */; - enum ENFILE = 23 /** File table overflow */; - enum EMFILE = 24 /** Too many open files */; - enum ENOTTY = 25 /** Inappropriate ioctl for device */; - enum ETXTBSY = 26 /** Text file busy */; - enum EFBIG = 27 /** File too large */; - enum ENOSPC = 28 /** No space left on device */; - enum ESPIPE = 29 /** Illegal seek */; - enum EROFS = 30 /** Read only file system */; - enum EMLINK = 31 /** Too many links */; - enum EPIPE = 32 /** Broken pipe */; - enum EDOM = 33 /** Math arg out of domain of func */; - enum ERANGE = 34 /** Math result not representable */; - enum ENOMSG = 35 /** No message of desired type */; - enum EIDRM = 36 /** Identifier removed */; - enum ECHRNG = 37 /** Channel number out of range */; - enum EL2NSYNC = 38 /** Level 2 not synchronized */; - enum EL3HLT = 39 /** Level 3 halted */; - enum EL3RST = 40 /** Level 3 reset */; - enum ELNRNG = 41 /** Link number out of range */; - enum EUNATCH = 42 /** Protocol driver not attached */; - enum ENOCSI = 43 /** No CSI structure available */; - enum EL2HLT = 44 /** Level 2 halted */; - enum EDEADLK = 45 /** Deadlock condition. */; - enum ENOLCK = 46 /** No record locks available. */; - enum ECANCELED = 47 /** Operation canceled */; - enum ENOTSUP = 48 /** Operation not supported */; - enum EDQUOT = 49 /** Disc quota exceeded */; - enum EBADE = 50 /** invalid exchange */; - enum EBADR = 51 /** invalid request descriptor */; - enum EXFULL = 52 /** exchange full */; - enum ENOANO = 53 /** no anode */; - enum EBADRQC = 54 /** invalid request code */; - enum EBADSLT = 55 /** invalid slot */; - enum EDEADLOCK = 56 /** file locking deadlock error */; - enum EBFONT = 57 /** bad font file fmt */; - enum EOWNERDEAD = 58 /** process died with the lock */; - enum ENOTRECOVERABLE = 59 /** lock is not recoverable */; - enum ENOSTR = 60 /** Device not a stream */; - enum ENODATA = 61 /** no data (for no delay io) */; - enum ETIME = 62 /** timer expired */; - enum ENOSR = 63 /** out of streams resources */; - enum ENONET = 64 /** Machine is not on the network */; - enum ENOPKG = 65 /** Package not installed */; - enum EREMOTE = 66 /** The object is remote */; - enum ENOLINK = 67 /** the link has been severed */; - enum EADV = 68 /** advertise error */; - enum ESRMNT = 69 /** srmount error */; - enum ECOMM = 70 /** Communication error on send */; - enum EPROTO = 71 /** Protocol error */; - enum ELOCKUNMAPPED = 72 /** locked lock was unmapped */; - enum ENOTACTIVE = 73 /** Facility is not active */; - enum EMULTIHOP = 74 /** multihop attempted */; - enum EBADMSG = 77 /** trying to read unreadable message */; - enum ENAMETOOLONG = 78 /** path name is too long */; - enum EOVERFLOW = 79 /** value too large to be stored in data type */; - enum ENOTUNIQ = 80 /** given log. name not unique */; - enum EBADFD = 81 /** f.d. invalid for this operation */; - enum EREMCHG = 82 /** Remote address changed */; - enum ELIBACC = 83 /** Can't access a needed shared lib. */; - enum ELIBBAD = 84 /** Accessing a corrupted shared lib. */; - enum ELIBSCN = 85 /** .lib section in a.out corrupted. */; - enum ELIBMAX = 86 /** Attempting to link in too many libs. */; - enum ELIBEXEC = 87 /** Attempting to exec a shared library. */; - enum EILSEQ = 88 /** Illegal byte sequence. */; - enum ENOSYS = 89 /** Unsupported file system operation */; - enum ELOOP = 90 /** Symbolic link loop */; - enum ERESTART = 91 /** Restartable system call */; - enum ESTRPIPE = 92 /** if pipe/FIFO, don't sleep in stream head */; - enum ENOTEMPTY = 93 /** directory not empty */; - enum EUSERS = 94 /** Too many users (for UFS) */; - enum ENOTSOCK = 95 /** Socket operation on non-socket */; - enum EDESTADDRREQ = 96 /** Destination address required */; - enum EMSGSIZE = 97 /** Message too long */; - enum EPROTOTYPE = 98 /** Protocol wrong type for socket */; - enum ENOPROTOOPT = 99 /** Protocol not available */; - enum EPROTONOSUPPORT = 120 /** Protocol not supported */; - enum ESOCKTNOSUPPORT = 121 /** Socket type not supported */; - enum EOPNOTSUPP = 122 /** Operation not supported on socket */; - enum EPFNOSUPPORT = 123 /** Protocol family not supported */; - enum EAFNOSUPPORT = 124 /** Address family not supported by the protocol family */; - enum EADDRINUSE = 125 /** Address already in use */; - enum EADDRNOTAVAIL = 126 /** Can't assign requested address */; - enum ENETDOWN = 127 /** Network is down */; - enum ENETUNREACH = 128 /** Network is unreachable */; - enum ENETRESET = 129 /** Network dropped connection because of reset */; - enum ECONNABORTED = 130 /** Software caused connection abort */; - enum ECONNRESET = 131 /** Connection reset by peer */; - enum ENOBUFS = 132 /** No buffer space available */; - enum EISCONN = 133 /** Socket is already connected */; - enum ENOTCONN = 134 /** Socket is not connected */; - enum ESHUTDOWN = 143 /** Can't send after socket shutdown */; - enum ETOOMANYREFS = 144 /** Too many references: can't splice */; - enum ETIMEDOUT = 145 /** Connection timed out */; - enum ECONNREFUSED = 146 /** Connection refused */; - enum EHOSTDOWN = 147 /** Host is down */; - enum EHOSTUNREACH = 148 /** No route to host */; - enum EWOULDBLOCK = EAGAIN; /** Resource temporarily unavailable */; - enum EALREADY = 149 /** operation already in progress */; - enum EINPROGRESS = 150 /** operation now in progress */; - enum ESTALE = 151 /** Stale NFS file handle */; + enum EPERM = 1; /// Not super-user + enum ENOENT = 2; /// No such file or directory + enum ESRCH = 3; /// No such process + enum EINTR = 4; /// interrupted system call + enum EIO = 5; /// I/O error + enum ENXIO = 6; /// No such device or address + enum E2BIG = 7; /// Arg list too long + enum ENOEXEC = 8; /// Exec format error + enum EBADF = 9; /// Bad file number + enum ECHILD = 10; /// No children + enum EAGAIN = 11; /// Resource temporarily unavailable + enum ENOMEM = 12; /// Not enough core + enum EACCES = 13; /// Permission denied + enum EFAULT = 14; /// Bad address + enum ENOTBLK = 15; /// Block device required + enum EBUSY = 16; /// Mount device busy + enum EEXIST = 17; /// File exists + enum EXDEV = 18; /// Cross-device link + enum ENODEV = 19; /// No such device + enum ENOTDIR = 20; /// Not a directory + enum EISDIR = 21; /// Is a directory + enum EINVAL = 22; /// Invalid argument + enum ENFILE = 23; /// File table overflow + enum EMFILE = 24; /// Too many open files + enum ENOTTY = 25; /// Inappropriate ioctl for device + enum ETXTBSY = 26; /// Text file busy + enum EFBIG = 27; /// File too large + enum ENOSPC = 28; /// No space left on device + enum ESPIPE = 29; /// Illegal seek + enum EROFS = 30; /// Read only file system + enum EMLINK = 31; /// Too many links + enum EPIPE = 32; /// Broken pipe + enum EDOM = 33; /// Math arg out of domain of func + enum ERANGE = 34; /// Math result not representable + enum ENOMSG = 35; /// No message of desired type + enum EIDRM = 36; /// Identifier removed + enum ECHRNG = 37; /// Channel number out of range + enum EL2NSYNC = 38; /// Level 2 not synchronized + enum EL3HLT = 39; /// Level 3 halted + enum EL3RST = 40; /// Level 3 reset + enum ELNRNG = 41; /// Link number out of range + enum EUNATCH = 42; /// Protocol driver not attached + enum ENOCSI = 43; /// No CSI structure available + enum EL2HLT = 44; /// Level 2 halted + enum EDEADLK = 45; /// Deadlock condition. + enum ENOLCK = 46; /// No record locks available. + enum ECANCELED = 47; /// Operation canceled + enum ENOTSUP = 48; /// Operation not supported + enum EDQUOT = 49; /// Disc quota exceeded + enum EBADE = 50; /// invalid exchange + enum EBADR = 51; /// invalid request descriptor + enum EXFULL = 52; /// exchange full + enum ENOANO = 53; /// no anode + enum EBADRQC = 54; /// invalid request code + enum EBADSLT = 55; /// invalid slot + enum EDEADLOCK = 56; /// file locking deadlock error + enum EBFONT = 57; /// bad font file fmt + enum EOWNERDEAD = 58; /// process died with the lock + enum ENOTRECOVERABLE = 59; /// lock is not recoverable + enum ENOSTR = 60; /// Device not a stream + enum ENODATA = 61; /// no data (for no delay io) + enum ETIME = 62; /// timer expired + enum ENOSR = 63; /// out of streams resources + enum ENONET = 64; /// Machine is not on the network + enum ENOPKG = 65; /// Package not installed + enum EREMOTE = 66; /// The object is remote + enum ENOLINK = 67; /// the link has been severed + enum EADV = 68; /// advertise error + enum ESRMNT = 69; /// srmount error + enum ECOMM = 70; /// Communication error on send + enum EPROTO = 71; /// Protocol error + enum ELOCKUNMAPPED = 72; /// locked lock was unmapped + enum ENOTACTIVE = 73; /// Facility is not active + enum EMULTIHOP = 74; /// multihop attempted + enum EBADMSG = 77; /// trying to read unreadable message + enum ENAMETOOLONG = 78; /// path name is too long + enum EOVERFLOW = 79; /// value too large to be stored in data type + enum ENOTUNIQ = 80; /// given log. name not unique + enum EBADFD = 81; /// f.d. invalid for this operation + enum EREMCHG = 82; /// Remote address changed + enum ELIBACC = 83; /// Can't access a needed shared lib. + enum ELIBBAD = 84; /// Accessing a corrupted shared lib. + enum ELIBSCN = 85; /// .lib section in a.out corrupted. + enum ELIBMAX = 86; /// Attempting to link in too many libs. + enum ELIBEXEC = 87; /// Attempting to exec a shared library. + enum EILSEQ = 88; /// Illegal byte sequence. + enum ENOSYS = 89; /// Unsupported file system operation + enum ELOOP = 90; /// Symbolic link loop + enum ERESTART = 91; /// Restartable system call + enum ESTRPIPE = 92; /// if pipe/FIFO, don't sleep in stream head + enum ENOTEMPTY = 93; /// directory not empty + enum EUSERS = 94; /// Too many users (for UFS) + enum ENOTSOCK = 95; /// Socket operation on non-socket + enum EDESTADDRREQ = 96; /// Destination address required + enum EMSGSIZE = 97; /// Message too long + enum EPROTOTYPE = 98; /// Protocol wrong type for socket + enum ENOPROTOOPT = 99; /// Protocol not available + enum EPROTONOSUPPORT = 120; /// Protocol not supported + enum ESOCKTNOSUPPORT = 121; /// Socket type not supported + enum EOPNOTSUPP = 122; /// Operation not supported on socket + enum EPFNOSUPPORT = 123; /// Protocol family not supported + enum EAFNOSUPPORT = 124; /// Address family not supported by the protocol family + enum EADDRINUSE = 125; /// Address already in use + enum EADDRNOTAVAIL = 126; /// Can't assign requested address + enum ENETDOWN = 127; /// Network is down + enum ENETUNREACH = 128; /// Network is unreachable + enum ENETRESET = 129; /// Network dropped connection because of reset + enum ECONNABORTED = 130; /// Software caused connection abort + enum ECONNRESET = 131; /// Connection reset by peer + enum ENOBUFS = 132; /// No buffer space available + enum EISCONN = 133; /// Socket is already connected + enum ENOTCONN = 134; /// Socket is not connected + enum ESHUTDOWN = 143; /// Can't send after socket shutdown + enum ETOOMANYREFS = 144; /// Too many references: can't splice + enum ETIMEDOUT = 145; /// Connection timed out + enum ECONNREFUSED = 146; /// Connection refused + enum EHOSTDOWN = 147; /// Host is down + enum EHOSTUNREACH = 148; /// No route to host + enum EWOULDBLOCK = EAGAIN; /// Resource temporarily unavailable + enum EALREADY = 149; /// operation already in progress + enum EINPROGRESS = 150; /// operation now in progress + enum ESTALE = 151; /// Stale NFS file handle } else version (Haiku) { diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d index e5d2519a00d..3002c022613 100644 --- a/libphobos/libdruntime/core/stdc/fenv.d +++ b/libphobos/libdruntime/core/stdc/fenv.d @@ -149,10 +149,10 @@ version (GNUFP) alias fexcept_t = uint; } // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/fpu/bits/fenv.h - else version (SPARC64) + else version (SPARC_Any) { - alias fenv_t = ulong; - alias fexcept_t = ulong; + alias fenv_t = c_ulong; + alias fexcept_t = c_ulong; } // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/s390/fpu/bits/fenv.h else version (IBMZ_Any) @@ -237,7 +237,7 @@ else version (NetBSD) uint status; /* Status word register */ uint tag; /* Tag word register */ uint[4] others; /* EIP, Pointer Selector, etc */ - }; + } _x87 x87; uint mxcsr; /* Control and status register */ @@ -256,10 +256,10 @@ else version (NetBSD) ushort tag; /* Tag word register */ ushort unused3; uint[4] others; /* EIP, Pointer Selector, etc */ - }; + } _x87 x87; uint mxcsr; /* Control and status register */ - }; + } } @@ -291,7 +291,7 @@ else version (DragonFlyBSD) uint status; uint tag; uint[4] others; - }; + } _x87 x87; uint mxcsr; @@ -877,7 +877,7 @@ int feholdexcept(fenv_t* envp); /// int fegetexceptflag(fexcept_t* flagp, int excepts); /// -int fesetexceptflag(in fexcept_t* flagp, int excepts); +int fesetexceptflag(const scope fexcept_t* flagp, int excepts); /// int fegetround(); @@ -887,7 +887,7 @@ int fesetround(int round); /// int fegetenv(fenv_t* envp); /// -int fesetenv(in fenv_t* envp); +int fesetenv(const scope fenv_t* envp); // MS define feraiseexcept() and feupdateenv() inline. version (CRuntime_Microsoft) // supported since MSVCRT 12 (VS 2013) only @@ -925,7 +925,7 @@ version (CRuntime_Microsoft) // supported since MSVCRT 12 (VS 2013) only } /// - int feupdateenv()(in fenv_t* envp) + int feupdateenv()(const scope fenv_t* envp) { int excepts = fetestexcept(FE_ALL_EXCEPT); return (fesetenv(envp) != 0 || feraiseexcept(excepts) != 0 ? 1 : 0); @@ -936,5 +936,5 @@ else /// int feraiseexcept(int excepts); /// - int feupdateenv(in fenv_t* envp); + int feupdateenv(const scope fenv_t* envp); } diff --git a/libphobos/libdruntime/core/stdc/inttypes.d b/libphobos/libdruntime/core/stdc/inttypes.d index d74ee7998ab..7f30e38ab92 100644 --- a/libphobos/libdruntime/core/stdc/inttypes.d +++ b/libphobos/libdruntime/core/stdc/inttypes.d @@ -434,10 +434,10 @@ intmax_t imaxabs(intmax_t j); /// imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); /// -intmax_t strtoimax(in char* nptr, char** endptr, int base); +intmax_t strtoimax(const scope char* nptr, char** endptr, int base); /// -uintmax_t strtoumax(in char* nptr, char** endptr, int base); +uintmax_t strtoumax(const scope char* nptr, char** endptr, int base); /// -intmax_t wcstoimax(in wchar_t* nptr, wchar_t** endptr, int base); +intmax_t wcstoimax(const scope wchar_t* nptr, wchar_t** endptr, int base); /// -uintmax_t wcstoumax(in wchar_t* nptr, wchar_t** endptr, int base); +uintmax_t wcstoumax(const scope wchar_t* nptr, wchar_t** endptr, int base); diff --git a/libphobos/libdruntime/core/stdc/limits.d b/libphobos/libdruntime/core/stdc/limits.d index 3ab7ed1e4f7..f3f88006a12 100644 --- a/libphobos/libdruntime/core/stdc/limits.d +++ b/libphobos/libdruntime/core/stdc/limits.d @@ -23,7 +23,7 @@ else version (TVOS) else version (WatchOS) version = Darwin; -private import core.stdc.config; +import core.stdc.config; extern (C): @trusted: // Constants only. diff --git a/libphobos/libdruntime/core/stdc/locale.d b/libphobos/libdruntime/core/stdc/locale.d index 3ba348adbf0..4b8d5c82e02 100644 --- a/libphobos/libdruntime/core/stdc/locale.d +++ b/libphobos/libdruntime/core/stdc/locale.d @@ -287,6 +287,6 @@ else } /// -@system char* setlocale(int category, in char* locale); +@system char* setlocale(int category, const scope char* locale); /// lconv* localeconv(); diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d index 492978939d8..e8d1fa8e7b5 100644 --- a/libphobos/libdruntime/core/stdc/math.d +++ b/libphobos/libdruntime/core/stdc/math.d @@ -13,7 +13,7 @@ module core.stdc.math; -private import core.stdc.config; +import core.stdc.config; version (OSX) version = Darwin; @@ -1037,14 +1037,25 @@ else version (Darwin) // other Darwins version (OSX) { - pure int __fpclassify(real x); - pure int __isfinite(real x); - pure int __isinf(real x); - pure int __isnan(real x); - alias __fpclassifyl = __fpclassify; - alias __isfinitel = __isfinite; - alias __isinfl = __isinf; - alias __isnanl = __isnan; + version (AArch64) + { + // Available in macOS ARM + 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); + pure int __isinf(real x); + pure int __isnan(real x); + alias __fpclassifyl = __fpclassify; + alias __isfinitel = __isfinite; + alias __isinfl = __isinf; + alias __isnanl = __isnan; + } } else { @@ -2028,464 +2039,406 @@ version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) only /// extern(D) pure real fmal()(real x, real y, real z) { return fma(cast(double) x, cast(double) y, cast(double) z); } } -/* NOTE: freebsd < 8-CURRENT doesn't appear to support *l, but we can - * approximate. - * A lot of them were added in 8.0-RELEASE, and so a lot of these workarounds - * should then be removed. - */ -// NOTE: FreeBSD 8.0-RELEASE doesn't support log2* nor these *l functions: -// acoshl, asinhl, atanhl, coshl, sinhl, tanhl, cbrtl, powl, expl, -// expm1l, logl, log1pl, log10l, erfcl, erfl, lgammal, tgammal; -// but we can approximate. else version (FreeBSD) { - version (none) // < 8-CURRENT - { - extern (D) - { - real acosl(real x) { return acos(x); } - real asinl(real x) { return asin(x); } - pure real atanl(real x) { return atan(x); } - real atan2l(real y, real x) { return atan2(y, x); } - pure real cosl(real x) { return cos(x); } - pure real sinl(real x) { return sin(x); } - pure real tanl(real x) { return tan(x); } - real exp2l(real x) { return exp2(x); } - pure real frexpl(real value, int* exp) { return frexp(value, exp); } - int ilogbl(real x) { return ilogb(x); } - real ldexpl(real x, int exp) { return ldexp(x, exp); } - real logbl(real x) { return logb(x); } - //real modfl(real value, real *iptr); // nontrivial conversion - real scalbnl(real x, int n) { return scalbn(x, n); } - real scalblnl(real x, c_long n) { return scalbln(x, n); } - pure real fabsl(real x) { return fabs(x); } - real hypotl(real x, real y) { return hypot(x, y); } - real sqrtl(real x) { return sqrt(x); } - pure real ceill(real x) { return ceil(x); } - pure real floorl(real x) { return floor(x); } - pure real nearbyintl(real x) { return nearbyint(x); } - pure real rintl(real x) { return rint(x); } - c_long lrintl(real x) { return lrint(x); } - pure real roundl(real x) { return round(x); } - c_long lroundl(real x) { return lround(x); } - long llroundl(real x) { return llround(x); } - pure real truncl(real x) { return trunc(x); } - real fmodl(real x, real y) { return fmod(x, y); } - real remainderl(real x, real y) { return remainder(x, y); } - real remquol(real x, real y, int* quo) { return remquo(x, y, quo); } - pure real copysignl(real x, real y) { return copysign(x, y); } - //pure double nan(char* tagp); - //pure float nanf(char* tagp); - //pure real nanl(char* tagp); - real nextafterl(real x, real y) { return nextafter(x, y); } - real nexttowardl(real x, real y) { return nexttoward(x, y); } - real fdiml(real x, real y) { return fdim(x, y); } - pure real fmaxl(real x, real y) { return fmax(x, y); } - pure real fminl(real x, real y) { return fmin(x, y); } - pure real fmal(real x, real y, real z) { return fma(x, y, z); } - } - } - else - { - /// - real acosl(real x); - /// - real asinl(real x); - /// - pure real atanl(real x); - /// - real atan2l(real y, real x); - /// - pure real cosl(real x); - /// - pure real sinl(real x); - /// - pure real tanl(real x); - /// - real exp2l(real x); - /// - pure real frexpl(real value, int* exp); - /// - int ilogbl(real x); - /// - real ldexpl(real x, int exp); - /// - real logbl(real x); - /// - pure real modfl(real value, real *iptr); - /// - real scalbnl(real x, int n); - /// - real scalblnl(real x, c_long n); - /// - pure real fabsl(real x); - /// - real hypotl(real x, real y); - /// - real sqrtl(real x); - /// - pure real ceill(real x); - /// - pure real floorl(real x); - /// - pure real nearbyintl(real x); - /// - pure real rintl(real x); - /// - c_long lrintl(real x); - /// - pure real roundl(real x); - /// - c_long lroundl(real x); - /// - long llroundl(real x); - /// - pure real truncl(real x); - /// - real fmodl(real x, real y); /// - real remainderl(real x, real y); - /// - real remquol(real x, real y, int* quo); - /// - pure real copysignl(real x, real y); - /// - pure double nan(char* tagp); - /// - pure float nanf(char* tagp); - /// - pure real nanl(char* tagp); - /// - real nextafterl(real x, real y); - /// - real nexttowardl(real x, real y); - /// - real fdiml(real x, real y); - /// - pure real fmaxl(real x, real y); - /// - pure real fminl(real x, real y); - /// - pure real fmal(real x, real y, real z); - } - /// double acos(double x); /// float acosf(float x); + /// + real acosl(real x); // since 8.0 /// double asin(double x); /// float asinf(float x); + /// + real asinl(real x); // since 8.0 /// pure double atan(double x); /// pure float atanf(float x); + /// + pure real atanl(real x); // since 8.0 /// double atan2(double y, double x); /// float atan2f(float y, float x); + /// + real atan2l(real y, real x); // since 8.0 /// pure double cos(double x); /// pure float cosf(float x); + /// + pure real cosl(real x); // since 8.0 /// pure double sin(double x); /// pure float sinf(float x); + /// + pure real sinl(real x); // since 8.0 /// pure double tan(double x); /// pure float tanf(float x); + /// + pure real tanl(real x); // since 8.0 /// double acosh(double x); /// float acoshf(float x); /// - extern(D) real acoshl(real x) { return acosh(x); } + real acoshl(real x); // since 10.0 /// pure double asinh(double x); /// pure float asinhf(float x); /// - extern(D) pure real asinhl(real x) { return asinh(x); } + pure real asinhl(real x); // since 10.0 /// double atanh(double x); /// float atanhf(float x); /// - extern(D) real atanhl(real x) { return atanh(x); } + real atanhl(real x); // since 10.0 /// double cosh(double x); /// float coshf(float x); /// - extern(D) real coshl(real x) { return cosh(x); } + real coshl(real x); // since 10.1 /// double sinh(double x); /// float sinhf(float x); /// - extern(D) real sinhl(real x) { return sinh(x); } + real sinhl(real x); // since 10.1 /// pure double tanh(double x); /// pure float tanhf(float x); /// - extern(D) pure real tanhl(real x) { return tanh(x); } + pure real tanhl(real x); // since 10.1 /// double exp(double x); /// float expf(float x); /// - extern(D) real expl(real x) { return exp(x); } + real expl(real x); // since 10.0 /// double exp2(double x); /// float exp2f(float x); + /// + real exp2l(real x); // since 8.0 /// double expm1(double x); /// float expm1f(float x); /// - extern(D) real expm1l(real x) { return expm1(x); } + real expm1l(real x); // since 10.0 /// pure double frexp(double value, int* exp); /// pure float frexpf(float value, int* exp); + /// + pure real frexpl(real value, int* exp); // since 6.0 /// int ilogb(double x); /// int ilogbf(float x); + /// + int ilogbl(real x); // since 5.4 /// double ldexp(double x, int exp); /// float ldexpf(float x, int exp); + /// + real ldexpl(real x, int exp); // since 6.0 /// double log(double x); /// float logf(float x); /// - extern(D) real logl(real x) { return log(x); } + real logl(real x); // since 10.0 /// double log10(double x); /// float log10f(float x); /// - extern(D) real log10l(real x) { return log10(x); } + real log10l(real x); // since 10.0 /// double log1p(double x); /// float log1pf(float x); /// - extern(D) real log1pl(real x) { return log1p(x); } + real log1pl(real x); // since 10.0 - private enum real ONE_LN2 = 1 / 0x1.62e42fefa39ef358p-1L; /// - extern(D) double log2(double x) { return log(x) * ONE_LN2; } + double log2(double x); // since 8.3 /// - extern(D) float log2f(float x) { return logf(x) * ONE_LN2; } + float log2f(float x); // since 8.3 /// - extern(D) real log2l(real x) { return logl(x) * ONE_LN2; } + real log2l(real x); // since 10.0 /// double logb(double x); /// float logbf(float x); + /// + real logbl(real x); // since 8.0 /// pure double modf(double value, double* iptr); /// pure float modff(float value, float* iptr); + /// + pure real modfl(real value, real *iptr); // since 8.0 /// double scalbn(double x, int n); /// float scalbnf(float x, int n); + /// + real scalbnl(real x, int n); // since 6.0 /// double scalbln(double x, c_long n); /// float scalblnf(float x, c_long n); + /// + real scalblnl(real x, c_long n); // since 6.0 /// pure double cbrt(double x); /// pure float cbrtf(float x); /// - extern(D) pure real cbrtl(real x) { return cbrt(x); } + pure real cbrtl(real x); // since 9.0 /// pure double fabs(double x); /// pure float fabsf(float x); + /// + pure real fabsl(real x); // since 5.3 /// double hypot(double x, double y); /// float hypotf(float x, float y); + /// + real hypotl(real x, real y); // since 8.0 /// double pow(double x, double y); /// float powf(float x, float y); /// - extern(D) real powl(real x, real y) { return pow(x, y); } + real powl(real x, real y); // since 10.4 /// double sqrt(double x); /// float sqrtf(float x); + /// + real sqrtl(real x); // since 8.0 /// pure double erf(double x); /// pure float erff(float x); /// - extern(D) pure real erfl(real x) { return erf(x); } + pure real erfl(real x); // since 10.1 /// double erfc(double x); /// float erfcf(float x); /// - extern(D) real erfcl(real x) { return erfc(x); } + real erfcl(real x); // since 10.1 /// double lgamma(double x); /// float lgammaf(float x); /// - extern(D) real lgammal(real x) { return lgamma(x); } + real lgammal(real x); // since 10.2 /// double tgamma(double x); /// float tgammaf(float x); /// - extern(D) real tgammal(real x) { return tgamma(x); } + real tgammal(real x); // since 11.2 /// pure double ceil(double x); /// pure float ceilf(float x); + /// + pure real ceill(real x); // since 5.4 /// pure double floor(double x); /// pure float floorf(float x); + /// + pure real floorl(real x); // since 5.4 /// pure double nearbyint(double x); /// pure float nearbyintf(float x); + /// + pure real nearbyintl(real x); // since 8.0 /// pure double rint(double x); /// pure float rintf(float x); + /// + pure real rintl(real x); // since 8.0 /// c_long lrint(double x); /// c_long lrintf(float x); + /// + c_long lrintl(real x); // since 8.0 /// long llrint(double x); /// long llrintf(float x); /// - extern(D) long llrintl(real x) { return llrint(x); } + long llrintl(real x); // since 8.0 /// pure double round(double x); /// pure float roundf(float x); + /// + pure real roundl(real x); // since 6.0 /// c_long lround(double x); /// c_long lroundf(float x); + /// + c_long lroundl(real x); // since 6.0 /// long llround(double x); /// long llroundf(float x); + /// + long llroundl(real x); // since 6.0 /// pure double trunc(double x); /// pure float truncf(float x); + /// + pure real truncl(real x); // since 6.0 /// double fmod(double x, double y); /// float fmodf(float x, float y); + /// + real fmodl(real x, real y); // since 8.0 /// double remainder(double x, double y); /// float remainderf(float x, float y); + /// + real remainderl(real x, real y); // since 8.0 /// double remquo(double x, double y, int* quo); /// float remquof(float x, float y, int* quo); + /// + real remquol(real x, real y, int* quo); // since 8.0 /// pure double copysign(double x, double y); /// pure float copysignf(float x, float y); + /// + pure real copysignl(real x, real y); // since 5.3 + + /// + pure double nan(const char*); // since 8.0 + /// + pure float nanf(const char*); // since 8.0 + /// + pure real nanl(const char*); // since 8.0 /// double nextafter(double x, double y); /// float nextafterf(float x, float y); + /// + real nextafterl(real x, real y); // since 6.0 /// double nexttoward(double x, real y); /// float nexttowardf(float x, real y); + /// + real nexttowardl(real x, real y); // since 6.0 /// double fdim(double x, double y); /// float fdimf(float x, float y); + /// + real fdiml(real x, real y); // since 5.3 /// pure double fmax(double x, double y); /// pure float fmaxf(float x, float y); + /// + pure real fmaxl(real x, real y); // since 5.3 /// pure double fmin(double x, double y); /// pure float fminf(float x, float y); + /// + pure real fminl(real x, real y); // since 5.3 /// pure double fma(double x, double y, double z); /// pure float fmaf(float x, float y, float z); + /// + pure real fmal(real x, real y, real z); // since 6.0 } else version (NetBSD) { diff --git a/libphobos/libdruntime/core/stdc/stdarg.d b/libphobos/libdruntime/core/stdc/stdarg.d index 586fe20d991..9a67f2e8e4d 100644 --- a/libphobos/libdruntime/core/stdc/stdarg.d +++ b/libphobos/libdruntime/core/stdc/stdarg.d @@ -3,525 +3,332 @@ * * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdarg.h.html, _stdarg.h) * - * Copyright: Copyright Digital Mars 2000 - 2009. + * Copyright: Copyright Digital Mars 2000 - 2020. * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). * Authors: Walter Bright, Hauke Duden * Standards: ISO/IEC 9899:1999 (E) * Source: $(DRUNTIMESRC core/stdc/_stdarg.d) */ -/* NOTE: This file has been patched from the original DMD distribution to - * work with the GDC compiler. - */ module core.stdc.stdarg; @system: -//@nogc: // Not yet, need to make TypeInfo's member functions @nogc first +@nogc: nothrow: +version (X86_64) +{ + version (Windows) { /* different ABI */ } + else version = SysV_x64; +} + version (GNU) { import gcc.builtins; - alias __builtin_va_list __gnuc_va_list; - - - /********************* - * The argument pointer type. - */ - alias __gnuc_va_list va_list; - - - /********** - * Initialize ap. - * parmn should be the last named parameter. - */ - void va_start(T)(out va_list ap, ref T parmn); - +} +else version (SysV_x64) +{ + static import core.internal.vararg.sysv_x64; - /************ - * Retrieve and return the next value that is type T. - */ - T va_arg(T)(ref va_list ap); + version (DigitalMars) + { + align(16) struct __va_argsave_t + { + size_t[6] regs; // RDI,RSI,RDX,RCX,R8,R9 + real[8] fpregs; // XMM0..XMM7 + __va_list va; + } + } +} +version (ARM) version = ARM_Any; +version (AArch64) version = ARM_Any; +version (MIPS32) version = MIPS_Any; +version (MIPS64) version = MIPS_Any; +version (PPC) version = PPC_Any; +version (PPC64) version = PPC_Any; - /************* - * Retrieve and store through parmn the next value that is of type T. - */ - void va_arg(T)(ref va_list ap, ref T parmn); +version (GNU) +{ + // Uses gcc.builtins +} +else version (ARM_Any) +{ + // Darwin uses a simpler varargs implementation + version (OSX) {} + else version (iOS) {} + else version (TVOS) {} + else version (WatchOS) {} + else: + + version (ARM) + { + version = AAPCS32; + } + else version (AArch64) + { + version = AAPCS64; + static import core.internal.vararg.aarch64; + } +} - /*********************** - * End use of ap. - */ - alias __builtin_va_end va_end; +T alignUp(size_t alignment = size_t.sizeof, T)(T base) pure +{ + enum mask = alignment - 1; + static assert(alignment > 0 && (alignment & mask) == 0, "alignment must be a power of 2"); + auto b = cast(size_t) base; + b = (b + mask) & ~mask; + return cast(T) b; +} +unittest +{ + assert(1.alignUp == size_t.sizeof); + assert(31.alignUp!16 == 32); + assert(32.alignUp!16 == 32); + assert(33.alignUp!16 == 48); + assert((-9).alignUp!8 == -8); +} - /*********************** - * Make a copy of ap. - */ - alias __builtin_va_copy va_copy; -} -else version (X86) +version (BigEndian) { - /********************* - * The argument pointer type. - */ - alias char* va_list; - - /********** - * Initialize ap. - * For 32 bit code, parmn should be the last named parameter. - * For 64 bit code, parmn should be __va_argsave. - */ - void va_start(T)(out va_list ap, ref T parmn) + // Adjusts a size_t-aligned pointer for types smaller than size_t. + T* adjustForBigEndian(T)(T* p, size_t size) pure { - ap = cast(va_list)( cast(void*) &parmn + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) ); + return size >= size_t.sizeof ? p : + cast(T*) ((cast(void*) p) + (size_t.sizeof - size)); } +} - /************ - * Retrieve and return the next value that is type T. - * Should use the other va_arg instead, as this won't work for 64 bit code. - */ - T va_arg(T)(ref va_list ap) - { - T arg = *cast(T*) ap; - ap = cast(va_list)( cast(void*) ap + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) ); - return arg; - } - /************ - * Retrieve and return the next value that is type T. - * This is the preferred version. - */ - void va_arg(T)(ref va_list ap, ref T parmn) - { - parmn = *cast(T*)ap; - ap = cast(va_list)(cast(void*)ap + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1))); - } +/** + * The argument pointer type. + */ +version (GNU) +{ + alias va_list = __gnuc_va_list; + alias __gnuc_va_list = __builtin_va_list; +} +else version (SysV_x64) +{ + alias va_list = core.internal.vararg.sysv_x64.va_list; + public import core.internal.vararg.sysv_x64 : __va_list, __va_list_tag; +} +else version (AAPCS32) +{ + alias va_list = __va_list; - /************* - * Retrieve and store through parmn the next value that is of TypeInfo ti. - * Used when the static type is not known. - */ - void va_arg()(ref va_list ap, TypeInfo ti, void* parmn) + // need std::__va_list for C++ mangling compatibility (AAPCS32 section 8.1.4) + extern (C++, std) struct __va_list { - // Wait until everyone updates to get TypeInfo.talign - //auto talign = ti.talign; - //auto p = cast(void*)(cast(size_t)ap + talign - 1) & ~(talign - 1); - auto p = ap; - auto tsize = ti.tsize; - ap = cast(va_list)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); - parmn[0..tsize] = p[0..tsize]; + void* __ap; } +} +else version (AAPCS64) +{ + alias va_list = core.internal.vararg.aarch64.va_list; +} +else +{ + alias va_list = char*; // incl. unknown platforms +} - /*********************** - * End use of ap. - */ - void va_end(va_list ap) + +/** + * Initialize ap. + * parmn should be the last named parameter. + */ +version (GNU) +{ + void va_start(T)(out va_list ap, ref T parmn); +} +else version (LDC) +{ + pragma(LDC_va_start) + void va_start(T)(out va_list ap, ref T parmn) @nogc; +} +else version (DigitalMars) +{ + version (X86) { + void va_start(T)(out va_list ap, ref T parmn) + { + ap = cast(va_list) ((cast(void*) &parmn) + T.sizeof.alignUp); + } } - - /// - void va_copy(out va_list dest, va_list src) + else { - dest = src; + void va_start(T)(out va_list ap, ref T parmn); // intrinsic; parmn should be __va_argsave for non-Windows x86_64 targets } } -else version (Windows) // Win64 -{ /* Win64 is characterized by all arguments fitting into a register size. - * Smaller ones are padded out to register size, and larger ones are passed by - * reference. - */ - /********************* - * The argument pointer type. - */ - alias char* va_list; - /********** - * Initialize ap. - * parmn should be the last named parameter. - */ - void va_start(T)(out va_list ap, ref T parmn); // Compiler intrinsic - - /************ - * Retrieve and return the next value that is type T. - */ - T va_arg(T)(ref va_list ap) +/** + * Retrieve and return the next value that is of type T. + */ +version (GNU) + T va_arg(T)(ref va_list ap); // intrinsic +else +T va_arg(T)(ref va_list ap) +{ + version (X86) { - static if (T.sizeof > size_t.sizeof) - T arg = **cast(T**)ap; - else - T arg = *cast(T*)ap; - ap = cast(va_list)(cast(void*)ap + ((size_t.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); - return arg; + auto p = cast(T*) ap; + ap += T.sizeof.alignUp; + return *p; } - - /************ - * Retrieve and return the next value that is type T. - * This is the preferred version. - */ - void va_arg(T)(ref va_list ap, ref T parmn) + else version (Win64) { - static if (T.sizeof > size_t.sizeof) - parmn = **cast(T**)ap; + // LDC passes slices as 2 separate 64-bit values, not as 128-bit struct + version (LDC) enum isLDC = true; + else enum isLDC = false; + static if (isLDC && is(T == E[], E)) + { + auto p = cast(T*) ap; + ap += T.sizeof; + return *p; + } else - parmn = *cast(T*)ap; - ap = cast(va_list)(cast(void*)ap + ((size_t.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); - } - - /************* - * Retrieve and store through parmn the next value that is of TypeInfo ti. - * Used when the static type is not known. - */ - void va_arg()(ref va_list ap, TypeInfo ti, void* parmn) - { - // Wait until everyone updates to get TypeInfo.talign - //auto talign = ti.talign; - //auto p = cast(void*)(cast(size_t)ap + talign - 1) & ~(talign - 1); - auto p = ap; - auto tsize = ti.tsize; - ap = cast(va_list)(cast(size_t)p + ((size_t.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); - void* q = (tsize > size_t.sizeof) ? *cast(void**)p : p; - parmn[0..tsize] = q[0..tsize]; + { + // passed indirectly by value if > 64 bits or of a size that is not a power of 2 + static if (T.sizeof > size_t.sizeof || (T.sizeof & (T.sizeof - 1)) != 0) + auto p = *cast(T**) ap; + else + auto p = cast(T*) ap; + ap += size_t.sizeof; + return *p; + } } - - /*********************** - * End use of ap. - */ - void va_end(va_list ap) + else version (SysV_x64) { + return core.internal.vararg.sysv_x64.va_arg!T(ap); } - - /// - void va_copy(out va_list dest, va_list src) + else version (AAPCS32) { - dest = src; + // AAPCS32 section 6.5 B.5: type with alignment >= 8 is 8-byte aligned + // instead of normal 4-byte alignment (APCS doesn't do this). + if (T.alignof >= 8) + ap.__ap = ap.__ap.alignUp!8; + auto p = cast(T*) ap.__ap; + version (BigEndian) + static if (T.sizeof < size_t.sizeof) + p = adjustForBigEndian(p, T.sizeof); + ap.__ap += T.sizeof.alignUp; + return *p; } -} -else version (X86_64) -{ - // Determine if type is a vector type - template isVectorType(T) + else version (AAPCS64) { - enum isVectorType = false; + return core.internal.vararg.aarch64.va_arg!T(ap); } - - template isVectorType(T : __vector(T[N]), size_t N) + else version (ARM_Any) { - enum isVectorType = true; + auto p = cast(T*) ap; + version (BigEndian) + static if (T.sizeof < size_t.sizeof) + p = adjustForBigEndian(p, T.sizeof); + ap += T.sizeof.alignUp; + return *p; } - - // Layout of this struct must match __gnuc_va_list for C ABI compatibility - struct __va_list_tag + else version (PPC_Any) { - uint offset_regs = 6 * 8; // no regs - uint offset_fpregs = 6 * 8 + 8 * 16; // no fp regs - void* stack_args; - void* reg_args; + /* + * The rules are described in the 64bit PowerPC ELF ABI Supplement 1.9, + * available here: + * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#PARAM-PASS + */ + + // Chapter 3.1.4 and 3.2.3: alignment may require the va_list pointer to first + // be aligned before accessing a value + if (T.alignof >= 8) + ap = ap.alignUp!8; + auto p = cast(T*) ap; + version (BigEndian) + static if (T.sizeof < size_t.sizeof) + p = adjustForBigEndian(p, T.sizeof); + ap += T.sizeof.alignUp; + return *p; } - alias __va_list = __va_list_tag; - - align(16) struct __va_argsave_t + else version (MIPS_Any) { - size_t[6] regs; // RDI,RSI,RDX,RCX,R8,R9 - real[8] fpregs; // XMM0..XMM7 - __va_list va; + auto p = cast(T*) ap; + version (BigEndian) + static if (T.sizeof < size_t.sizeof) + p = adjustForBigEndian(p, T.sizeof); + ap += T.sizeof.alignUp; + return *p; } + else + static assert(0, "Unsupported platform"); +} - /* - * Making it an array of 1 causes va_list to be passed as a pointer in - * function argument lists - */ - alias va_list = __va_list*; - - /// - void va_start(T)(out va_list ap, ref T parmn); // Compiler intrinsic - /// - T va_arg(T)(va_list ap) - { T a; - va_arg(ap, a); - return a; - } +/** + * Retrieve and store in parmn the next value that is of type T. + */ +version (GNU) + void va_arg(T)(ref va_list ap, ref T parmn); // intrinsic +else +void va_arg(T)(ref va_list ap, ref T parmn) +{ + parmn = va_arg!T(ap); +} - /// - void va_arg(T)(va_list apx, ref T parmn) - { - __va_list* ap = cast(__va_list*)apx; - static if (is(T U == __argTypes)) - { - static if (U.length == 0 || T.sizeof > 16 || (U[0].sizeof > 8 && !isVectorType!(U[0]))) - { // Always passed in memory - // The arg may have more strict alignment than the stack - auto p = (cast(size_t)ap.stack_args + T.alignof - 1) & ~(T.alignof - 1); - ap.stack_args = cast(void*)(p + ((T.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); - parmn = *cast(T*)p; - } - else static if (U.length == 1) - { // Arg is passed in one register - alias U[0] T1; - static if (is(T1 == double) || is(T1 == float) || isVectorType!(T1)) - { // Passed in XMM register - if (ap.offset_fpregs < (6 * 8 + 16 * 8)) - { - parmn = *cast(T*)(ap.reg_args + ap.offset_fpregs); - ap.offset_fpregs += 16; - } - else - { - parmn = *cast(T*)ap.stack_args; - ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1); - } - } - else - { // Passed in regular register - if (ap.offset_regs < 6 * 8 && T.sizeof <= 8) - { - parmn = *cast(T*)(ap.reg_args + ap.offset_regs); - ap.offset_regs += 8; - } - else - { - auto p = (cast(size_t)ap.stack_args + T.alignof - 1) & ~(T.alignof - 1); - ap.stack_args = cast(void*)(p + ((T.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); - parmn = *cast(T*)p; - } - } - } - else static if (U.length == 2) - { // Arg is passed in two registers - alias U[0] T1; - alias U[1] T2; - auto p = cast(void*)&parmn + 8; - // Both must be in registers, or both on stack, hence 4 cases +/** + * End use of ap. + */ +version (GNU) +{ + alias va_end = __builtin_va_end; +} +else version (LDC) +{ + pragma(LDC_va_end) + void va_end(va_list ap); +} +else version (DigitalMars) +{ + void va_end(va_list ap) {} +} - static if ((is(T1 == double) || is(T1 == float)) && - (is(T2 == double) || is(T2 == float))) - { - if (ap.offset_fpregs < (6 * 8 + 16 * 8) - 16) - { - *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_fpregs); - *cast(T2*)p = *cast(T2*)(ap.reg_args + ap.offset_fpregs + 16); - ap.offset_fpregs += 32; - } - else - { - *cast(T1*)&parmn = *cast(T1*)ap.stack_args; - ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1); - *cast(T2*)p = *cast(T2*)ap.stack_args; - ap.stack_args += (T2.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1); - } - } - else static if (is(T1 == double) || is(T1 == float)) - { - void* a = void; - if (ap.offset_fpregs < (6 * 8 + 16 * 8) && - ap.offset_regs < 6 * 8 && T2.sizeof <= 8) - { - *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_fpregs); - ap.offset_fpregs += 16; - a = ap.reg_args + ap.offset_regs; - ap.offset_regs += 8; - } - else - { - *cast(T1*)&parmn = *cast(T1*)ap.stack_args; - ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1); - a = ap.stack_args; - ap.stack_args += 8; - } - // Be careful not to go past the size of the actual argument - const sz2 = T.sizeof - 8; - p[0..sz2] = a[0..sz2]; - } - else static if (is(T2 == double) || is(T2 == float)) - { - if (ap.offset_regs < 6 * 8 && T1.sizeof <= 8 && - ap.offset_fpregs < (6 * 8 + 16 * 8)) - { - *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_regs); - ap.offset_regs += 8; - *cast(T2*)p = *cast(T2*)(ap.reg_args + ap.offset_fpregs); - ap.offset_fpregs += 16; - } - else - { - *cast(T1*)&parmn = *cast(T1*)ap.stack_args; - ap.stack_args += 8; - *cast(T2*)p = *cast(T2*)ap.stack_args; - ap.stack_args += (T2.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1); - } - } - else // both in regular registers - { - void* a = void; - if (ap.offset_regs < 5 * 8 && T1.sizeof <= 8 && T2.sizeof <= 8) - { - *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_regs); - ap.offset_regs += 8; - a = ap.reg_args + ap.offset_regs; - ap.offset_regs += 8; - } - else - { - *cast(T1*)&parmn = *cast(T1*)ap.stack_args; - ap.stack_args += 8; - a = ap.stack_args; - ap.stack_args += 8; - } - // Be careful not to go past the size of the actual argument - const sz2 = T.sizeof - 8; - p[0..sz2] = a[0..sz2]; - } - } - else - { - static assert(false); - } - } - else - { - static assert(false, "not a valid argument type for va_arg"); - } - } - /// - void va_arg()(va_list apx, TypeInfo ti, void* parmn) +/** + * Make a copy of ap. + */ +version (GNU) +{ + alias va_copy = __builtin_va_copy; +} +else version (LDC) +{ + pragma(LDC_va_copy) + void va_copy(out va_list dest, va_list src); +} +else version (DigitalMars) +{ + version (SysV_x64) { - __va_list* ap = cast(__va_list*)apx; - TypeInfo arg1, arg2; - if (!ti.argTypes(arg1, arg2)) + void va_copy(out va_list dest, va_list src, void* storage = alloca(__va_list_tag.sizeof)) { - bool inXMMregister(TypeInfo arg) pure nothrow @safe - { - return (arg.flags & 2) != 0; - } - - TypeInfo_Vector v1 = arg1 ? cast(TypeInfo_Vector)arg1 : null; - if (arg1 && (arg1.tsize <= 8 || v1)) - { // Arg is passed in one register - auto tsize = arg1.tsize; - void* p; - bool stack = false; - auto offset_fpregs_save = ap.offset_fpregs; - auto offset_regs_save = ap.offset_regs; - L1: - if (inXMMregister(arg1) || v1) - { // Passed in XMM register - if (ap.offset_fpregs < (6 * 8 + 16 * 8) && !stack) - { - p = ap.reg_args + ap.offset_fpregs; - ap.offset_fpregs += 16; - } - else - { - p = ap.stack_args; - ap.stack_args += (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1); - stack = true; - } - } - else - { // Passed in regular register - if (ap.offset_regs < 6 * 8 && !stack) - { - p = ap.reg_args + ap.offset_regs; - ap.offset_regs += 8; - } - else - { - p = ap.stack_args; - ap.stack_args += 8; - stack = true; - } - } - parmn[0..tsize] = p[0..tsize]; - - if (arg2) - { - if (inXMMregister(arg2)) - { // Passed in XMM register - if (ap.offset_fpregs < (6 * 8 + 16 * 8) && !stack) - { - p = ap.reg_args + ap.offset_fpregs; - ap.offset_fpregs += 16; - } - else - { - if (!stack) - { // arg1 is really on the stack, so rewind and redo - ap.offset_fpregs = offset_fpregs_save; - ap.offset_regs = offset_regs_save; - stack = true; - goto L1; - } - p = ap.stack_args; - ap.stack_args += (arg2.tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1); - } - } - else - { // Passed in regular register - if (ap.offset_regs < 6 * 8 && !stack) - { - p = ap.reg_args + ap.offset_regs; - ap.offset_regs += 8; - } - else - { - if (!stack) - { // arg1 is really on the stack, so rewind and redo - ap.offset_fpregs = offset_fpregs_save; - ap.offset_regs = offset_regs_save; - stack = true; - goto L1; - } - p = ap.stack_args; - ap.stack_args += 8; - } - } - auto sz = ti.tsize - 8; - (parmn + 8)[0..sz] = p[0..sz]; - } - } - else - { // Always passed in memory - // The arg may have more strict alignment than the stack - auto talign = ti.talign; - auto tsize = ti.tsize; - auto p = cast(void*)((cast(size_t)ap.stack_args + talign - 1) & ~(talign - 1)); - ap.stack_args = cast(void*)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); - parmn[0..tsize] = p[0..tsize]; - } + // Instead of copying the pointers, and aliasing the source va_list, + // the default argument alloca will allocate storage in the caller's + // stack frame. This is still not correct (it should be allocated in + // the place where the va_list variable is declared) but most of the + // time the caller's stack frame _is_ the place where the va_list is + // allocated, so in most cases this will now work. + dest = cast(va_list) storage; + *dest = *src; } - else - { - assert(false, "not a valid argument type for va_arg"); - } - } - /// - void va_end(va_list ap) - { + import core.stdc.stdlib : alloca; } - - import core.stdc.stdlib : alloca; - - /// - void va_copy(out va_list dest, va_list src, void* storage = alloca(__va_list_tag.sizeof)) + else { - // Instead of copying the pointers, and aliasing the source va_list, - // the default argument alloca will allocate storage in the caller's - // stack frame. This is still not correct (it should be allocated in - // the place where the va_list variable is declared) but most of the - // time the caller's stack frame _is_ the place where the va_list is - // allocated, so in most cases this will now work. - dest = cast(va_list)storage; - *dest = *src; + void va_copy(out va_list dest, va_list src) + { + dest = src; + } } } -else -{ - static assert(false, "Unsupported platform"); -} diff --git a/libphobos/libdruntime/core/stdc/stdint.d b/libphobos/libdruntime/core/stdc/stdint.d index 0e310521e0e..ac71b1d09d5 100644 --- a/libphobos/libdruntime/core/stdc/stdint.d +++ b/libphobos/libdruntime/core/stdc/stdint.d @@ -14,10 +14,10 @@ module core.stdc.stdint; -private import core.stdc.config; -private import core.stdc.stddef; // for wchar_t -private import core.stdc.signal; // for sig_atomic_t -private import core.stdc.wchar_; // for wint_t +import core.stdc.config; +import core.stdc.stddef; // for wchar_t +import core.stdc.signal; // for sig_atomic_t +import core.stdc.wchar_; // for wint_t version (OSX) version = Darwin; diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d index e68f393e3e6..00efe885289 100644 --- a/libphobos/libdruntime/core/stdc/stdio.d +++ b/libphobos/libdruntime/core/stdc/stdio.d @@ -268,7 +268,7 @@ else version (DragonFlyBSD) ssize_t s_len; // current length of string int s_flags; // flags ssize_t s_sect_len; // current length of section - }; + } enum { SBUF_FIXEDLEN = 0x00000000, // fixed length buffer (default) @@ -526,7 +526,7 @@ else version (FreeBSD) int function(void*) _close; int function(void*, char*, int) _read; fpos_t function(void*, fpos_t, int) _seek; - int function(void*, in char*, int) _write; + int function(void*, const scope char*, int) _write; __sbuf _ub; ubyte* _up; @@ -572,7 +572,7 @@ else version (NetBSD) int function(void*) _close; ssize_t function(void*, char*, size_t) _read; fpos_t function(void*, fpos_t, int) _seek; - ssize_t function(void*, in char*, size_t) _write; + ssize_t function(void*, const scope char*, size_t) _write; __sbuf _ub; ubyte* _up; @@ -1166,22 +1166,22 @@ version (MinGW) // Prefer the MinGW versions over the MSVC ones, as the latter don't handle // reals at all. /// - int __mingw_fprintf(FILE* stream, scope const char* format, ...); + int __mingw_fprintf(FILE* stream, scope const char* format, scope const ...); /// alias __mingw_fprintf fprintf; /// - int __mingw_fscanf(FILE* stream, scope const char* format, ...); + int __mingw_fscanf(FILE* stream, scope const char* format, scope ...); /// alias __mingw_fscanf fscanf; /// - int __mingw_sprintf(scope char* s, scope const char* format, ...); + int __mingw_sprintf(scope char* s, scope const char* format, scope const ...); /// alias __mingw_sprintf sprintf; /// - int __mingw_sscanf(scope const char* s, scope const char* format, ...); + int __mingw_sscanf(scope const char* s, scope const char* format, scope ...); /// alias __mingw_sscanf sscanf; @@ -1216,25 +1216,25 @@ version (MinGW) alias __mingw_vscanf vscanf; /// - int __mingw_printf(scope const char* format, ...); + int __mingw_printf(scope const char* format, scope const ...); /// alias __mingw_printf printf; /// - int __mingw_scanf(scope const char* format, ...); + int __mingw_scanf(scope const char* format, scope ...); /// alias __mingw_scanf scanf; } else { /// - int fprintf(FILE* stream, scope const char* format, ...); + int fprintf(FILE* stream, scope const char* format, scope const ...); /// - int fscanf(FILE* stream, scope const char* format, ...); + int fscanf(FILE* stream, scope const char* format, scope ...); /// - int sprintf(scope char* s, scope const char* format, ...); + int sprintf(scope char* s, scope const char* format, scope const ...); /// - int sscanf(scope const char* s, scope const char* format, ...); + int sscanf(scope const char* s, scope const char* format, scope ...); /// int vfprintf(FILE* stream, scope const char* format, va_list arg); /// @@ -1248,9 +1248,9 @@ else /// int vscanf(scope const char* format, va_list arg); /// - int printf(scope const char* format, ...); + int printf(scope const char* format, scope const ...); /// - int scanf(scope const char* format, ...); + int scanf(scope const char* format, scope ...); } // No unsafe pointer manipulation. @@ -1323,7 +1323,7 @@ version (CRuntime_DigitalMars) pure int fileno()(FILE* stream) { return stream._file; } } /// - int _snprintf(scope char* s, size_t n, scope const char* fmt, ...); + int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...); /// alias _snprintf snprintf; @@ -1351,7 +1351,7 @@ else version (CRuntime_Microsoft) version (MinGW) { - int __mingw_snprintf(scope char* s, size_t n, scope const char* fmt, ...); + int __mingw_snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...); /// alias __mingw_snprintf _snprintf; /// @@ -1367,9 +1367,9 @@ else version (CRuntime_Microsoft) else { /// - int _snprintf(scope char* s, size_t n, scope const char* format, ...); + int _snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// - int snprintf(scope char* s, size_t n, scope const char* format, ...); + int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); @@ -1410,7 +1410,7 @@ else version (CRuntime_Glibc) } /// - int snprintf(scope char* s, size_t n, scope const char* format, ...); + int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } @@ -1432,7 +1432,7 @@ else version (Darwin) } /// - int snprintf(scope char* s, size_t n, scope const char* format, ...); + int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } @@ -1454,7 +1454,7 @@ else version (FreeBSD) } /// - int snprintf(scope char* s, size_t n, scope const char* format, ...); + int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } @@ -1476,9 +1476,9 @@ else version (NetBSD) } /// - int snprintf(char* s, size_t n, in char* format, ...); + int snprintf(char* s, size_t n, const scope char* format, scope const ...); /// - int vsnprintf(char* s, size_t n, in char* format, va_list arg); + int vsnprintf(char* s, size_t n, const scope char* format, va_list arg); } else version (OpenBSD) { @@ -1567,7 +1567,7 @@ else version (OpenBSD) } /// - int snprintf(scope char* s, size_t n, scope const char* format, ...); + int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } @@ -1599,8 +1599,8 @@ else version (DragonFlyBSD) enum __SALC = 0x4000; enum __SIGN = 0x8000; - int snprintf(scope char* s, size_t n, scope const char* format, ...); - int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); + int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); + int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (Solaris) { @@ -1620,7 +1620,7 @@ else version (Solaris) } /// - int snprintf(scope char* s, size_t n, scope const char* format, ...); + int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } @@ -1641,8 +1641,8 @@ else version (CRuntime_Bionic) int fileno(FILE*); } - /// - int snprintf(scope char* s, size_t n, scope const char* format, ...); + /// + int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } @@ -1663,7 +1663,7 @@ else version (CRuntime_Musl) } /// - int snprintf(scope char* s, size_t n, scope const char* format, ...); + int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } @@ -1685,7 +1685,7 @@ else version (CRuntime_UClibc) } /// - int snprintf(scope char* s, size_t n, scope const char* format, ...); + int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d index 7c0b7b6bc9b..7caef4c1339 100644 --- a/libphobos/libdruntime/core/stdc/stdlib.d +++ b/libphobos/libdruntime/core/stdc/stdlib.d @@ -14,7 +14,7 @@ module core.stdc.stdlib; -private import core.stdc.config; +import core.stdc.config; public import core.stdc.stddef; // for wchar_t version (OSX) diff --git a/libphobos/libdruntime/core/stdc/string.d b/libphobos/libdruntime/core/stdc/string.d index 0929a4eab53..a26811ca623 100644 --- a/libphobos/libdruntime/core/stdc/string.d +++ b/libphobos/libdruntime/core/stdc/string.d @@ -35,51 +35,35 @@ nothrow: @nogc: /// -pure void* memchr(return const void* s, int c, size_t n); +inout(void)* memchr(return inout void* s, int c, size_t n) pure; /// -pure int memcmp(scope const void* s1, scope const void* s2, size_t n); +int memcmp(scope const void* s1, scope const void* s2, size_t n) pure; /// -pure void* memcpy(return void* s1, scope const void* s2, size_t n); +void* memcpy(return void* s1, scope const void* s2, size_t n) pure; version (Windows) { /// int memicmp(scope const char* s1, scope const char* s2, size_t n); } /// -pure void* memmove(return void* s1, scope const void* s2, size_t n); +void* memmove(return void* s1, scope const void* s2, size_t n) pure; /// -pure void* memset(return void* s, int c, size_t n); +void* memset(return void* s, int c, size_t n) pure; /// -pure char* strcpy(return char* s1, scope const char* s2); +char* strcat(return char* s1, scope const char* s2) pure; /// -pure char* strncpy(return char* s1, scope const char* s2, size_t n); +inout(char)* strchr(return inout(char)* s, int c) pure; /// -pure char* strcat(return char* s1, scope const char* s2); -/// -pure char* strncat(return char* s1, scope const char* s2, size_t n); -/// -pure int strcmp(scope const char* s1, scope const char* s2); +int strcmp(scope const char* s1, scope const char* s2) pure; /// int strcoll(scope const char* s1, scope const char* s2); /// -pure int strncmp(scope const char* s1, scope const char* s2, size_t n); -/// -size_t strxfrm(scope char* s1, scope const char* s2, size_t n); -/// -pure inout(char)* strchr(return inout(char)* s, int c); -/// -pure size_t strcspn(scope const char* s1, scope const char* s2); +char* strcpy(return char* s1, scope const char* s2) pure; /// -pure inout(char)* strpbrk(return inout(char)* s1, scope const char* s2); +size_t strcspn(scope const char* s1, scope const char* s2) pure; /// -pure inout(char)* strrchr(return inout(char)* s, int c); -/// -pure size_t strspn(scope const char* s1, scope const char* s2); -/// -pure inout(char)* strstr(return inout(char)* s1, scope const char* s2); -/// -char* strtok(return char* s1, scope const char* s2); +char* strdup(scope const char *s); /// char* strerror(int errnum); // This `strerror_r` definition is not following the POSIX standard @@ -94,6 +78,22 @@ else int strerror_r(int errnum, scope char* buf, size_t buflen); } /// -pure size_t strlen(scope const char* s); +size_t strlen(scope const char* s) pure; /// -char* strdup(scope const char *s); +char* strncat(return char* s1, scope const char* s2, size_t n) pure; +/// +int strncmp(scope const char* s1, scope const char* s2, size_t n) pure; +/// +char* strncpy(return char* s1, scope const char* s2, size_t n) pure; +/// +inout(char)* strpbrk(return inout(char)* s1, scope const char* s2) pure; +/// +inout(char)* strrchr(return inout(char)* s, int c) pure; +/// +size_t strspn(scope const char* s1, scope const char* s2) pure; +/// +inout(char)* strstr(return inout(char)* s1, scope const char* s2) pure; +/// +char* strtok(return char* s1, scope const char* s2); +/// +size_t strxfrm(scope char* s1, scope const char* s2, size_t n); diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d index 16184e29845..4dd1b3ccc66 100644 --- a/libphobos/libdruntime/core/stdc/tgmath.d +++ b/libphobos/libdruntime/core/stdc/tgmath.d @@ -14,7 +14,7 @@ module core.stdc.tgmath; -private import core.stdc.config; +import core.stdc.config; private static import core.stdc.math; private static import core.stdc.complex; @@ -23,554 +23,6 @@ extern (C): nothrow: @nogc: -version (FreeBSD) -{ - /// - alias core.stdc.math.acos acos; - /// - alias core.stdc.math.acosf acos; - /// - alias core.stdc.math.acosl acos; - - /// - alias core.stdc.complex.cacos acos; - /// - alias core.stdc.complex.cacosf acos; - /// - alias core.stdc.complex.cacosl acos; - - /// - alias core.stdc.math.asin asin; - /// - alias core.stdc.math.asinf asin; - /// - alias core.stdc.math.asinl asin; - - /// - alias core.stdc.complex.casin asin; - /// - alias core.stdc.complex.casinf asin; - /// - alias core.stdc.complex.casinl asin; - - /// - alias core.stdc.math.atan atan; - /// - alias core.stdc.math.atanf atan; - /// - alias core.stdc.math.atanl atan; - - /// - alias core.stdc.complex.catan atan; - /// - alias core.stdc.complex.catanf atan; - /// - alias core.stdc.complex.catanl atan; - - /// - alias core.stdc.math.atan2 atan2; - /// - alias core.stdc.math.atan2f atan2; - /// - alias core.stdc.math.atan2l atan2; - - /// - alias core.stdc.math.cos cos; - /// - alias core.stdc.math.cosf cos; - /// - alias core.stdc.math.cosl cos; - - /// - alias core.stdc.complex.ccos cos; - /// - alias core.stdc.complex.ccosf cos; - /// - alias core.stdc.complex.ccosl cos; - - /// - alias core.stdc.math.sin sin; - /// - alias core.stdc.math.sinf sin; - /// - alias core.stdc.math.sinl sin; - - /// - alias core.stdc.complex.csin csin; - /// - alias core.stdc.complex.csinf csin; - /// - alias core.stdc.complex.csinl csin; - - /// - alias core.stdc.math.tan tan; - /// - alias core.stdc.math.tanf tan; - /// - alias core.stdc.math.tanl tan; - - /// - alias core.stdc.complex.ctan tan; - /// - alias core.stdc.complex.ctanf tan; - /// - alias core.stdc.complex.ctanl tan; - - /// - alias core.stdc.math.acosh acosh; - /// - alias core.stdc.math.acoshf acosh; - /// - alias core.stdc.math.acoshl acosh; - - /// - alias core.stdc.complex.cacosh acosh; - /// - alias core.stdc.complex.cacoshf acosh; - /// - alias core.stdc.complex.cacoshl acosh; - - /// - alias core.stdc.math.asinh asinh; - /// - alias core.stdc.math.asinhf asinh; - /// - alias core.stdc.math.asinhl asinh; - - /// - alias core.stdc.complex.casinh asinh; - /// - alias core.stdc.complex.casinhf asinh; - /// - alias core.stdc.complex.casinhl asinh; - - /// - alias core.stdc.math.atanh atanh; - /// - alias core.stdc.math.atanhf atanh; - /// - alias core.stdc.math.atanhl atanh; - - /// - alias core.stdc.complex.catanh atanh; - /// - alias core.stdc.complex.catanhf atanh; - /// - alias core.stdc.complex.catanhl atanh; - - /// - alias core.stdc.math.cosh cosh; - /// - alias core.stdc.math.coshf cosh; - /// - alias core.stdc.math.coshl cosh; - - /// - alias core.stdc.complex.ccosh cosh; - /// - alias core.stdc.complex.ccoshf cosh; - /// - alias core.stdc.complex.ccoshl cosh; - - /// - alias core.stdc.math.sinh sinh; - /// - alias core.stdc.math.sinhf sinh; - /// - alias core.stdc.math.sinhl sinh; - - /// - alias core.stdc.complex.csinh sinh; - /// - alias core.stdc.complex.csinhf sinh; - /// - alias core.stdc.complex.csinhl sinh; - - /// - alias core.stdc.math.tanh tanh; - /// - alias core.stdc.math.tanhf tanh; - /// - alias core.stdc.math.tanhl tanh; - - /// - alias core.stdc.complex.ctanh tanh; - /// - alias core.stdc.complex.ctanhf tanh; - /// - alias core.stdc.complex.ctanhl tanh; - - /// - alias core.stdc.math.exp exp; - /// - alias core.stdc.math.expf exp; - /// - alias core.stdc.math.expl exp; - - /// - alias core.stdc.complex.cexp exp; - /// - alias core.stdc.complex.cexpf exp; - /// - alias core.stdc.complex.cexpl exp; - - /// - alias core.stdc.math.exp2 exp2; - /// - alias core.stdc.math.exp2f exp2; - /// - alias core.stdc.math.exp2l exp2; - - /// - alias core.stdc.math.expm1 expm1; - /// - alias core.stdc.math.expm1f expm1; - /// - alias core.stdc.math.expm1l expm1; - - /// - alias core.stdc.math.frexp frexp; - /// - alias core.stdc.math.frexpf frexp; - /// - alias core.stdc.math.frexpl frexp; - - /// - alias core.stdc.math.ilogb ilogb; - /// - alias core.stdc.math.ilogbf ilogb; - /// - alias core.stdc.math.ilogbl ilogb; - - /// - alias core.stdc.math.ldexp ldexp; - /// - alias core.stdc.math.ldexpf ldexp; - /// - alias core.stdc.math.ldexpl ldexp; - - /// - alias core.stdc.math.log log; - /// - alias core.stdc.math.logf log; - /// - alias core.stdc.math.logl log; - - /// - alias core.stdc.complex.clog log; - /// - alias core.stdc.complex.clogf log; - /// - alias core.stdc.complex.clogl log; - - /// - alias core.stdc.math.log10 log10; - /// - alias core.stdc.math.log10f log10; - /// - alias core.stdc.math.log10l log10; - - /// - alias core.stdc.math.log1p log1p; - /// - alias core.stdc.math.log1pf log1p; - /// - alias core.stdc.math.log1pl log1p; - - /// - alias core.stdc.math.log2 log2; - /// - alias core.stdc.math.log2f log2; - /// - alias core.stdc.math.log2l log2; - - /// - alias core.stdc.math.logb logb; - /// - alias core.stdc.math.logbf logb; - /// - alias core.stdc.math.logbl logb; - - /// - alias core.stdc.math.modf modf; - /// - alias core.stdc.math.modff modf; -// alias core.stdc.math.modfl modf; - - /// - alias core.stdc.math.scalbn scalbn; - /// - alias core.stdc.math.scalbnf scalbn; - /// - alias core.stdc.math.scalbnl scalbn; - - /// - alias core.stdc.math.scalbln scalbln; - /// - alias core.stdc.math.scalblnf scalbln; - /// - alias core.stdc.math.scalblnl scalbln; - - /// - alias core.stdc.math.cbrt cbrt; - /// - alias core.stdc.math.cbrtf cbrt; - /// - alias core.stdc.math.cbrtl cbrt; - - /// - alias core.stdc.math.fabs fabs; - /// - alias core.stdc.math.fabsf fabs; - /// - alias core.stdc.math.fabsl fabs; - - /// - alias core.stdc.complex.cabs fabs; - /// - alias core.stdc.complex.cabsf fabs; - /// - alias core.stdc.complex.cabsl fabs; - - /// - alias core.stdc.math.hypot hypot; - /// - alias core.stdc.math.hypotf hypot; - /// - alias core.stdc.math.hypotl hypot; - - /// - alias core.stdc.math.pow pow; - /// - alias core.stdc.math.powf pow; - /// - alias core.stdc.math.powl pow; - - /// - alias core.stdc.complex.cpow pow; - /// - alias core.stdc.complex.cpowf pow; - /// - alias core.stdc.complex.cpowl pow; - - /// - alias core.stdc.math.sqrt sqrt; - /// - alias core.stdc.math.sqrtf sqrt; - /// - alias core.stdc.math.sqrtl sqrt; - - /// - alias core.stdc.complex.csqrt sqrt; - /// - alias core.stdc.complex.csqrtf sqrt; - /// - alias core.stdc.complex.csqrtl sqrt; - - /// - alias core.stdc.math.erf erf; - /// - alias core.stdc.math.erff erf; - /// - alias core.stdc.math.erfl erf; - - /// - alias core.stdc.math.erfc erfc; - /// - alias core.stdc.math.erfcf erfc; - /// - alias core.stdc.math.erfcl erfc; - - /// - alias core.stdc.math.lgamma lgamma; - /// - alias core.stdc.math.lgammaf lgamma; - /// - alias core.stdc.math.lgammal lgamma; - - /// - alias core.stdc.math.tgamma tgamma; - /// - alias core.stdc.math.tgammaf tgamma; - /// - alias core.stdc.math.tgammal tgamma; - - /// - alias core.stdc.math.ceil ceil; - /// - alias core.stdc.math.ceilf ceil; - /// - alias core.stdc.math.ceill ceil; - - /// - alias core.stdc.math.floor floor; - /// - alias core.stdc.math.floorf floor; - /// - alias core.stdc.math.floorl floor; - - /// - alias core.stdc.math.nearbyint nearbyint; - /// - alias core.stdc.math.nearbyintf nearbyint; - /// - alias core.stdc.math.nearbyintl nearbyint; - - /// - alias core.stdc.math.rint rint; - /// - alias core.stdc.math.rintf rint; - /// - alias core.stdc.math.rintl rint; - - /// - alias core.stdc.math.lrint lrint; - /// - alias core.stdc.math.lrintf lrint; - /// - alias core.stdc.math.lrintl lrint; - - /// - alias core.stdc.math.llrint llrint; - /// - alias core.stdc.math.llrintf llrint; - /// - alias core.stdc.math.llrintl llrint; - - /// - alias core.stdc.math.round round; - /// - alias core.stdc.math.roundf round; - /// - alias core.stdc.math.roundl round; - - /// - alias core.stdc.math.lround lround; - /// - alias core.stdc.math.lroundf lround; - /// - alias core.stdc.math.lroundl lround; - - /// - alias core.stdc.math.llround llround; - /// - alias core.stdc.math.llroundf llround; - /// - alias core.stdc.math.llroundl llround; - - /// - alias core.stdc.math.trunc trunc; - /// - alias core.stdc.math.truncf trunc; - /// - alias core.stdc.math.truncl trunc; - - /// - alias core.stdc.math.fmod fmod; - /// - alias core.stdc.math.fmodf fmod; - /// - alias core.stdc.math.fmodl fmod; - - /// - alias core.stdc.math.remainder remainder; - /// - alias core.stdc.math.remainderf remainder; - /// - alias core.stdc.math.remainderl remainder; - - /// - alias core.stdc.math.remquo remquo; - /// - alias core.stdc.math.remquof remquo; - /// - alias core.stdc.math.remquol remquo; - - /// - alias core.stdc.math.copysign copysign; - /// - alias core.stdc.math.copysignf copysign; - /// - alias core.stdc.math.copysignl copysign; - -// alias core.stdc.math.nan nan; -// alias core.stdc.math.nanf nan; -// alias core.stdc.math.nanl nan; - - /// - alias core.stdc.math.nextafter nextafter; - /// - alias core.stdc.math.nextafterf nextafter; - /// - alias core.stdc.math.nextafterl nextafter; - - /// - alias core.stdc.math.nexttoward nexttoward; - /// - alias core.stdc.math.nexttowardf nexttoward; - /// - alias core.stdc.math.nexttowardl nexttoward; - - /// - alias core.stdc.math.fdim fdim; - /// - alias core.stdc.math.fdimf fdim; - /// - alias core.stdc.math.fdiml fdim; - - /// - alias core.stdc.math.fmax fmax; - /// - alias core.stdc.math.fmaxf fmax; - /// - alias core.stdc.math.fmaxl fmax; - - /// - alias core.stdc.math.fmin fmin; - /// - alias core.stdc.math.fmin fmin; - /// - alias core.stdc.math.fminl fmin; - - /// - alias core.stdc.math.fma fma; - /// - alias core.stdc.math.fmaf fma; - /// - alias core.stdc.math.fmal fma; - - /// - alias core.stdc.complex.carg carg; - /// - alias core.stdc.complex.cargf carg; - /// - alias core.stdc.complex.cargl carg; - - /// - alias core.stdc.complex.cimag cimag; - /// - alias core.stdc.complex.cimagf cimag; - /// - alias core.stdc.complex.cimagl cimag; - - /// - alias core.stdc.complex.conj conj; - /// - alias core.stdc.complex.conjf conj; - /// - alias core.stdc.complex.conjl conj; - - /// - alias core.stdc.complex.cproj cproj; - /// - alias core.stdc.complex.cprojf cproj; - /// - alias core.stdc.complex.cprojl cproj; - -// alias core.stdc.complex.creal creal; -// alias core.stdc.complex.crealf creal; -// alias core.stdc.complex.creall creal; -} version (NetBSD) { /// diff --git a/libphobos/libdruntime/core/stdc/time.d b/libphobos/libdruntime/core/stdc/time.d index 4a571e153bf..b19c3c7a899 100644 --- a/libphobos/libdruntime/core/stdc/time.d +++ b/libphobos/libdruntime/core/stdc/time.d @@ -15,138 +15,20 @@ module core.stdc.time; -private import core.stdc.config; +version (Posix) + public import core.sys.posix.stdc.time; +else version (Windows) + public import core.sys.windows.stdc.time; +else + static assert(0, "unsupported system"); -version (OSX) - version = Darwin; -else version (iOS) - version = Darwin; -else version (TVOS) - version = Darwin; -else version (WatchOS) - version = Darwin; +import core.stdc.config; extern (C): @trusted: // There are only a few functions here that use unsafe C strings. nothrow: @nogc: -version (Windows) -{ - /// - struct tm - { - int tm_sec; /// seconds after the minute - [0, 60] - int tm_min; /// minutes after the hour - [0, 59] - int tm_hour; /// hours since midnight - [0, 23] - int tm_mday; /// day of the month - [1, 31] - int tm_mon; /// months since January - [0, 11] - int tm_year; /// years since 1900 - int tm_wday; /// days since Sunday - [0, 6] - int tm_yday; /// days since January 1 - [0, 365] - int tm_isdst; /// Daylight Saving Time flag - } -} -else version (Posix) -{ - /// - struct tm - { - int tm_sec; /// seconds after the minute [0-60] - int tm_min; /// minutes after the hour [0-59] - int tm_hour; /// hours since midnight [0-23] - int tm_mday; /// day of the month [1-31] - int tm_mon; /// months since January [0-11] - int tm_year; /// years since 1900 - int tm_wday; /// days since Sunday [0-6] - int tm_yday; /// days since January 1 [0-365] - int tm_isdst; /// Daylight Savings Time flag - c_long tm_gmtoff; /// offset from CUT in seconds - char* tm_zone; /// timezone abbreviation - } -} - -version (Posix) -{ - public import core.sys.posix.sys.types : time_t, clock_t; -} -else version (Windows) -{ - /// - alias c_long time_t; - /// - alias c_long clock_t; -} - -/// -version (Windows) -{ - enum clock_t CLOCKS_PER_SEC = 1000; - clock_t clock(); -} -else version (OSX) -{ - enum clock_t CLOCKS_PER_SEC = 1_000_000; // was 100 until OSX 10.4/10.5 - version (X86) - extern (C) pragma(mangle, "clock$UNIX2003") clock_t clock(); - else - clock_t clock(); -} -else version (Darwin) // other Darwins (iOS, TVOS, WatchOS) -{ - enum clock_t CLOCKS_PER_SEC = 1_000_000; - clock_t clock(); -} -else version (FreeBSD) -{ - enum clock_t CLOCKS_PER_SEC = 128; - clock_t clock(); -} -else version (NetBSD) -{ - enum clock_t CLOCKS_PER_SEC = 100; - clock_t clock(); -} -else version (OpenBSD) -{ - enum clock_t CLOCKS_PER_SEC = 100; - clock_t clock(); -} -else version (DragonFlyBSD) -{ - enum clock_t CLOCKS_PER_SEC = 128; - clock_t clock(); -} -else version (Solaris) -{ - enum clock_t CLOCKS_PER_SEC = 1_000_000; - clock_t clock(); -} -else version (CRuntime_Glibc) -{ - enum clock_t CLOCKS_PER_SEC = 1_000_000; - clock_t clock(); -} -else version (CRuntime_Musl) -{ - enum clock_t CLOCKS_PER_SEC = 1_000_000; - clock_t clock(); -} -else version (CRuntime_Bionic) -{ - enum clock_t CLOCKS_PER_SEC = 1_000_000; - clock_t clock(); -} -else version (CRuntime_UClibc) -{ - enum clock_t CLOCKS_PER_SEC = 1_000_000; - clock_t clock(); -} -else -{ - static assert(0, "unsupported system"); -} - /// pure double difftime(time_t time1, time_t time0); // MT-Safe /// @@ -164,92 +46,3 @@ time_t time(scope time_t* timer); @system tm* localtime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf env locale /// @system size_t strftime(scope char* s, size_t maxsize, const scope char* format, const scope tm* timeptr); // @system: MT-Safe env locale - -version (Windows) -{ - /// - void tzset(); // non-standard - /// - void _tzset(); // non-standard - /// - @system char* _strdate(return scope char* s); // non-standard - /// - @system char* _strtime(return scope char* s); // non-standard - - /// - extern __gshared const(char)*[2] tzname; // non-standard -} -else version (Darwin) -{ - /// - void tzset(); // non-standard - /// - extern __gshared const(char)*[2] tzname; // non-standard -} -else version (CRuntime_Glibc) -{ - /// - void tzset(); // non-standard - /// - extern __gshared const(char)*[2] tzname; // non-standard -} -else version (FreeBSD) -{ - /// - void tzset(); // non-standard - /// - extern __gshared const(char)*[2] tzname; // non-standard -} -else version (NetBSD) -{ - /// - void tzset(); // non-standard - /// - extern __gshared const(char)*[2] tzname; // non-standard -} -else version (OpenBSD) -{ - /// - void tzset(); // non-standard - /// - extern __gshared const(char)*[2] tzname; // non-standard -} -else version (DragonFlyBSD) -{ - /// - void tzset(); // non-standard - /// - extern __gshared const(char)*[2] tzname; // non-standard -} -else version (Solaris) -{ - /// - void tzset(); - /// - extern __gshared const(char)*[2] tzname; -} -else version (CRuntime_Bionic) -{ - /// - void tzset(); - /// - extern __gshared const(char)*[2] tzname; -} -else version (CRuntime_Musl) -{ - /// - void tzset(); // non-standard - /// - extern __gshared const(char)*[2] tzname; // non-standard -} -else version (CRuntime_UClibc) -{ - /// - void tzset(); - /// - extern __gshared const(char)*[2] tzname; -} -else -{ - static assert(false, "Unsupported platform"); -} diff --git a/libphobos/libdruntime/core/stdc/wchar_.d b/libphobos/libdruntime/core/stdc/wchar_.d index 1cf8678f4cc..eecc8ef918e 100644 --- a/libphobos/libdruntime/core/stdc/wchar_.d +++ b/libphobos/libdruntime/core/stdc/wchar_.d @@ -12,14 +12,11 @@ * Standards: ISO/IEC 9899:1999 (E) */ -/* NOTE: This file has been patched from the original DMD distribution to - * work with the GDC compiler. - */ module core.stdc.wchar_; -private import core.stdc.config; -private import core.stdc.stdarg; // for va_list -private import core.stdc.stdio; // for FILE, not exposed per spec +import core.stdc.config; +import core.stdc.stdarg; // for va_list +import core.stdc.stdio; // for FILE, not exposed per spec public import core.stdc.stddef; // for wchar_t public import core.stdc.time; // for tm public import core.stdc.stdint; // for WCHAR_MIN, WCHAR_MAX @@ -131,44 +128,29 @@ alias wchar_t wint_t; enum wchar_t WEOF = 0xFFFF; /// -int fwprintf(FILE* stream, in wchar_t* format, ...); +int fwprintf(FILE* stream, const scope wchar_t* format, scope const ...); /// -int fwscanf(FILE* stream, in wchar_t* format, ...); -int swscanf(in wchar_t* s, in wchar_t* format, ...); +int fwscanf(FILE* stream, const scope wchar_t* format, scope ...); /// -int vfwprintf(FILE* stream, in wchar_t* format, va_list arg); +int swprintf(wchar_t* s, size_t n, const scope wchar_t* format, scope const ...); /// -int vfwscanf(FILE* stream, in wchar_t* format, va_list arg); -int vswscanf(in wchar_t* s, in wchar_t* format, va_list arg); +int swscanf(const scope wchar_t* s, const scope wchar_t* format, scope ...); /// -int vwprintf(in wchar_t* format, va_list arg); +int vfwprintf(FILE* stream, const scope wchar_t* format, va_list arg); /// -int vwscanf(in wchar_t* format, va_list arg); +int vfwscanf(FILE* stream, const scope wchar_t* format, va_list arg); /// -int wprintf(in wchar_t* format, ...); +int vswprintf(wchar_t* s, size_t n, const scope wchar_t* format, va_list arg); /// -int wscanf(in wchar_t* format, ...); - -/* - * Windows has 2 versions of swprintf and vswprintf. MinGW defaults to the - * Microsoft signature. Alias to match DMD/ANSI signature. - */ -version (MinGW) -{ - /// - int _snwprintf(wchar_t* s, size_t n, in wchar_t* format, ...); - alias _snwprintf swprintf; - /// - int _vsnwprintf(wchar_t* s, size_t n, in wchar_t* format, va_list arg); - alias _vsnwprintf vswprintf; -} -else -{ - /// - int swprintf(wchar_t* s, size_t n, in wchar_t* format, ...); - /// - int vswprintf(wchar_t* s, size_t n, in wchar_t* format, va_list arg); -} +int vswscanf(const scope wchar_t* s, const scope wchar_t* format, va_list arg); +/// +int vwprintf(const scope wchar_t* format, va_list arg); +/// +int vwscanf(const scope wchar_t* format, va_list arg); +/// +int wprintf(const scope wchar_t* format, scope const ...); +/// +int wscanf(const scope wchar_t* format, scope ...); // No unsafe pointer manipulation. @trusted @@ -182,7 +164,7 @@ else /// wchar_t* fgetws(wchar_t* s, int n, FILE* stream); /// -int fputws(in wchar_t* s, FILE* stream); +int fputws(const scope wchar_t* s, FILE* stream); // No unsafe pointer manipulation. extern (D) @trusted @@ -215,19 +197,19 @@ extern (D) @trusted } /// -double wcstod(in wchar_t* nptr, wchar_t** endptr); +double wcstod(const scope wchar_t* nptr, wchar_t** endptr); /// -float wcstof(in wchar_t* nptr, wchar_t** endptr); +float wcstof(const scope wchar_t* nptr, wchar_t** endptr); /// -real wcstold(in wchar_t* nptr, wchar_t** endptr); +real wcstold(const scope wchar_t* nptr, wchar_t** endptr); /// -c_long wcstol(in wchar_t* nptr, wchar_t** endptr, int base); +c_long wcstol(const scope wchar_t* nptr, wchar_t** endptr, int base); /// -long wcstoll(in wchar_t* nptr, wchar_t** endptr, int base); +long wcstoll(const scope wchar_t* nptr, wchar_t** endptr, int base); /// -c_ulong wcstoul(in wchar_t* nptr, wchar_t** endptr, int base); +c_ulong wcstoul(const scope wchar_t* nptr, wchar_t** endptr, int base); /// -ulong wcstoull(in wchar_t* nptr, wchar_t** endptr, int base); +ulong wcstoull(const scope wchar_t* nptr, wchar_t** endptr, int base); /// pure wchar_t* wcscpy(return wchar_t* s1, scope const wchar_t* s2); @@ -263,7 +245,7 @@ wchar_t* wcstok(return wchar_t* s1, scope const wchar_t* s2, wchar_t** ptr); pure size_t wcslen(scope const wchar_t* s); /// -pure wchar_t* wmemchr(return const wchar_t* s, wchar_t c, size_t n); +pure inout(wchar_t)* wmemchr(return inout wchar_t* s, wchar_t c, size_t n); /// pure int wmemcmp(scope const wchar_t* s1, scope const wchar_t* s2, size_t n); /// @@ -274,7 +256,7 @@ pure wchar_t* wmemmove(return wchar_t* s1, scope const wchar_t* s2, size_t n); pure wchar_t* wmemset(return wchar_t* s, wchar_t c, size_t n); /// -size_t wcsftime(wchar_t* s, size_t maxsize, in wchar_t* format, in tm* timeptr); +size_t wcsftime(wchar_t* s, size_t maxsize, const scope wchar_t* format, const scope tm* timeptr); version (Windows) { @@ -298,14 +280,14 @@ version (Windows) } /// -int mbsinit(in mbstate_t* ps); +int mbsinit(const scope mbstate_t* ps); /// -size_t mbrlen(in char* s, size_t n, mbstate_t* ps); +size_t mbrlen(const scope char* s, size_t n, mbstate_t* ps); /// -size_t mbrtowc(wchar_t* pwc, in char* s, size_t n, mbstate_t* ps); +size_t mbrtowc(wchar_t* pwc, const scope char* s, size_t n, mbstate_t* ps); /// size_t wcrtomb(char* s, wchar_t wc, mbstate_t* ps); /// -size_t mbsrtowcs(wchar_t* dst, in char** src, size_t len, mbstate_t* ps); +size_t mbsrtowcs(wchar_t* dst, const scope char** src, size_t len, mbstate_t* ps); /// -size_t wcsrtombs(char* dst, in wchar_t** src, size_t len, mbstate_t* ps); +size_t wcsrtombs(char* dst, const scope wchar_t** src, size_t len, mbstate_t* ps); diff --git a/libphobos/libdruntime/core/stdc/wctype.d b/libphobos/libdruntime/core/stdc/wctype.d index b0c81079a7a..b37e8322dc3 100644 --- a/libphobos/libdruntime/core/stdc/wctype.d +++ b/libphobos/libdruntime/core/stdc/wctype.d @@ -54,7 +54,7 @@ pure int iswxdigit(wint_t wc); /// int iswctype(wint_t wc, wctype_t desc); /// -@system wctype_t wctype(in char* property); +@system wctype_t wctype(const scope char* property); /// pure wint_t towlower(wint_t wc); /// @@ -62,4 +62,4 @@ pure wint_t towupper(wint_t wc); /// wint_t towctrans(wint_t wc, wctrans_t desc); /// -@system wctrans_t wctrans(in char* property); +@system wctrans_t wctrans(const scope char* property); diff --git a/libphobos/libdruntime/core/sys/bionic/err.d b/libphobos/libdruntime/core/sys/bionic/err.d new file mode 100644 index 00000000000..e2756e10c91 --- /dev/null +++ b/libphobos/libdruntime/core/sys/bionic/err.d @@ -0,0 +1,23 @@ +/** + * D header file for Bionic err.h. + * + * Copyright: Copyright © 2019, The D Language Foundation + * License: Boost License 1.0. + * Authors: Ernesto Castellotti + */ +module core.sys.bionic.err; +import core.stdc.stdarg : va_list; + +version (CRuntime_Bionic): +extern (C): +nothrow: +@nogc: + +void err(int eval, scope const char* fmt, ...); +void errx(int eval, scope const char* fmt, ...); +void warn(scope const char* fmt, ...); +void warnx(scope const char* fmt, ...); +void verr(int eval, scope const char* fmt, va_list args); +void verrx(int eval, scope const char* fmt, va_list args); +void vwarn(scope const char* fmt, va_list args); +void vwarnx(scope const char* fmt, va_list args); diff --git a/libphobos/libdruntime/core/sys/darwin/dlfcn.d b/libphobos/libdruntime/core/sys/darwin/dlfcn.d index c22424f3b7b..a38d9009e9d 100644 --- a/libphobos/libdruntime/core/sys/darwin/dlfcn.d +++ b/libphobos/libdruntime/core/sys/darwin/dlfcn.d @@ -33,7 +33,7 @@ struct Dl_info void* dli_saddr; } -int dladdr(in void* addr, Dl_info* info); +int dladdr(const scope void* addr, Dl_info* info); enum RTLD_NOLOAD = 0x10; enum RTLD_NODELETE = 0x80; diff --git a/libphobos/libdruntime/core/sys/darwin/err.d b/libphobos/libdruntime/core/sys/darwin/err.d new file mode 100644 index 00000000000..d96c790f3b6 --- /dev/null +++ b/libphobos/libdruntime/core/sys/darwin/err.d @@ -0,0 +1,41 @@ +/** + * D header file for Darwin err.h. + * + * Copyright: Copyright © 2019, The D Language Foundation + * License: Boost License 1.0. + * Authors: Ernesto Castellotti + */ +module core.sys.darwin.err; +import core.stdc.stdarg : va_list; + +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + + +version (Darwin): +extern (C): +nothrow: +@nogc: + +alias ExitFunction = void function(int); + +void err(int eval, scope const char* fmt, ...); +void errc(int eval, int code, scope const char* fmt, ...); +void errx(int eval, scope const char* fmt, ...); +void warn(scope const char* fmt, ...); +void warnc(int code, scope const char* fmt, ...); +void warnx(scope const char* fmt, ...); +void verr(int eval, scope const char* fmt, va_list args); +void verrc(int eval, int code, scope const char* fmt, va_list args); +void verrx(int eval, scope const char* fmt, va_list args); +void vwarn(scope const char* fmt, va_list args); +void vwarnc(int code, scope const char* fmt, va_list args); +void vwarnx(scope const char* fmt, va_list args); +void err_set_file(void* vfp); +void err_set_exit(ExitFunction exitf); diff --git a/libphobos/libdruntime/core/sys/darwin/ifaddrs.d b/libphobos/libdruntime/core/sys/darwin/ifaddrs.d new file mode 100644 index 00000000000..a2540361d0f --- /dev/null +++ b/libphobos/libdruntime/core/sys/darwin/ifaddrs.d @@ -0,0 +1,77 @@ +/******************************************************************************* + + Binding for Mac OSX's , expose network interface addresses + + The following functions are present as of Mac OSX 10.15: + - getifaddrs(3): get interface addresses + - freeifaddrs(3): deallocates the return value of `getifaddrs` + - getifmaddrs(3): get multicast group membership + - freeifmaddrs(3): deallocates the return value of `getifmaddrs` + + Copyright: Copyright © 2020, The D Language Foundation + License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). + Authors: Daniel Graczer + +*******************************************************************************/ + +module core.sys.darwin.ifaddrs; + +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + +version (Darwin): +extern (C): +nothrow: +@nogc: +@system: + +import core.sys.posix.sys.socket; + +/// +struct ifaddrs +{ + /// Next item in the list + ifaddrs* ifa_next; + /// Name of the interface + char* ifa_name; + /// Flags from SIOCGIFFLAGS + uint ifa_flags; + /// Address of interface + sockaddr* ifa_addr; + /// Netmask of interface + sockaddr* ifa_netmask; + /// Point-to-point destination addresss + sockaddr* if_dstaddr; + /// Address specific data + void* ifa_data; +} + +/// Returns: linked list of ifaddrs structures describing interfaces +int getifaddrs(ifaddrs**); +/// Frees the linked list returned by getifaddrs +void freeifaddrs(ifaddrs*); + +/// +struct ifmaddrs +{ + /// Pointer to next struct + ifmaddrs* ifma_next; + /// Interface name (AF_LINK) + sockaddr* ifma_name; + /// Multicast address + sockaddr* ifma_addr; + /// Link-layer translation, if any + sockaddr* ifma_lladdr; +} + +/// Stores a reference to a linked list of the multicast memberships +/// on the local machine in the memory referenced by ifmaddrs +int getifmaddrs(ifmaddrs**); +/// Frees the list allocated by getifmaddrs +void freeifmaddrs(ifmaddrs*); diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d index 5bf5609a203..62d1a779262 100644 --- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d +++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d @@ -33,7 +33,7 @@ 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)); +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)); diff --git a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d index cf89747d0f2..fd1a8e4ea36 100644 --- a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d +++ b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d @@ -44,7 +44,7 @@ version (CoreDdoc) * Returns the section data of the given section in the given segment in the * mach executable it is linked into. * - * ___ + * --- * void main() * { * import core.sys.darwin.mach.getsect; @@ -52,7 +52,7 @@ version (CoreDdoc) * assert(getsectdata("__TEXT", "__text", &size)); * assert(size > 0); * } - * ___ + * --- * * Params: * segname = the name of the segment @@ -63,8 +63,8 @@ version (CoreDdoc) * Returns: a pointer to the section data or `null` if it doesn't exist */ char* getsectdata( - in char* segname, - in char* sectname, + const scope char* segname, + const scope char* sectname, c_ulong *size ); @@ -74,7 +74,7 @@ version (CoreDdoc) * Returns the section data of the given section in the given segment in the * given framework. * - * ___ + * --- * void main() * { * import core.sys.darwin.mach.getsect; @@ -82,7 +82,7 @@ version (CoreDdoc) * assert(getsectdatafromFramework("Foundation", "__TEXT", "__text", &size)); * assert(size > 0); * } - * ___ + * --- * * Params: * FrameworkName = the name of the framework to get the section data from @@ -94,9 +94,9 @@ version (CoreDdoc) * Returns: a pointer to the section data or `null` if it doesn't exist */ char* getsectdatafromFramework( - in char* FrameworkName, - in char* segname, - in char* sectname, + const scope char* FrameworkName, + const scope char* segname, + const scope char* sectname, c_ulong* size ); @@ -115,13 +115,13 @@ version (CoreDdoc) * Returns the section structure of the given section in the given segment * in the mach executable it is linked into. * - * ___ + * --- * void main() * { * import core.sys.darwin.mach.getsect; * assert(getsectbyname("__TEXT", "__text")); * } - * ___ + * --- * * Params: * segname = the name of the segment @@ -130,8 +130,8 @@ version (CoreDdoc) * Returns: a pointer to the section structure or `null` if it doesn't exist */ const(Section)* getsectbyname( - in char* segname, - in char* sectname + const scope char* segname, + const scope char* sectname ); /** @@ -140,7 +140,7 @@ version (CoreDdoc) * Returns the section data of the given section in the given segment in the * image pointed to by the given mach header. * - * ___ + * --- * void main() * { * import core.sys.darwin.mach.getsect; @@ -151,7 +151,7 @@ version (CoreDdoc) * assert(getsectdata(mph, "__TEXT", "__text", &size)); * assert(size > 0); * } - * ___ + * --- * * Params: * mhp = the mach header to get the section data from @@ -163,9 +163,9 @@ version (CoreDdoc) * Returns: a pointer to the section data or `null` if it doesn't exist */ ubyte* getsectiondata( - in MachHeader* mhp, - in char* segname, - in char* sectname, + const scope MachHeader* mhp, + const scope char* segname, + const scope char* sectname, c_ulong* size ); @@ -175,13 +175,13 @@ version (CoreDdoc) * Returns the segment structure of the given segment in the mach executable * it is linked into. * - * ___ + * --- * void main() * { * import core.sys.darwin.mach.getsect; * assert(getsegbyname("__TEXT")); * } - * ___ + * --- * * Params: * segname = the name of the segment @@ -189,7 +189,7 @@ version (CoreDdoc) * Returns: a pointer to the section structure or `null` if it doesn't exist */ const(SegmentCommand)* getsegbyname( - in char* segname + const scope char* segname ); /** @@ -198,7 +198,7 @@ version (CoreDdoc) * Returns the segment data of the given segment in the image pointed to by * the given mach header. * - * ___ + * --- * void main() * { * import core.sys.darwin.mach.getsect; @@ -209,7 +209,7 @@ version (CoreDdoc) * assert(getsegmentdata(mph, "__TEXT", &size)); * assert(size > 0); * } - * ___ + * --- * * Params: * mhp = the mach header to get the section data from @@ -220,8 +220,8 @@ version (CoreDdoc) * Returns: a pointer to the section data or `null` if it doesn't exist */ ubyte* getsegmentdata( - in MachHeader* mhp, - in char* segname, + const scope MachHeader* mhp, + const scope char* segname, c_ulong* size ); @@ -236,7 +236,7 @@ version (CoreDdoc) * Returns the section data of the given section in the given segment in the * image pointed to by the given mach header. * - * ___ + * --- * void main() * { * import core.sys.darwin.mach.getsect; @@ -247,7 +247,7 @@ version (CoreDdoc) * assert(getsectdatafromheader(mph, "__TEXT", "__text", &size)); * assert(size > 0); * } - * ___ + * --- * * Params: * mhp = the mach header to get the section data from @@ -259,17 +259,17 @@ version (CoreDdoc) * Returns: a pointer to the section data or `null` if it doesn't exist */ ubyte* getsectdatafromheader( - in mach_header* mhp, - in char* segname, - in char* sectname, + const scope mach_header* mhp, + const scope char* segname, + const scope char* sectname, c_ulong* size ); /// ditto ubyte* getsectdatafromheader_64( - in mach_header_64* mhp, - in char* segname, - in char* sectname, + const scope mach_header_64* mhp, + const scope char* segname, + const scope char* sectname, c_ulong* size ); @@ -280,7 +280,7 @@ version (CoreDdoc) * Returns the section structure of the given section in the given segment * in image pointed to by the given mach header. * - * ___ + * --- * void main() * { * import core.sys.darwin.mach.getsect; @@ -289,7 +289,7 @@ version (CoreDdoc) * auto mph = _NSGetMachExecuteHeader(); * assert(getsectbynamefromheader(mph, "__TEXT", "__text")); * } - * ___ + * --- * * Params: * mhp = the mach header to get the section from @@ -299,16 +299,16 @@ version (CoreDdoc) * Returns: a pointer to the section structure or `null` if it doesn't exist */ const(section)* getsectbynamefromheader( - in mach_header* mhp, - in char* segname, - in char* sectname + const scope mach_header* mhp, + const scope char* segname, + const scope char* sectname ); /// ditto const(section_64)* getsectbynamefromheader_64( - in mach_header_64* mhp, - in char* segname, - in char* sectname + const scope mach_header_64* mhp, + const scope char* segname, + const scope char* sectname ); /** @@ -326,17 +326,17 @@ version (CoreDdoc) * Returns: a pointer to the section structure or `null` if it doesn't exist */ const(section)* getsectbynamefromheaderwithswap( - in mach_header* mhp, - in char* segname, - in char* section, + const scope mach_header* mhp, + const scope char* segname, + const scope char* section, int fSwap ); /// ditto const(section)* getsectbynamefromheaderwithswap_64( - in mach_header_64* mhp, - in char* segname, - in char* section, + const scope mach_header_64* mhp, + const scope char* segname, + const scope char* section, int fSwap ); } @@ -357,15 +357,15 @@ public import core.sys.darwin.mach.loader; import core.stdc.config : c_ulong; char* getsectdata( - in char* segname, - in char* sectname, + const scope char* segname, + const scope char* sectname, c_ulong *size ); char* getsectdatafromFramework( - in char* FrameworkName, - in char* segname, - in char* sectname, + const scope char* FrameworkName, + const scope char* segname, + const scope char* sectname, c_ulong* size ); @@ -377,24 +377,24 @@ c_ulong get_edata(); version (D_LP64) { const(section_64)* getsectbyname( - in char* segname, - in char* sectname + const scope char* segname, + const scope char* sectname ); ubyte* getsectiondata( - in mach_header_64* mhp, - in char* segname, - in char* sectname, + const scope mach_header_64* mhp, + const scope char* segname, + const scope char* sectname, c_ulong* size ); const(segment_command_64)* getsegbyname( - in char* segname + const scope char* segname ); ubyte* getsegmentdata( - in mach_header_64* mhp, - in char* segname, + const scope mach_header_64* mhp, + const scope char* segname, c_ulong* size ); } @@ -403,24 +403,24 @@ version (D_LP64) else { const(section)* getsectbyname( - in char* segname, - in char* sectname + const scope char* segname, + const scope char* sectname ); ubyte* getsectiondata( - in mach_header* mhp, - in char* segname, - in char* sectname, + const scope mach_header* mhp, + const scope char* segname, + const scope char* sectname, c_ulong* size ); const(segment_command)* getsegbyname( - in char* segname + const scope char* segname ); ubyte* getsegmentdata( - in mach_header* mhp, - in char* segname, + const scope mach_header* mhp, + const scope char* segname, c_ulong* size ); } @@ -428,44 +428,44 @@ else // Interfaces for tools working with 32-bit Mach-O files. ubyte* getsectdatafromheader( - in mach_header* mhp, - in char* segname, - in char* sectname, + const scope mach_header* mhp, + const scope char* segname, + const scope char* sectname, c_ulong* size ); const(section)* getsectbynamefromheader( - in mach_header* mhp, - in char* segname, - in char* sectname + const scope mach_header* mhp, + const scope char* segname, + const scope char* sectname ); const(section)* getsectbynamefromheaderwithswap( - in mach_header* mhp, - in char* segname, - in char* section, + const scope mach_header* mhp, + const scope char* segname, + const scope char* section, int fSwap ); // Interfaces for tools working with 64-bit Mach-O files. ubyte* getsectdatafromheader_64( - in mach_header_64* mhp, - in char* segname, - in char* sectname, + const scope mach_header_64* mhp, + const scope char* segname, + const scope char* sectname, c_ulong* size ); const(section_64)* getsectbynamefromheader_64( - in mach_header_64* mhp, - in char* segname, - in char* sectname + const scope mach_header_64* mhp, + const scope char* segname, + const scope char* sectname ); const(section)* getsectbynamefromheaderwithswap_64( - in mach_header_64* mhp, - in char* segname, - in char* section, + const scope mach_header_64* mhp, + const scope char* segname, + const scope char* section, int fSwap ); diff --git a/libphobos/libdruntime/core/sys/darwin/mach/loader.d b/libphobos/libdruntime/core/sys/darwin/mach/loader.d index af42485fd83..f46698c3b53 100644 --- a/libphobos/libdruntime/core/sys/darwin/mach/loader.d +++ b/libphobos/libdruntime/core/sys/darwin/mach/loader.d @@ -2568,14 +2568,7 @@ version (CoreDdoc) ulong size; } } - -else version (OSX) - version = Darwin; -else version (iOS) - version = Darwin; -else version (TVOS) - version = Darwin; -else version (WatchOS) +else version = Darwin; version (Darwin): @@ -3116,12 +3109,8 @@ struct dylib_reference } @property void isym()(uint v) @safe pure nothrow @nogc - in - { - assert(v >= 0U, "Value is smaller than the minimum value of bitfield 'isym'"); - assert(v <= 16777215U, "Value is greater than the maximum value of bitfield 'isym'"); - } - body + in(v >= 0U, "Value is smaller than the minimum value of bitfield 'isym'") + in(v <= 16777215U, "Value is greater than the maximum value of bitfield 'isym'") { storage = cast(uint) ((storage & (-1 - cast(uint) 16777215U)) | ((cast(uint) v << 0U) & 16777215U)); @@ -3133,12 +3122,8 @@ struct dylib_reference } @property void flags()(uint v) pure nothrow @nogc @safe - in - { - assert(v >= 0U, "Value is smaller than the minimum value of bitfield 'flags'"); - assert(v <= 255U, "Value is greater than the maximum value of bitfield 'flags'"); - } - body + in(v >= 0U, "Value is smaller than the minimum value of bitfield 'flags'") + in(v <= 255U, "Value is greater than the maximum value of bitfield 'flags'") { storage = cast(uint) ((storage & (-1 - cast(uint) 4278190080U)) | ((cast(uint) v << 24U) & 4278190080U)); @@ -3163,12 +3148,8 @@ struct twolevel_hint } @property void isub_image()(uint v) pure nothrow @nogc @safe - in - { - assert(v >= 0U, "Value is smaller than the minimum value of bitfield 'isub_image'"); - assert(v <= 255U, "Value is greater than the maximum value of bitfield 'isub_image'"); - } - body + in(v >= 0U, "Value is smaller than the minimum value of bitfield 'isub_image'") + in(v <= 255U, "Value is greater than the maximum value of bitfield 'isub_image'") { storage = cast(uint) ((storage & (-1-cast(uint)255U)) | ((cast(uint) v << 0U) & 255U)); @@ -3180,12 +3161,8 @@ struct twolevel_hint } @property void itoc()(uint v) pure nothrow @nogc @safe - in - { - assert(v >= 0U, "Value is smaller than the minimum value of bitfield 'itoc'"); - assert(v <= 16777215U, "Value is greater than the maximum value of bitfield 'itoc'"); - } - body + in(v >= 0U, "Value is smaller than the minimum value of bitfield 'itoc'") + in(v <= 16777215U, "Value is greater than the maximum value of bitfield 'itoc'") { storage = cast(uint) ((storage & (-1-cast(uint)4294967040U)) | ((cast(uint) v << 8U) & 4294967040U)); diff --git a/libphobos/libdruntime/core/sys/darwin/mach/nlist.d b/libphobos/libdruntime/core/sys/darwin/mach/nlist.d new file mode 100644 index 00000000000..11e5ced26b7 --- /dev/null +++ b/libphobos/libdruntime/core/sys/darwin/mach/nlist.d @@ -0,0 +1,317 @@ +/** + * Bindings for symbols and defines in `mach-o/nlist.h` + * + * This file was created based on the MacOSX 10.15 SDK. + * + * Copyright: + * D Language Foundation 2020 + * Some documentation was extracted from the C headers + * and is the property of Apple Inc. + * + * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). + * Authors: Mathias 'Geod24' Lang + * Source: $(DRUNTIMESRC core/sys/darwin/mach/_nlist.d) + */ +module core.sys.darwin.mach.nlist; + +import core.stdc.config; + +extern(C): +nothrow: +@nogc: +pure: + +/** + * An entry in a list of symbols for 64-bits architectures + * + * Said symbols can be used to describe many different type of data, + * including STABS debug infos. Introduced in MacOSX 10.8 SDK. + * + * See_Also: + * https://developer.apple.com/documentation/kernel/nlist_64 + */ +struct nlist_64 +{ + /// Compatibility alias, as `n_strx` is in an union in C code + alias n_un = n_strx; + + /** + * Index of this symbol's name into the string table + * + * All names are stored as NUL-terminated strings into the string table. + * For historical reason, the very first entry into the string table is `0`, + * hence all non-NULL names have an index > 0. + */ + uint n_strx; + + /** + * A bitfield that describes the type of this symbol + * + * In reality, this describes 4 fields: + * - N_STAB (top 3 bits) + * - N_PEXT (next 1 bit) + * - N_TYPE (next 3 bits) + * - N_EXT (last 1 bit) + * + * The enum values `N_STAB`, `N_PEXT`, `N_TYPE`, and `N_EXT` should be used + * as masks to check which type this `nlist_64` actually is. + */ + ubyte n_type; + /// Section number (note that `0` means `NO_SECT`) + ubyte n_sect; + /* see */ + ushort n_desc; + /* value of this symbol (or stab offset) */ + ulong n_value; + // Note: `n_value` *is* `uint64_t`, not `c_ulong` ! +} + +/// Mask to use with `nlist_64.n_type` to check what the entry describes +enum +{ + /** + * If any of these bits set, a symbolic debugging entry + * + * Only symbolic debugging entries have some of the N_STAB bits set and if any + * of these bits are set then it is a symbolic debugging entry (a stab). In + * which case then the values of the n_type field (the entire field) are given + * in + */ + N_STAB = 0xe0, + /// Private external symbol bit + N_PEXT = 0x10, + /// Mask for the type bits + N_TYPE = 0x0e, /* mask for the type bits */ + /// External symbol bit, set for external symbols + N_EXT = 0x01, +} + +/// Values for `NTypeMask.N_TYPE` bits of the `nlist_64.n_type` field. +enum +{ + /// Undefined (`n_sect == NO_SECT`) + N_UNDF = 0x0, + /// Absolute (`n_sect == NO_SECT`) + N_ABS = 0x2, + /// Defined in section number `nlist_64.n_sect` + N_SECT = 0xe, + /// Prebound undefined (defined in a dylib) + N_PBUD = 0xc, + /** + * Indirect symbol + * + * If the type is `N_INDR` then the symbol is defined to be the same as + * another symbol. In this case the `n_value` field is an index into + * the string table of the other symbol's name. When the other symbol + * is defined then they both take on the defined type and value. + */ + N_INDR = 0xa, +} + +/** + * Symbol is not in any section + * + * If the type is N_SECT then the n_sect field contains an ordinal of the + * section the symbol is defined in. The sections are numbered from 1 and + * refer to sections in order they appear in the load commands for the file + * they are in. This means the same ordinal may very well refer to different + * sections in different files. + * + * The n_value field for all symbol table entries (including N_STAB's) gets + * updated by the link editor based on the value of it's n_sect field and where + * the section n_sect references gets relocated. If the value of the n_sect + * field is NO_SECT then it's n_value field is not changed by the link editor. + */ +enum NO_SECT = 0; + +/// Maximum number of sections: 1 thru 255 inclusive +enum MAX_SECT = 255; + +/** + * Common symbols are represented by undefined (N_UNDF) external (N_EXT) types + * who's values (n_value) are non-zero. In which case the value of the n_value + * field is the size (in bytes) of the common symbol. The n_sect field is set + * to NO_SECT. The alignment of a common symbol may be set as a power of 2 + * between 2^1 and 2^15 as part of the n_desc field using the macros below. If + * the alignment is not set (a value of zero) then natural alignment based on + * the size is used. + */ +extern(D) ubyte GET_COMM_ALIGN(uint n_desc) @safe +{ + return (((n_desc) >> 8) & 0x0f); +} + +/// Ditto +extern(D) ref ushort SET_COMM_ALIGN(return ref ushort n_desc, size_t wanted_align) @safe +{ + return n_desc = (((n_desc) & 0xf0ff) | (((wanted_align) & 0x0f) << 8)); +} + +/** + * To support the lazy binding of undefined symbols in the dynamic link-editor, + * the undefined symbols in the symbol table (the nlist structures) are marked + * with the indication if the undefined reference is a lazy reference or + * non-lazy reference. If both a non-lazy reference and a lazy reference is + * made to the same symbol the non-lazy reference takes precedence. A reference + * is lazy only when all references to that symbol are made through a symbol + * pointer in a lazy symbol pointer section. + * + * The implementation of marking nlist structures in the symbol table for + * undefined symbols will be to use some of the bits of the n_desc field as a + * reference type. The mask REFERENCE_TYPE will be applied to the n_desc field + * of an nlist structure for an undefined symbol to determine the type of + * undefined reference (lazy or non-lazy). + * + * The constants for the REFERENCE FLAGS are propagated to the reference table + * in a shared library file. In that case the constant for a defined symbol, + * REFERENCE_FLAG_DEFINED, is also used. + */ +enum +{ + /// Reference type bits of the n_desc field of undefined symbols + REFERENCE_TYPE = 0x7, + + /// types of references + REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0, + /// Ditto + REFERENCE_FLAG_UNDEFINED_LAZY = 1, + /// Ditto + REFERENCE_FLAG_DEFINED = 2, + /// Ditto + REFERENCE_FLAG_PRIVATE_DEFINED = 3, + /// Ditto + REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4, + /// Ditto + REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5, + + /** + * To simplify stripping of objects that use are used with the dynamic link + * editor, the static link editor marks the symbols defined an object that are + * referenced by a dynamicly bound object (dynamic shared libraries, bundles). + * With this marking strip knows not to strip these symbols. + */ + REFERENCED_DYNAMICALLY = 0x0010, +} + +/** + * For images created by the static link editor with the -twolevel_namespace + * option in effect the flags field of the mach header is marked with + * MH_TWOLEVEL. And the binding of the undefined references of the image are + * determined by the static link editor. Which library an undefined symbol is + * bound to is recorded by the static linker in the high 8 bits of the n_desc + * field using the SET_LIBRARY_ORDINAL macro below. The ordinal recorded + * references the libraries listed in the Mach-O's LC_LOAD_DYLIB, + * LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_LOAD_UPWARD_DYLIB, and + * LC_LAZY_LOAD_DYLIB, etc. load commands in the order they appear in the + * headers. The library ordinals start from 1. + * For a dynamic library that is built as a two-level namespace image the + * undefined references from module defined in another use the same nlist struct + * an in that case SELF_LIBRARY_ORDINAL is used as the library ordinal. For + * defined symbols in all images they also must have the library ordinal set to + * SELF_LIBRARY_ORDINAL. The EXECUTABLE_ORDINAL refers to the executable + * image for references from plugins that refer to the executable that loads + * them. + * + * The DYNAMIC_LOOKUP_ORDINAL is for undefined symbols in a two-level namespace + * image that are looked up by the dynamic linker with flat namespace semantics. + * This ordinal was added as a feature in Mac OS X 10.3 by reducing the + * value of MAX_LIBRARY_ORDINAL by one. So it is legal for existing binaries + * or binaries built with older tools to have 0xfe (254) dynamic libraries. In + * this case the ordinal value 0xfe (254) must be treated as a library ordinal + * for compatibility. + */ +ubyte GET_LIBRARY_ORDINAL(uint n_desc) @safe { return ((n_desc) >> 8) & 0xff; } +/// Ditto +ref ushort SET_LIBRARY_ORDINAL(return scope ref ushort n_desc, uint ordinal) @safe +{ + return n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8)); +} + +/// Ditto +enum +{ + SELF_LIBRARY_ORDINAL = 0x00, + MAX_LIBRARY_ORDINAL = 0xfd, + DYNAMIC_LOOKUP_ORDINAL = 0xfe, + EXECUTABLE_ORDINAL = 0xff, +} + +/** + * The bit 0x0020 of the n_desc field is used for two non-overlapping purposes + * and has two different symbolic names, N_NO_DEAD_STRIP and N_DESC_DISCARDED. + */ +enum +{ + /** + * Symbol is not to be dead stripped + * + * The N_NO_DEAD_STRIP bit of the n_desc field only ever appears in a + * relocatable .o file (MH_OBJECT filetype). And is used to indicate to the + * static link editor it is never to dead strip the symbol. + */ + N_NO_DEAD_STRIP = 0x0020, + + /** + * Symbol is discarded + * + * The N_DESC_DISCARDED bit of the n_desc field never appears in linked image. + * But is used in very rare cases by the dynamic link editor to mark an in + * memory symbol as discared and longer used for linking. + */ + N_DESC_DISCARDED =0x0020, + + /** + * Symbol is weak referenced + * + * The N_WEAK_REF bit of the n_desc field indicates to the dynamic linker that + * the undefined symbol is allowed to be missing and is to have the address of + * zero when missing. + */ + N_WEAK_REF = 0x0040, + + /** + * Coalesed symbol is a weak definition + * + * The N_WEAK_DEF bit of the n_desc field indicates to the static and dynamic + * linkers that the symbol definition is weak, allowing a non-weak symbol to + * also be used which causes the weak definition to be discared. Currently this + * is only supported for symbols in coalesed sections. + */ + N_WEAK_DEF = 0x0080, + + /** + * Reference to a weak symbol + * + * The N_REF_TO_WEAK bit of the n_desc field indicates to the dynamic linker + * that the undefined symbol should be resolved using flat namespace searching. + */ + N_REF_TO_WEAK = 0x0080, + + /** + * Symbol is a Thumb function (ARM) + * + * The N_ARM_THUMB_DEF bit of the n_desc field indicates that the symbol is + * a defintion of a Thumb function. + */ + N_ARM_THUMB_DEF = 0x0008, + + /** + * The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the + * that the function is actually a resolver function and should + * be called to get the address of the real function to use. + * This bit is only available in .o files (MH_OBJECT filetype) + */ + N_SYMBOL_RESOLVER = 0x0100, + + /** + * The N_ALT_ENTRY bit of the n_desc field indicates that the + * symbol is pinned to the previous content. + */ + N_ALT_ENTRY = 0x0200, + + /** + * The N_COLD_FUNC bit of the n_desc field indicates that the symbol is used + * infrequently and the linker should order it towards the end of the section. + */ + N_COLD_FUNC = 0x0400, +} diff --git a/libphobos/libdruntime/core/sys/darwin/mach/stab.d b/libphobos/libdruntime/core/sys/darwin/mach/stab.d new file mode 100644 index 00000000000..ecdb4560a68 --- /dev/null +++ b/libphobos/libdruntime/core/sys/darwin/mach/stab.d @@ -0,0 +1,90 @@ +/** + * Bindings for symbols and defines in `mach-o/stab.h` + * + * This file gives definitions supplementing for permanent symbol + * table entries of Mach-O files. Modified from the BSD definitions. The + * modifications from the original definitions were changing what the values of + * what was the n_other field (an unused field) which is now the n_sect field. + * These modifications are required to support symbols in an arbitrary number of + * sections not just the three sections (text, data and bss) in a BSD file. + * The values of the defined constants have NOT been changed. + * + * These must have one of the N_STAB bits on. The n_value fields are subject + * to relocation according to the value of their n_sect field. So for types + * that refer to things in sections the n_sect field must be filled in with the + * proper section ordinal. For types that are not to have their n_value field + * relocatated the n_sect field must be NO_SECT. + * + * This file was created based on the MacOSX 10.15 SDK. + * + * Copyright: + * D Language Foundation 2020 + * Some documentation was extracted from the C headers + * and is the property of Apple Inc. + * + * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). + * Authors: Mathias 'Geod24' Lang + * Source: $(DRUNTIMESRC core/sys/darwin/mach/_nlist.d) + */ +module core.sys.darwin.mach.stab; + +extern(C): +nothrow: +@nogc: +pure: + +/** + * Symbolic debugger symbols. + * + * The comments give the conventional use for + * ``` + * .stabs "n_name", n_type, n_sect, n_desc, n_value + * ``` + * + * where n_type is the defined constant and not listed in the comment. Other + * fields not listed are zero. n_sect is the section ordinal the entry is + * refering to. + */ +enum +{ + N_GSYM = 0x20, /// global symbol: name,,NO_SECT,type,0 + N_FNAME = 0x22, /// procedure name (f77 kludge): name,,NO_SECT,0,0 + N_FUN = 0x24, /// procedure: name,,n_sect,linenumber,address + N_STSYM = 0x26, /// static symbol: name,,n_sect,type,address + N_LCSYM = 0x28, /// .lcomm symbol: name,,n_sect,type,address + N_BNSYM = 0x2e, /// begin nsect sym: 0,,n_sect,0,address + N_AST = 0x32, /// AST file path: name,,NO_SECT,0,0 + N_OPT = 0x3c, /// emitted with gcc2_compiled and in gcc source + N_RSYM = 0x40, /// register sym: name,,NO_SECT,type,register + N_SLINE = 0x44, /// src line: 0,,n_sect,linenumber,address + N_ENSYM = 0x4e, /// end nsect sym: 0,,n_sect,0,address + N_SSYM = 0x60, /// structure elt: name,,NO_SECT,type,struct_offset + N_SO = 0x64, /// source file name: name,,n_sect,0,address + /** + * Object file name: name,,(see below),0,st_mtime + * + * Historically N_OSO set n_sect to 0. + * The N_OSO n_sect may instead hold the low byte of the cpusubtype value + * from the Mach-O header. + */ + N_OSO = 0x66, + N_LSYM = 0x80, /// local sym: name,,NO_SECT,type,offset + N_BINCL = 0x82, /// include file beginning: name,,NO_SECT,0,sum + N_SOL = 0x84, /// #included file name: name,,n_sect,0,address + N_PARAMS = 0x86, /// compiler parameters: name,,NO_SECT,0,0 + N_VERSION = 0x88, /// compiler version: name,,NO_SECT,0,0 + N_OLEVEL = 0x8A, /// compiler -O level: name,,NO_SECT,0,0 + N_PSYM = 0xa0, /// parameter: name,,NO_SECT,type,offset + N_EINCL = 0xa2, /// include file end: name,,NO_SECT,0,0 + N_ENTRY = 0xa4, /// alternate entry: name,,n_sect,linenumber,address + N_LBRAC = 0xc0, /// left bracket: 0,,NO_SECT,nesting level,address + N_EXCL = 0xc2, /// deleted include file: name,,NO_SECT,0,sum + N_RBRAC = 0xe0, /// right bracket: 0,,NO_SECT,nesting level,address + N_BCOMM = 0xe2, /// begin common: name,,NO_SECT,0,0 + N_ECOMM = 0xe4, /// end common: name,,n_sect,0,0 + N_ECOML = 0xe8, /// end common (local name): 0,,n_sect,0,address + N_LENG = 0xfe, /// second stab entry with length information + + // For the berkeley pascal compiler, pc(1): + N_PC = 0x30, /// global pascal symbol: name,,NO_SECT,subtype,line +} diff --git a/libphobos/libdruntime/core/sys/darwin/netinet/in_.d b/libphobos/libdruntime/core/sys/darwin/netinet/in_.d index 0653d3a4b59..b850e3c98cf 100644 --- a/libphobos/libdruntime/core/sys/darwin/netinet/in_.d +++ b/libphobos/libdruntime/core/sys/darwin/netinet/in_.d @@ -225,7 +225,7 @@ static if (_DARWIN_C_SOURCE) { in_addr ip_dst; char[40] ip_opts = 0; - }; + } enum IP_OPTIONS = 1; enum IP_HDRINCL = 2; @@ -307,14 +307,14 @@ static if (_DARWIN_C_SOURCE) { in_addr imr_multiaddr; in_addr imr_interface; - }; + } struct ip_mreqn { in_addr imr_multiaddr; in_addr imr_address; int imr_ifindex; - }; + } struct ip_mreq_source { @@ -322,14 +322,14 @@ static if (_DARWIN_C_SOURCE) in_addr imr_multiaddr; in_addr imr_sourceaddr; in_addr imr_interface; - }; + } struct group_req { align(4): uint gr_interface; sockaddr_storage gr_group; - }; + } struct group_source_req { @@ -337,7 +337,7 @@ static if (_DARWIN_C_SOURCE) uint gsr_interface; sockaddr_storage gsr_group; sockaddr_storage gsr_source; - }; + } int setipv4sourcefilter(int, in_addr, in_addr, uint, uint, in_addr*); int getipv4sourcefilter(int, in_addr, in_addr, uint*, uint*, in_addr*); @@ -357,7 +357,7 @@ static if (_DARWIN_C_SOURCE) uint ipi_ifindex; in_addr ipi_spec_dst; in_addr ipi_addr; - }; + } enum IPPROTO_MAXID = IPPROTO_AH + 1; @@ -524,13 +524,13 @@ static if (_DARWIN_C_SOURCE) { in6_addr ipi6_addr; uint ipi6_ifindex; - }; + } struct ip6_mtuinfo { sockaddr_in6 ip6m_addr; uint ip6m_mtu; - }; + } enum IPV6_PORTRANGE_DEFAULT = 0; enum IPV6_PORTRANGE_HIGH = 1; diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d index 786d9f2833d..456cde96cbd 100644 --- a/libphobos/libdruntime/core/sys/darwin/pthread.d +++ b/libphobos/libdruntime/core/sys/darwin/pthread.d @@ -43,18 +43,18 @@ 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*); +int pthread_setname_np(const scope char*); // ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2) int pthread_main_np(); mach_port_t pthread_mach_thread_np(pthread_t); size_t pthread_get_stacksize_np(pthread_t); void* pthread_get_stackaddr_np(pthread_t); 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_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, in sigset_t*, sigset_t*); +int pthread_sigmask(int, const scope sigset_t*, sigset_t*); // ^ __DARWIN_ALIAS(pthread_sigmask) void pthread_yield_np(); diff --git a/libphobos/libdruntime/core/sys/darwin/sys/attr.d b/libphobos/libdruntime/core/sys/darwin/sys/attr.d new file mode 100644 index 00000000000..cb22b380ef6 --- /dev/null +++ b/libphobos/libdruntime/core/sys/darwin/sys/attr.d @@ -0,0 +1,338 @@ +/** + * D header file for Darwin + * + * $(LINK2 https://opensource.apple.com/source/xnu/xnu-2422.115.4/bsd/sys/attr.h.auto.html, Apple sys/attr.h) + */ +module core.sys.darwin.sys.attr; + +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + +version (Darwin): +extern (C): +nothrow: +@nogc: + +import core.internal.attributes : betterC; +import core.sys.darwin.sys.cdefs : c_ulong; +import core.sys.posix.sys.time : timeval; + +// These functions aren't actually declared in attr.h but in unistd.h. +@system +{ + void getattrlist(scope const char* path, scope attrlist* attrList, scope void* attrBuf, + size_t attrBufSize, c_ulong options); + + void setattrlist(scope const char* path, scope attrlist* attrList, scope void* attrBuf, + size_t attrBufSize, c_ulong options); + + version (TVOS) {} + else version (WatchOS) {} + else + int searchfs(scope const char* path, scope fssearchblock* searchBlock, + scope c_ulong* numMatches, uint scriptCode, uint options, scope searchstate* state); +} + +enum +{ + FSOPT_NOFOLLOW = 0x00000001, + FSOPT_NOINMEMUPDATE = 0x00000002, + FSOPT_REPORT_FULLSIZE = 0x00000004, + FSOPT_PACK_INVAL_ATTRS = 0x00000008, + FSOPT_ATTR_CMN_EXTENDED = 0x00000020, // macOS 10.10 +} + +enum SEARCHFS_MAX_SEARCHPARMS = 4096; + +alias uint text_encoding_t, fsobj_type_t, fsobj_tag_t, fsfile_type_t, fsvolid_t, attrgroup_t; + +struct attrlist +{ + ushort bitmapcount, reserved; + attrgroup_t commonattr, volattr, dirattr, fileattr, forkattr; +} +enum ATTR_BIT_MAP_COUNT = 5; + +struct attribute_set_t +{ + attrgroup_t commonattr, volattr, dirattr, fileattr, forkattr; +} + +struct attrreference_t +{ + int attr_dataoffset; + uint attr_length; +} + +struct diskextent +{ + uint startblock, blockcount; +} + +alias extentrecord = diskextent[8]; + +alias vol_capabilities_set_t = uint[4]; + +enum +{ + VOL_CAPABILITIES_FORMAT = 0, + VOL_CAPABILITIES_INTERFACES = 1, + VOL_CAPABILITIES_RESERVED1 = 2, + VOL_CAPABILITIES_RESERVED2 = 3, +} + +struct vol_capabilities_attr_t +{ + vol_capabilities_set_t capabilities, valid; +} + +enum ATTR_MAX_BUFFER = 8192; + +enum +{ + VOL_CAP_FMT_PERSISTENTOBJECTIDS = 0x00000001, + VOL_CAP_FMT_SYMBOLICLINKS = 0x00000002, + VOL_CAP_FMT_HARDLINKS = 0x00000004, + VOL_CAP_FMT_JOURNAL = 0x00000008, + VOL_CAP_FMT_JOURNAL_ACTIVE = 0x00000010, + VOL_CAP_FMT_NO_ROOT_TIMES = 0x00000020, + VOL_CAP_FMT_SPARSE_FILES = 0x00000040, + VOL_CAP_FMT_ZERO_RUNS = 0x00000080, + VOL_CAP_FMT_CASE_SENSITIVE = 0x00000100, + VOL_CAP_FMT_CASE_PRESERVING = 0x00000200, + VOL_CAP_FMT_FAST_STATFS = 0x00000400, + VOL_CAP_FMT_2TB_FILESIZE = 0x00000800, + VOL_CAP_FMT_OPENDENYMODES = 0x00001000, + VOL_CAP_FMT_HIDDEN_FILES = 0x00002000, + VOL_CAP_FMT_PATH_FROM_ID = 0x00004000, + VOL_CAP_FMT_NO_VOLUME_SIZES = 0x00008000, + VOL_CAP_FMT_DECMPFS_COMPRESSION = 0x00010000, + VOL_CAP_FMT_64BIT_OBJECT_IDS = 0x00020000, + VOL_CAP_FMT_DIR_HARDLINKS = 0x00040000, // macOS 10.12 + VOL_CAP_FMT_DOCUMENT_ID = 0x00080000, // macOS 10.12 + VOL_CAP_FMT_WRITE_GENERATION_COUNT = 0x00100000, // macOS 10.12 + VOL_CAP_FMT_NO_IMMUTABLE_FILES = 0x00200000, // macOS 10.12.4 + VOL_CAP_FMT_NO_PERMISSIONS = 0x00400000, // macOS 10.12.4 + VOL_CAP_FMT_SHARED_SPACE = 0x00800000, // macOS 10.15 + VOL_CAP_FMT_VOL_GROUPS = 0x01000000, // macOS 10.15 +} + +enum +{ + VOL_CAP_INT_SEARCHFS = 0x00000001, + VOL_CAP_INT_ATTRLIST = 0x00000002, + VOL_CAP_INT_NFSEXPORT = 0x00000004, + VOL_CAP_INT_READDIRATTR = 0x00000008, + VOL_CAP_INT_EXCHANGEDATA = 0x00000010, + VOL_CAP_INT_COPYFILE = 0x00000020, + VOL_CAP_INT_ALLOCATE = 0x00000040, + VOL_CAP_INT_VOL_RENAME = 0x00000080, + VOL_CAP_INT_ADVLOCK = 0x00000100, + VOL_CAP_INT_FLOCK = 0x00000200, + VOL_CAP_INT_EXTENDED_SECURITY = 0x00000400, + VOL_CAP_INT_USERACCESS = 0x00000800, + VOL_CAP_INT_MANLOCK = 0x00001000, + VOL_CAP_INT_NAMEDSTREAMS = 0x00002000, + VOL_CAP_INT_EXTENDED_ATTR = 0x00004000, + VOL_CAP_INT_CLONE = 0x00010000, // macOS 10.12 + VOL_CAP_INT_SNAPSHOT = 0x00020000, // macOS 10.12 + VOL_CAP_INT_RENAME_SWAP = 0x00040000, // macOS 10.12 + VOL_CAP_INT_RENAME_EXCL = 0x00080000, // macOS 10.12 + VOL_CAP_INT_RENAME_OPENFAIL = 0x00100000, // macOS 10.15 +} + +struct vol_attributes_attr_t +{ + attribute_set_t validattr, nativeattr; +} + +enum +{ + ATTR_CMN_NAME = 0x00000001, + ATTR_CMN_DEVID = 0x00000002, + ATTR_CMN_FSID = 0x00000004, + ATTR_CMN_OBJTYPE = 0x00000008, + ATTR_CMN_OBJTAG = 0x00000010, + ATTR_CMN_OBJID = 0x00000020, + ATTR_CMN_OBJPERMANENTID = 0x00000040, + ATTR_CMN_PAROBJID = 0x00000080, + ATTR_CMN_SCRIPT = 0x00000100, + ATTR_CMN_CRTIME = 0x00000200, + ATTR_CMN_MODTIME = 0x00000400, + ATTR_CMN_CHGTIME = 0x00000800, + ATTR_CMN_ACCTIME = 0x00001000, + ATTR_CMN_BKUPTIME = 0x00002000, + ATTR_CMN_FNDRINFO = 0x00004000, + ATTR_CMN_OWNERID = 0x00008000, + ATTR_CMN_GRPID = 0x00010000, + ATTR_CMN_ACCESSMASK = 0x00020000, + ATTR_CMN_FLAGS = 0x00040000, + + ATTR_CMN_GEN_COUNT = 0x00080000, + ATTR_CMN_DOCUMENT_ID = 0x00100000, + + ATTR_CMN_USERACCESS = 0x00200000, + ATTR_CMN_EXTENDED_SECURITY = 0x00400000, + ATTR_CMN_UUID = 0x00800000, + ATTR_CMN_GRPUUID = 0x01000000, + ATTR_CMN_FILEID = 0x02000000, + ATTR_CMN_PARENTID = 0x04000000, + ATTR_CMN_FULLPATH = 0x08000000, + ATTR_CMN_ADDEDTIME = 0x10000000, + ATTR_CMN_ERROR = 0x20000000, // macOS 10.10 + ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000, // macOS 10.10 +} + +enum ATTR_CMN_RETURNED_ATTRS = 0x80000000; +enum ATTR_CMN_VALIDMASK = 0xFFFFFFFF; +enum ATTR_CMN_SETMASK = 0x51C7FF00; +enum ATTR_CMN_VOLSETMASK = 0x00006700; + +enum +{ + ATTR_VOL_FSTYPE = 0x00000001, + ATTR_VOL_SIGNATURE = 0x00000002, + ATTR_VOL_SIZE = 0x00000004, + ATTR_VOL_SPACEFREE = 0x00000008, + ATTR_VOL_SPACEAVAIL = 0x00000010, + ATTR_VOL_MINALLOCATION = 0x00000020, + ATTR_VOL_ALLOCATIONCLUMP = 0x00000040, + ATTR_VOL_IOBLOCKSIZE = 0x00000080, + ATTR_VOL_OBJCOUNT = 0x00000100, + ATTR_VOL_FILECOUNT = 0x00000200, + ATTR_VOL_DIRCOUNT = 0x00000400, + ATTR_VOL_MAXOBJCOUNT = 0x00000800, + ATTR_VOL_MOUNTPOINT = 0x00001000, + ATTR_VOL_NAME = 0x00002000, + ATTR_VOL_MOUNTFLAGS = 0x00004000, + ATTR_VOL_MOUNTEDDEVICE = 0x00008000, + ATTR_VOL_ENCODINGSUSED = 0x00010000, + ATTR_VOL_CAPABILITIES = 0x00020000, + ATTR_VOL_UUID = 0x00040000, + ATTR_VOL_QUOTA_SIZE = 0x10000000, // macOS 10.12.4 + ATTR_VOL_RESERVED_SIZE = 0x20000000, // macOS 10.12.4 + ATTR_VOL_ATTRIBUTES = 0x40000000, + ATTR_VOL_INFO = 0x80000000, +} + +enum ATTR_VOL_VALIDMASK = 0xF007FFFF; +enum ATTR_VOL_SETMASK = 0x80002000; + +enum +{ + ATTR_DIR_LINKCOUNT = 0x00000001, + ATTR_DIR_ENTRYCOUNT = 0x00000002, + ATTR_DIR_MOUNTSTATUS = 0x00000004, + ATTR_DIR_ALLOCSIZE = 0x00000008, // macOS 10.12.4 + ATTR_DIR_IOBLOCKSIZE = 0x00000010, // macOS 10.12.4 + ATTR_DIR_DATALENGTH = 0x00000020, // macOS 10.12.4 +} + +enum +{ + DIR_MNTSTATUS_MNTPOINT = 0x00000001, + DIR_MNTSTATUS_TRIGGER = 0x00000002, +} + +enum ATTR_DIR_VALIDMASK = 0x0000003f; +enum ATTR_DIR_SETMASK = 0x00000000; + +enum +{ + ATTR_FILE_LINKCOUNT = 0x00000001, + ATTR_FILE_TOTALSIZE = 0x00000002, + ATTR_FILE_ALLOCSIZE = 0x00000004, + ATTR_FILE_IOBLOCKSIZE = 0x00000008, + ATTR_FILE_DEVTYPE = 0x00000020, + ATTR_FILE_FORKCOUNT = 0x00000080, + ATTR_FILE_FORKLIST = 0x00000100, + ATTR_FILE_DATALENGTH = 0x00000200, + ATTR_FILE_DATAALLOCSIZE = 0x00000400, + ATTR_FILE_RSRCLENGTH = 0x00001000, + ATTR_FILE_RSRCALLOCSIZE = 0x00002000, +} + +enum ATTR_FILE_VALIDMASK = 0x000037FF; +enum ATTR_FILE_SETMASK = 0x00000020; + +enum +{ + ATTR_CMNEXT_RELPATH = 0x00000004, // macOS 10.12.4 + ATTR_CMNEXT_PRIVATESIZE = 0x00000008, // macOS 10.12.4 + ATTR_CMNEXT_NOFIRMLINKPATH = 0x00000020, // macOS 10.15 + ATTR_CMNEXT_REALDEVID = 0x00000040, // macOS 10.15 + ATTR_CMNEXT_REALFSID = 0x00000080, // macOS 10.15 +} + +enum ATTR_CMNEXT_VALIDMASK = 0x000000fc; +enum ATTR_CMNEXT_SETMASK = 0x00000000; + +enum ATTR_BULK_REQUIRED = ATTR_CMN_NAME | ATTR_CMN_RETURNED_ATTRS; + +enum +{ + SRCHFS_START = 0x00000001, + SRCHFS_MATCHPARTIALNAMES = 0x00000002, + SRCHFS_MATCHDIRS = 0x00000004, + SRCHFS_MATCHFILES = 0x00000008, + SRCHFS_SKIPLINKS = 0x00000010, + SRCHFS_SKIPINVISIBLE = 0x00000020, + SRCHFS_SKIPPACKAGES = 0x00000040, + SRCHFS_SKIPINAPPROPRIATE = 0x00000080, + + SRCHFS_NEGATEPARAMS = 0x80000000, + SRCHFS_VALIDOPTIONSMASK = 0x800000FF, +} + +struct fssearchblock +{ + attrlist* returnattrs; + void* returnbuffer; + size_t returnbuffersize; + c_ulong maxmatches; + timeval timelimit; + void* searchparams1; + size_t sizeofsearchparams1; + void* searchparams2; + size_t sizeofsearchparams2; + attrlist searchattrs; +} + +struct searchstate +{ + uint ss_union_flags; + uint ss_union_layer; + ubyte[548] ss_fsstate; +} +static assert(searchstate.sizeof == uint.sizeof * 2 + searchstate.ss_fsstate.sizeof, + "searchstate struct must be packed"); + +enum FST_EOF = -1; + +@betterC @nogc nothrow pure @safe unittest +{ + // Use an enum instead of `version (Darwin)` so it works with the betterc test extractor. + version (OSX) enum isDarwin = true; + else version (iOS) enum isDarwin = true; + else version (TVOS) enum isDarwin = true; + else version (WatchOS) enum isDarwin = true; + else enum isDarwin = false; + static if (isDarwin) + { + // Verify that these types don't need __initZ and so can be used in betterC. + attrlist al; + attribute_set_t as; + attrreference_t ar; + diskextent de; + vol_capabilities_attr_t vca; + vol_attributes_attr_t vaa; + fssearchblock fsb; + searchstate ss; + } +} diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d b/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d index 3ffa1b93da0..1d3812fc55b 100644 --- a/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d +++ b/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d @@ -50,7 +50,7 @@ struct Dl_info { void *dli_fbase; /* Base address of shared object. */ const(char) *dli_sname; /* Name of nearest symbol. */ void *dli_saddr; /* Address of nearest symbol. */ -}; +} /* @@ -59,13 +59,13 @@ struct Dl_info { struct Dl_serpath { char * dls_name; /* single search path entry */ uint dls_flags; /* path information */ -}; +} struct Dl_serinfo { size_t dls_size; /* total buffer size */ uint dls_cnt; /* number of path entries */ Dl_serpath[1] dls_serpath; /* there may be more than one */ -}; +} /*- * The actual type declared by this typedef is immaterial, provided that @@ -78,7 +78,7 @@ struct Dl_serinfo { */ struct __dlfunc_arg { int __dlfunc_dummy; -}; +} alias dlfunc_t = void function(__dlfunc_arg); diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/err.d b/libphobos/libdruntime/core/sys/dragonflybsd/err.d new file mode 100644 index 00000000000..c3693f85f5e --- /dev/null +++ b/libphobos/libdruntime/core/sys/dragonflybsd/err.d @@ -0,0 +1,31 @@ +/** + * D header file for DragonFlyBSD err.h. + * + * Copyright: Copyright © 2019, The D Language Foundation + * License: Boost License 1.0. + * Authors: Ernesto Castellotti + */ +module core.sys.dragonflybsd.err; +import core.stdc.stdarg : va_list; + +version (DragonFlyBSD): +extern (C): +nothrow: +@nogc: + +alias ExitFunction = void function(int); + +void err(int eval, scope const char* fmt, ...); +void errc(int eval, int code, scope const char* fmt, ...); +void errx(int eval, scope const char* fmt, ...); +void warn(scope const char* fmt, ...); +void warnc(int code, scope const char* fmt, ...); +void warnx(scope const char* fmt, ...); +void verr(int eval, scope const char* fmt, va_list args); +void verrc(int eval, int code, scope const char* fmt, va_list args); +void verrx(int eval, scope const char* fmt, va_list args); +void vwarn(scope const char* fmt, va_list args); +void vwarnc(int code, scope const char* fmt, va_list args); +void vwarnx(scope const char* fmt, va_list args); +void err_set_file(void* vfp); +void err_set_exit(ExitFunction exitf); diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/netinet/in_.d b/libphobos/libdruntime/core/sys/dragonflybsd/netinet/in_.d index c771dc13dba..b0528167c27 100644 --- a/libphobos/libdruntime/core/sys/dragonflybsd/netinet/in_.d +++ b/libphobos/libdruntime/core/sys/dragonflybsd/netinet/in_.d @@ -264,34 +264,34 @@ struct ip_mreq { in_addr imr_multiaddr; in_addr imr_interface; -}; +} struct ip_mreqn { in_addr imr_multiaddr; in_addr imr_address; int imr_ifindex; -}; +} struct ip_mreq_source { in_addr imr_multiaddr; in_addr imr_sourceaddr; in_addr imr_interface; -}; +} struct group_req { uint gr_interface; sockaddr_storage gr_group; -}; +} struct group_source_req { uint gsr_interface; sockaddr_storage gsr_group; sockaddr_storage gsr_source; -}; +} int setipv4sourcefilter(int, in_addr, in_addr, uint, uint, in_addr*); int getipv4sourcefilter(int, in_addr, in_addr, uint*, uint*, in_addr*); @@ -450,13 +450,13 @@ struct in6_pktinfo { in6_addr ipi6_addr; uint ipi6_ifindex; -}; +} struct ip6_mtuinfo { sockaddr_in6 ip6m_addr; uint ip6m_mtu; -}; +} enum IPV6_PORTRANGE_DEFAULT = 0; enum IPV6_PORTRANGE_HIGH = 1; diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/dragonflybsd/sys/link_elf.d index 88f7e06fb65..5dad964057c 100644 --- a/libphobos/libdruntime/core/sys/dragonflybsd/sys/link_elf.d +++ b/libphobos/libdruntime/core/sys/dragonflybsd/sys/link_elf.d @@ -58,7 +58,7 @@ struct r_debug int r_version; link_map* r_map; void function(r_debug*, link_map*) r_brk; -}; +} struct dl_phdr_info { @@ -70,7 +70,7 @@ struct dl_phdr_info uint64_t dlpi_subs; size_t dlpi_tls_modid; void* dlpi_tls_data; -}; +} private alias int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb; diff --git a/libphobos/libdruntime/core/sys/freebsd/dlfcn.d b/libphobos/libdruntime/core/sys/freebsd/dlfcn.d index 95b6c1dfbae..fad91418e6d 100644 --- a/libphobos/libdruntime/core/sys/freebsd/dlfcn.d +++ b/libphobos/libdruntime/core/sys/freebsd/dlfcn.d @@ -54,7 +54,7 @@ static if (__BSD_VISIBLE) void *dli_fbase; /* Base address of shared object. */ const(char) *dli_sname; /* Name of nearest symbol. */ void *dli_saddr; /* Address of nearest symbol. */ - }; + } /*- * The actual type declared by this typedef is immaterial, provided that @@ -67,7 +67,7 @@ static if (__BSD_VISIBLE) */ struct __dlfunc_arg { int __dlfunc_dummy; - }; + } alias dlfunc_t = void function(__dlfunc_arg); @@ -77,13 +77,13 @@ static if (__BSD_VISIBLE) struct Dl_serpath { char * dls_name; /* single search path entry */ uint dls_flags; /* path information */ - }; + } struct Dl_serinfo { size_t dls_size; /* total buffer size */ uint dls_cnt; /* number of path entries */ Dl_serpath[1] dls_serpath; /* there may be more than one */ - }; + } } /* XSI functions first. */ diff --git a/libphobos/libdruntime/core/sys/freebsd/err.d b/libphobos/libdruntime/core/sys/freebsd/err.d new file mode 100644 index 00000000000..8937e0ec705 --- /dev/null +++ b/libphobos/libdruntime/core/sys/freebsd/err.d @@ -0,0 +1,31 @@ +/** + * D header file for FreeBSD err.h. + * + * Copyright: Copyright © 2019, The D Language Foundation + * License: Boost License 1.0. + * Authors: Ernesto Castellotti + */ +module core.sys.freebsd.err; +import core.stdc.stdarg : va_list; + +version (FreeBSD): +extern (C): +nothrow: +@nogc: + +alias ExitFunction = void function(int); + +void err(int eval, scope const char* fmt, ...); +void errc(int eval, int code, scope const char* fmt, ...); +void errx(int eval, scope const char* fmt, ...); +void warn(scope const char* fmt, ...); +void warnc(int code, scope const char* fmt, ...); +void warnx(scope const char* fmt, ...); +void verr(int eval, scope const char* fmt, va_list args); +void verrc(int eval, int code, scope const char* fmt, va_list args); +void verrx(int eval, scope const char* fmt, va_list args); +void vwarn(scope const char* fmt, va_list args); +void vwarnc(int code, scope const char* fmt, va_list args); +void vwarnx(scope const char* fmt, va_list args); +void err_set_file(void* vfp); +void err_set_exit(ExitFunction exitf); diff --git a/libphobos/libdruntime/core/sys/freebsd/execinfo.d b/libphobos/libdruntime/core/sys/freebsd/execinfo.d index 125ef097d27..d32408458d3 100644 --- a/libphobos/libdruntime/core/sys/freebsd/execinfo.d +++ b/libphobos/libdruntime/core/sys/freebsd/execinfo.d @@ -14,6 +14,8 @@ nothrow: version (GNU) version = BacktraceExternal; +version (LDC) + version = BacktraceExternal; version (BacktraceExternal) { diff --git a/libphobos/libdruntime/core/sys/freebsd/netinet/in_.d b/libphobos/libdruntime/core/sys/freebsd/netinet/in_.d index af6a077ee8b..bce17919102 100644 --- a/libphobos/libdruntime/core/sys/freebsd/netinet/in_.d +++ b/libphobos/libdruntime/core/sys/freebsd/netinet/in_.d @@ -268,34 +268,34 @@ static if (__BSD_VISIBLE) { in_addr imr_multiaddr; in_addr imr_interface; - }; + } struct ip_mreqn { in_addr imr_multiaddr; in_addr imr_address; int imr_ifindex; - }; + } struct ip_mreq_source { in_addr imr_multiaddr; in_addr imr_sourceaddr; in_addr imr_interface; - }; + } struct group_req { uint gr_interface; sockaddr_storage gr_group; - }; + } struct group_source_req { uint gsr_interface; sockaddr_storage gsr_group; sockaddr_storage gsr_source; - }; + } int setipv4sourcefilter(int, in_addr, in_addr, uint, uint, in_addr*); int getipv4sourcefilter(int, in_addr, in_addr, uint*, uint*, in_addr*); @@ -463,13 +463,13 @@ static if (__POSIX_VISIBLE) { in6_addr ipi6_addr; uint ipi6_ifindex; - }; + } struct ip6_mtuinfo { sockaddr_in6 ip6m_addr; uint ip6m_mtu; - }; + } enum IPV6_PORTRANGE_DEFAULT = 0; enum IPV6_PORTRANGE_HIGH = 1; diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/event.d b/libphobos/libdruntime/core/sys/freebsd/sys/event.d index 8ac7c3b4758..7f5786219b7 100644 --- a/libphobos/libdruntime/core/sys/freebsd/sys/event.d +++ b/libphobos/libdruntime/core/sys/freebsd/sys/event.d @@ -161,6 +161,23 @@ enum } int kqueue(); -int kevent(int kq, const kevent_t *changelist, int nchanges, - kevent_t *eventlist, int nevents, - const timespec *timeout); + +version (GNU) +{ + int kevent(int kq, const kevent_t *changelist, int nchanges, + kevent_t *eventlist, int nevents, + const timespec *timeout); +} +else +{ + static if (__FreeBSD_version >= 1200000) + pragma(mangle, "kevent@@FBSD_1.5") + int kevent(int kq, const kevent_t *changelist, int nchanges, + kevent_t *eventlist, int nevents, + const timespec *timeout); + else + pragma(mangle, "kevent@FBSD_1.0") + int kevent(int kq, const kevent_t *changelist, int nchanges, + kevent_t *eventlist, int nevents, + const timespec *timeout); +} diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/freebsd/sys/link_elf.d index 97e7cfa7e18..d743d51a7b2 100644 --- a/libphobos/libdruntime/core/sys/freebsd/sys/link_elf.d +++ b/libphobos/libdruntime/core/sys/freebsd/sys/link_elf.d @@ -56,7 +56,7 @@ struct r_debug int r_version; link_map* r_map; void function(r_debug*, link_map*) r_brk; -}; +} struct dl_phdr_info { @@ -68,7 +68,7 @@ struct dl_phdr_info uint64_t dlpi_subs; size_t dlpi_tls_modid; void* dlpi_tls_data; -}; +} private alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb; diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/mount.d b/libphobos/libdruntime/core/sys/freebsd/sys/mount.d index e45c4600661..1b0f0423001 100644 --- a/libphobos/libdruntime/core/sys/freebsd/sys/mount.d +++ b/libphobos/libdruntime/core/sys/freebsd/sys/mount.d @@ -298,17 +298,47 @@ enum uint VQ_FLAG2000 = 0x2000; enum uint VQ_FLAG4000 = 0x4000; enum uint VQ_FLAG8000 = 0x8000; -int fhopen(const fhandle_t*, int); -int fhstat(const fhandle_t*, stat_t*); -int fhstatfs(const fhandle_t*, statfs_t*); -int fstatfs(int, statfs_t*); -int getfh(const char*, fhandle_t*); -int getfsstat(statfs_t*, c_long, int); -int getmntinfo(statfs_t**, int); -int lgetfh(const char*, fhandle_t*); -int mount(const char*, const char*, int, void*); -//int nmount(iovec*, uint, int); -int statfs(const char*, statfs_t*); -int unmount(const char*, int); - -//int getvfsbyname(const char*, xvfsconf*); +version (GNU) +{ + int fhopen(const fhandle_t*, int); + int fhstat(const fhandle_t*, stat_t*); + int fhstatfs(const fhandle_t*, statfs_t*); + int fstatfs(int, statfs_t*); + int getfh(const char*, fhandle_t*); + int getfsstat(statfs_t*, c_long, int); + int getmntinfo(statfs_t**, int); + int lgetfh(const char*, fhandle_t*); + int mount(const char*, const char*, int, void*); + //int nmount(iovec*, uint, int); + int statfs(const char*, statfs_t*); + int unmount(const char*, int); + //int getvfsbyname(const char*, xvfsconf*); +} +else +{ + static if (__FreeBSD_version >= 1200000) + { + pragma(mangle, "fhstat@FBSD_1.5") int fhstat(const fhandle_t*, stat_t*); + pragma(mangle, "fhstatfs@FBSD_1.5") int fhstatfs(const fhandle_t*, statfs_t*); + pragma(mangle, "fstatfs@FBSD_1.5") int fstatfs(int, statfs_t*); + pragma(mangle, "getfsstat@FBSD_1.5") int getfsstat(statfs_t*, c_long, int); + pragma(mangle, "getmntinfo@FBSD_1.5") int getmntinfo(statfs_t**, int); + pragma(mangle, "statfs@FBSD_1.5") int statfs(const char*, statfs_t*); + } + else + { + pragma(mangle, "fhstat@FBSD_1.0") int fhstat(const fhandle_t*, stat_t*); + pragma(mangle, "fhstatfs@FBSD_1.0") int fhstatfs(const fhandle_t*, statfs_t*); + pragma(mangle, "fstatfs@FBSD_1.0") int fstatfs(int, statfs_t*); + pragma(mangle, "getfsstat@FBSD_1.0") int getfsstat(statfs_t*, c_long, int); + pragma(mangle, "getmntinfo@FBSD_1.0") int getmntinfo(statfs_t**, int); + pragma(mangle, "statfs@FBSD_1.0") int statfs(const char*, statfs_t*); + } + pragma(mangle, "fhopen@@FBSD_1.0") int fhopen(const fhandle_t*, int); + pragma(mangle, "getfh@@FBSD_1.0") int getfh(const char*, fhandle_t*); + pragma(mangle, "lgetfh@@FBSD_1.0") int lgetfh(const char*, fhandle_t*); + pragma(mangle, "mount@@FBSD_1.0") int mount(const char*, const char*, int, void*); + //int nmount(iovec*, uint, int); + pragma(mangle, "unmount@@FBSD_1.0") int unmount(const char*, int); + //int getvfsbyname(const char*, xvfsconf*); +} diff --git a/libphobos/libdruntime/core/sys/linux/dlfcn.d b/libphobos/libdruntime/core/sys/linux/dlfcn.d index f2decc2b3ec..a815d0907fe 100644 --- a/libphobos/libdruntime/core/sys/linux/dlfcn.d +++ b/libphobos/libdruntime/core/sys/linux/dlfcn.d @@ -9,6 +9,7 @@ version (linux): extern (C): nothrow: @nogc: +@system: version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; @@ -236,14 +237,14 @@ static if (__USE_GNU) enum LM_ID_NEWLM = -1; } -// void* dlopen(in char* __file, int __mode); // POSIX +// void* dlopen(const scope char* __file, int __mode); // POSIX // int dlclose(void* __handle); // POSIX -// void* dlsym(void* __handle, in char* __name); // POSIX +// void* dlsym(void* __handle, const scope char* __name); // POSIX static if (__USE_GNU) { - void* dlmopen(Lmid_t __nsid, in char* __file, int __mode); - void* dlvsym(void* __handle, in char* __name, in char* __version); + void* dlmopen(Lmid_t __nsid, const scope char* __file, int __mode); + void* dlvsym(void* __handle, const scope char* __name, const scope char* __version); } // char* dlerror(); // POSIX @@ -258,7 +259,7 @@ static if (__USE_GNU) void* dli_saddr; } - int dladdr(in void* __address, Dl_info* __info); + int dladdr(const scope void* __address, Dl_info* __info); int dladdr1(void* __address, Dl_info* __info, void** __extra_info, int __flags); enum diff --git a/libphobos/libdruntime/core/sys/linux/elf.d b/libphobos/libdruntime/core/sys/linux/elf.d index ab07ac94108..4d0b2273117 100644 --- a/libphobos/libdruntime/core/sys/linux/elf.d +++ b/libphobos/libdruntime/core/sys/linux/elf.d @@ -9,6 +9,7 @@ version (linux): extern (C): pure: nothrow: +@system: import core.stdc.stdint; @@ -831,7 +832,6 @@ enum AT_EXECFN = 31; enum AT_SYSINFO = 32; enum AT_SYSINFO_EHDR = 33; -; enum AT_L1I_CACHESHAPE = 34; enum AT_L1D_CACHESHAPE = 35; enum AT_L2_CACHESHAPE = 36; diff --git a/libphobos/libdruntime/core/sys/linux/epoll.d b/libphobos/libdruntime/core/sys/linux/epoll.d index 4798967c79d..0c3aed98853 100644 --- a/libphobos/libdruntime/core/sys/linux/epoll.d +++ b/libphobos/libdruntime/core/sys/linux/epoll.d @@ -14,6 +14,7 @@ extern (C): @system: @nogc: nothrow: +@system: version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/linux/err.d b/libphobos/libdruntime/core/sys/linux/err.d new file mode 100644 index 00000000000..be5378d0618 --- /dev/null +++ b/libphobos/libdruntime/core/sys/linux/err.d @@ -0,0 +1,24 @@ +/** + * D header file for Linux err.h. + * + * Copyright: Copyright © 2019, The D Language Foundation + * License: Boost License 1.0. + * Authors: Ernesto Castellotti + */ +module core.sys.linux.err; +import core.stdc.stdarg : va_list; + +version (linux): +extern (C): +nothrow: +@nogc: +@system: + +void err(int eval, scope const char* fmt, ...); +void errx(int eval, scope const char* fmt, ...); +void warn(scope const char* fmt, ...); +void warnx(scope const char* fmt, ...); +void verr(int eval, scope const char* fmt, va_list args); +void verrx(int eval, scope const char* fmt, va_list args); +void vwarn(scope const char* fmt, va_list args); +void vwarnx(scope const char* fmt, va_list args); diff --git a/libphobos/libdruntime/core/sys/linux/errno.d b/libphobos/libdruntime/core/sys/linux/errno.d index bc93675c735..02ae151427e 100644 --- a/libphobos/libdruntime/core/sys/linux/errno.d +++ b/libphobos/libdruntime/core/sys/linux/errno.d @@ -8,6 +8,7 @@ module core.sys.linux.errno; version (linux): extern (C): nothrow: +@system: public import core.stdc.errno; import core.sys.linux.config; diff --git a/libphobos/libdruntime/core/sys/linux/execinfo.d b/libphobos/libdruntime/core/sys/linux/execinfo.d index 3259443fe53..4169ca36c5b 100644 --- a/libphobos/libdruntime/core/sys/linux/execinfo.d +++ b/libphobos/libdruntime/core/sys/linux/execinfo.d @@ -10,6 +10,8 @@ module core.sys.linux.execinfo; version (linux): extern (C): nothrow: +@system: +@nogc: int backtrace(void** buffer, int size); char** backtrace_symbols(const(void*)* buffer, int size); diff --git a/libphobos/libdruntime/core/sys/linux/fcntl.d b/libphobos/libdruntime/core/sys/linux/fcntl.d index 974a5cc2a38..11c374530bf 100644 --- a/libphobos/libdruntime/core/sys/linux/fcntl.d +++ b/libphobos/libdruntime/core/sys/linux/fcntl.d @@ -5,6 +5,7 @@ public import core.sys.posix.fcntl; version (linux): extern(C): nothrow: +@system: // From linux/falloc.h /// fallocate(2) params diff --git a/libphobos/libdruntime/core/sys/linux/ifaddrs.d b/libphobos/libdruntime/core/sys/linux/ifaddrs.d index d7b6d6de727..5490e97aa0f 100644 --- a/libphobos/libdruntime/core/sys/linux/ifaddrs.d +++ b/libphobos/libdruntime/core/sys/linux/ifaddrs.d @@ -22,6 +22,7 @@ version (linux): extern (C): nothrow: @nogc: +@system: struct ifaddrs { @@ -46,7 +47,7 @@ struct ifaddrs /// Address specific data void* ifa_data; -}; +} /// Returns: linked list of ifaddrs structures describing interfaces int getifaddrs(ifaddrs** ); diff --git a/libphobos/libdruntime/core/sys/linux/link.d b/libphobos/libdruntime/core/sys/linux/link.d index 4d7eb1eb7d3..b417ec8ec77 100644 --- a/libphobos/libdruntime/core/sys/linux/link.d +++ b/libphobos/libdruntime/core/sys/linux/link.d @@ -8,6 +8,7 @@ module core.sys.linux.link; version (linux): extern (C): nothrow: +@system: version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/linux/netinet/in_.d b/libphobos/libdruntime/core/sys/linux/netinet/in_.d index 47102e11eb8..67bf6545c8f 100644 --- a/libphobos/libdruntime/core/sys/linux/netinet/in_.d +++ b/libphobos/libdruntime/core/sys/linux/netinet/in_.d @@ -121,27 +121,27 @@ version (linux_libc) { in_addr imr_multiaddr; in_addr imr_interface; - }; + } struct ip_mreq_source { in_addr imr_multiaddr; in_addr imr_interface; in_addr imr_sourceaddr; - }; + } struct group_req { uint gr_interface; sockaddr_storage gr_group; - }; + } struct group_source_req { uint gsr_interface; sockaddr_storage gsr_group; sockaddr_storage gsr_source; - }; + } struct ip_msfilter { @@ -150,7 +150,7 @@ version (linux_libc) uint imsf_fmode; uint imsf_numsrc; in_addr[1] imsf_slist; - }; + } extern(D) size_t IP_MSFILTER_SIZE(int numsrc) { @@ -164,7 +164,7 @@ version (linux_libc) uint gf_fmode; uint gf_numsrc; sockaddr_storage[1] gf_slist; - }; + } extern(D) size_t GROUP_FILTER_SIZE(int numsrc) pure @safe { @@ -186,13 +186,13 @@ version (linux_libc) { in6_addr ipi6_addr; uint ipi6_ifindex; - }; + } struct ip6_mtuinfo { sockaddr_in6 ip6m_addr; uint ip6m_mtu; - }; + } int inet6_opt_init(void* __extbuf, socklen_t __extlen); int inet6_opt_append(void* __extbuf, socklen_t __extlen, int __offset, @@ -313,21 +313,21 @@ version (linux_libc) { in_addr ip_dst; char[40] ip_opts = 0; - }; + } struct ip_mreqn { in_addr imr_multiaddr; in_addr imr_address; int imr_ifindex; - }; + } struct in_pktinfo { int ipi_ifindex; in_addr ipi_spec_dst; in_addr ipi_addr; - }; + } } enum IPV6_ADDRFORM = 1; diff --git a/libphobos/libdruntime/core/sys/linux/sched.d b/libphobos/libdruntime/core/sys/linux/sched.d index 53cd0ef6822..dc815a0fc3c 100644 --- a/libphobos/libdruntime/core/sys/linux/sched.d +++ b/libphobos/libdruntime/core/sys/linux/sched.d @@ -17,6 +17,7 @@ module core.sys.linux.sched; import core.bitop : popcnt; +import core.stdc.stdlib : malloc, free; import core.sys.posix.sched; import core.sys.posix.config; import core.sys.posix.sys.types; @@ -25,6 +26,7 @@ version (linux): extern (C): @nogc: nothrow: +@system: private // helpers @@ -49,6 +51,21 @@ private // helpers return 1UL << (cpu % __NCPUBITS); } + cpu_set_t* __CPU_ALLOC(size_t count) + { + return cast(cpu_set_t*) malloc(__CPU_ALLOC_SIZE(count)); + } + + size_t __CPU_ALLOC_SIZE(size_t count) pure + { + return ((count + __NCPUBITS - 1) / __NCPUBITS) * cpu_mask.sizeof; + } + + void __CPU_FREE(cpu_set_t* set) + { + free(cast(void*) set); + } + cpu_mask __CPU_SET_S(size_t cpu, size_t setsize, cpu_set_t* cpusetp) pure { if (cpu < 8 * setsize) @@ -87,6 +104,21 @@ struct cpu_set_t /// Access macros for 'cpu_set' (missing a lot of them) +cpu_set_t* CPU_ALLOC(size_t count) +{ + return __CPU_ALLOC(count); +} + +size_t CPU_ALLOC_SIZE(size_t count) pure +{ + return __CPU_ALLOC_SIZE(count); +} + +void CPU_FREE(cpu_set_t* set) +{ + __CPU_FREE(set); +} + cpu_mask CPU_SET(size_t cpu, cpu_set_t* cpusetp) pure { return __CPU_SET_S(cpu, cpu_set_t.sizeof, cpusetp); @@ -102,6 +134,11 @@ int CPU_COUNT(cpu_set_t* cpusetp) pure return __CPU_COUNT_S(cpu_set_t.sizeof, cpusetp); } +int CPU_COUNT_S(size_t setsize, cpu_set_t* cpusetp) pure +{ + return __CPU_COUNT_S(setsize, cpusetp); +} + /* Scheduler control functions */ int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); @@ -110,6 +147,12 @@ int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); int clone(int function(void*), void* child_stack, int flags, void* arg, ...); int unshare(int flags) @trusted; +version (CRuntime_Glibc) +{ + /* Determine CPU on which the calling thread is running */ + int sched_getcpu(); +} + enum CLONE_FILES = 0x400; enum CLONE_FS = 0x200; enum CLONE_NEWCGROUP = 0x2000000; @@ -122,4 +165,5 @@ enum CLONE_NEWUTS = 0x4000000; enum CLONE_SIGHAND = 0x800; enum CLONE_SYSVSEM = 0x40000; enum CLONE_THREAD = 0x10000; +enum CLONE_VFORK = 0x4000; enum CLONE_VM = 0x100; diff --git a/libphobos/libdruntime/core/sys/linux/stdio.d b/libphobos/libdruntime/core/sys/linux/stdio.d index 578b2152ce8..ab8971b482f 100644 --- a/libphobos/libdruntime/core/sys/linux/stdio.d +++ b/libphobos/libdruntime/core/sys/linux/stdio.d @@ -13,6 +13,8 @@ import core.sys.linux.config : __USE_FILE_OFFSET64; import core.stdc.stdio : FILE; import core.stdc.stddef : wchar_t; +@system: + extern(C) nothrow { alias ssize_t function(void *cookie, char *buf, size_t size) cookie_read_function_t; diff --git a/libphobos/libdruntime/core/sys/linux/string.d b/libphobos/libdruntime/core/sys/linux/string.d index a388c8ba1ae..1b2c8d86a4a 100644 --- a/libphobos/libdruntime/core/sys/linux/string.d +++ b/libphobos/libdruntime/core/sys/linux/string.d @@ -14,6 +14,7 @@ version (linux): extern (C): nothrow: @nogc: +@system: static if (__USE_GNU) { diff --git a/libphobos/libdruntime/core/sys/linux/sys/inotify.d b/libphobos/libdruntime/core/sys/linux/sys/inotify.d index 67545a80cd6..e0acf33fa51 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/inotify.d +++ b/libphobos/libdruntime/core/sys/linux/sys/inotify.d @@ -10,6 +10,7 @@ version (linux): extern (C): @system: nothrow: +@nogc: version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/linux/sys/mman.d b/libphobos/libdruntime/core/sys/linux/sys/mman.d index 212943bbb3a..20e8cf29f8d 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/mman.d +++ b/libphobos/libdruntime/core/sys/linux/sys/mman.d @@ -8,6 +8,8 @@ module core.sys.linux.sys.mman; version (linux): extern (C): nothrow: +@system: +@nogc: version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/linux/sys/prctl.d b/libphobos/libdruntime/core/sys/linux/sys/prctl.d index a5a4807f17a..a7322166a20 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/prctl.d +++ b/libphobos/libdruntime/core/sys/linux/sys/prctl.d @@ -141,7 +141,7 @@ struct prctl_mm_map ulong* auxv; uint auxv_size; uint exe_fd; -}; +} int prctl(int option, size_t arg2, size_t arg3, size_t arg4, size_t arg5); diff --git a/libphobos/libdruntime/core/sys/linux/sys/signalfd.d b/libphobos/libdruntime/core/sys/linux/sys/signalfd.d index 5d4cb674955..736b1456169 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/signalfd.d +++ b/libphobos/libdruntime/core/sys/linux/sys/signalfd.d @@ -14,6 +14,7 @@ version (linux): extern (C): @system: nothrow: +@nogc: struct signalfd_siginfo { diff --git a/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d b/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d index 699cd3e67c4..0c9ed592c3b 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d +++ b/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d @@ -7,6 +7,7 @@ module core.sys.linux.sys.sysinfo; version (linux) extern(C) @nogc nothrow: +@system: import core.sys.linux.config; diff --git a/libphobos/libdruntime/core/sys/linux/sys/time.d b/libphobos/libdruntime/core/sys/linux/sys/time.d index 4b55f708657..6ea626ed390 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/time.d +++ b/libphobos/libdruntime/core/sys/linux/sys/time.d @@ -13,7 +13,7 @@ */ module core.sys.linux.sys.time; -private import core.sys.linux.config; +import core.sys.linux.config; public import core.sys.posix.sys.time; // timeval version (linux): diff --git a/libphobos/libdruntime/core/sys/linux/sys/xattr.d b/libphobos/libdruntime/core/sys/linux/sys/xattr.d index a14c6c6174b..2f8d3f376f9 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/xattr.d +++ b/libphobos/libdruntime/core/sys/linux/sys/xattr.d @@ -13,6 +13,7 @@ version (linux): extern (C): @system: nothrow: +@nogc: enum { XATTR_CREATE = 1, /* set value, fail if attr already exists. */ @@ -52,17 +53,17 @@ enum XATTR_CAPS_SUFFIX = "capability"; enum XATTR_NAME_CAPS = XATTR_SECURITY_PREFIX ~ XATTR_CAPS_SUFFIX; -int setxattr(in char* path, in char* name, in void* value, size_t size, int flags); +int setxattr(const scope char* path, const scope char* name, const scope void* value, size_t size, int flags); -int lsetxattr(in char* path, in char* name, in void* value, size_t size, int flags); -int fsetxattr(int fd, in char* name, in void* value, size_t size, int flags); -ssize_t getxattr(in char* path, in char* name, void* value, size_t size); -ssize_t lgetxattr(in char* path, in char* name, void* value, size_t size); -ssize_t fgetxattr(int fd, in char* name, void* value, size_t size); -ssize_t listxattr(in char* path, char* list, size_t size); -ssize_t llistxattr(in char* path, char* list, size_t size); +int lsetxattr(const scope char* path, const scope char* name, const scope void* value, size_t size, int flags); +int fsetxattr(int fd, const scope char* name, const scope void* value, size_t size, int flags); +ssize_t getxattr(const scope char* path, const scope char* name, void* value, size_t size); +ssize_t lgetxattr(const scope char* path, const scope char* name, void* value, size_t size); +ssize_t fgetxattr(int fd, const scope char* name, void* value, size_t size); +ssize_t listxattr(const scope char* path, char* list, size_t size); +ssize_t llistxattr(const scope char* path, char* list, size_t size); ssize_t flistxattr (int __fd, char *list, size_t size); -int removexattr (in char *path, in char *name); -int lremovexattr (in char *path, in char *name); -int fremovexattr (int fd, in char *name); +int removexattr (const scope char *path, const scope char *name); +int lremovexattr (const scope char *path, const scope char *name); +int fremovexattr (int fd, const scope char *name); diff --git a/libphobos/libdruntime/core/sys/linux/tipc.d b/libphobos/libdruntime/core/sys/linux/tipc.d index 161a313d079..3246e62ec04 100644 --- a/libphobos/libdruntime/core/sys/linux/tipc.d +++ b/libphobos/libdruntime/core/sys/linux/tipc.d @@ -10,6 +10,7 @@ module core.sys.linux.tipc; version (linux): extern (C) nothrow @nogc: +@system: struct tipc_portid { diff --git a/libphobos/libdruntime/core/sys/linux/unistd.d b/libphobos/libdruntime/core/sys/linux/unistd.d index 21fd96208e8..48457467005 100644 --- a/libphobos/libdruntime/core/sys/linux/unistd.d +++ b/libphobos/libdruntime/core/sys/linux/unistd.d @@ -5,6 +5,7 @@ public import core.sys.posix.unistd; version (linux): extern(C): nothrow: +@system: // Additional seek constants for sparse file handling // from Linux's unistd.h, stdio.h, and linux/fs.h @@ -18,3 +19,6 @@ enum { /// Prompt for a password without echoing it. char* getpass(const(char)* prompt); + +// Exit all threads in a process +void exit_group(int status); diff --git a/libphobos/libdruntime/core/sys/netbsd/dlfcn.d b/libphobos/libdruntime/core/sys/netbsd/dlfcn.d index 88eb94bf20e..dbbcc7638fd 100644 --- a/libphobos/libdruntime/core/sys/netbsd/dlfcn.d +++ b/libphobos/libdruntime/core/sys/netbsd/dlfcn.d @@ -55,7 +55,7 @@ static if (__BSD_VISIBLE) void *dli_fbase; /* Base address of shared object. */ const(char) *dli_sname; /* Name of nearest symbol. */ void *dli_saddr; /* Address of nearest symbol. */ - }; + } /*- * The actual type declared by this typedef is immaterial, provided that @@ -68,7 +68,7 @@ static if (__BSD_VISIBLE) */ struct __dlfunc_arg { int __dlfunc_dummy; - }; + } alias dlfunc_t = void function(__dlfunc_arg); @@ -78,13 +78,13 @@ static if (__BSD_VISIBLE) struct Dl_serpath { char * dls_name; /* single search path entry */ uint dls_flags; /* path information */ - }; + } struct Dl_serinfo { size_t dls_size; /* total buffer size */ uint dls_cnt; /* number of path entries */ Dl_serpath[1] dls_serpath; /* there may be more than one */ - }; + } } private template __externC(RT, P...) diff --git a/libphobos/libdruntime/core/sys/netbsd/err.d b/libphobos/libdruntime/core/sys/netbsd/err.d new file mode 100644 index 00000000000..44eb66adc2f --- /dev/null +++ b/libphobos/libdruntime/core/sys/netbsd/err.d @@ -0,0 +1,27 @@ +/** + * D header file for NetBSD err.h. + * + * Copyright: Copyright © 2019, The D Language Foundation + * License: Boost License 1.0. + * Authors: Ernesto Castellotti + */ +module core.sys.netbsd.err; +import core.stdc.stdarg : va_list; + +version (NetBSD): +extern (C): +nothrow: +@nogc: + +void err(int eval, scope const char* fmt, ...); +void errc(int eval, int code, scope const char* fmt, ...); +void errx(int eval, scope const char* fmt, ...); +void warn(scope const char* fmt, ...); +void warnc(int code, scope const char* fmt, ...); +void warnx(scope const char* fmt, ...); +void verr(int eval, scope const char* fmt, va_list args); +void verrc(int eval, int code, scope const char* fmt, va_list args); +void verrx(int eval, scope const char* fmt, va_list args); +void vwarn(scope const char* fmt, va_list args); +void vwarnc(int code, scope const char* fmt, va_list args); +void vwarnx(scope const char* fmt, va_list args); diff --git a/libphobos/libdruntime/core/sys/netbsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/netbsd/sys/link_elf.d index cc24a776629..4caec61adc8 100644 --- a/libphobos/libdruntime/core/sys/netbsd/sys/link_elf.d +++ b/libphobos/libdruntime/core/sys/netbsd/sys/link_elf.d @@ -50,7 +50,7 @@ struct r_debug int r_version; link_map* r_map; void function(r_debug*, link_map*) r_brk; -}; +} struct dl_phdr_info { @@ -62,7 +62,7 @@ struct dl_phdr_info uint64_t dlpi_subs; size_t dlpi_tls_modid; void* dlpi_tls_data; -}; +} private alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb; diff --git a/libphobos/libdruntime/core/sys/openbsd/err.d b/libphobos/libdruntime/core/sys/openbsd/err.d new file mode 100644 index 00000000000..b4676140e38 --- /dev/null +++ b/libphobos/libdruntime/core/sys/openbsd/err.d @@ -0,0 +1,27 @@ +/** + * D header file for OpenBSD err.h. + * + * Copyright: Copyright © 2019, The D Language Foundation + * License: Boost License 1.0. + * Authors: Ernesto Castellotti + */ +module core.sys.openbsd.err; +import core.stdc.stdarg : va_list; + +version (OpenBSD): +extern (C): +nothrow: +@nogc: + +void err(int eval, scope const char* fmt, ...); +void errc(int eval, int code, scope const char* fmt, ...); +void errx(int eval, scope const char* fmt, ...); +void warn(scope const char* fmt, ...); +void warnc(int code, scope const char* fmt, ...); +void warnx(scope const char* fmt, ...); +void verr(int eval, scope const char* fmt, va_list args); +void verrc(int eval, int code, scope const char* fmt, va_list args); +void verrx(int eval, scope const char* fmt, va_list args); +void vwarn(scope const char* fmt, va_list args); +void vwarnc(int code, scope const char* fmt, va_list args); +void vwarnx(scope const char* fmt, va_list args); diff --git a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d index 3582b4c08c5..f88671a3160 100644 --- a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d +++ b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d @@ -55,7 +55,7 @@ struct dl_phdr_info char* dlpi_name; ElfW!"Phdr"* dlpi_phdr; ElfW!"Half" dlpi_phnum; -}; +} private alias int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb; diff --git a/libphobos/libdruntime/core/sys/posix/aio.d b/libphobos/libdruntime/core/sys/posix/aio.d index 1165446be5c..f4e0f122d30 100644 --- a/libphobos/libdruntime/core/sys/posix/aio.d +++ b/libphobos/libdruntime/core/sys/posix/aio.d @@ -8,8 +8,8 @@ */ module core.sys.posix.aio; -private import core.sys.posix.signal; -private import core.sys.posix.sys.types; +import core.sys.posix.signal; +import core.sys.posix.sys.types; version (OSX) version = Darwin; diff --git a/libphobos/libdruntime/core/sys/posix/arpa/inet.d b/libphobos/libdruntime/core/sys/posix/arpa/inet.d index ac8e3eb1c76..6881142a0fb 100644 --- a/libphobos/libdruntime/core/sys/posix/arpa/inet.d +++ b/libphobos/libdruntime/core/sys/posix/arpa/inet.d @@ -14,7 +14,7 @@ */ module core.sys.posix.arpa.inet; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.stdc.inttypes; // for uint32_t, uint16_t public import core.sys.posix.sys.socket; // for socklen_t @@ -51,11 +51,11 @@ uint16_t htons(uint16_t); uint32_t ntohl(uint32_t); uint16_t ntohs(uint16_t); -in_addr_t inet_addr(in char*); +in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); // per spec: const char* inet_ntop(int, const void*, char*, socklen_t); -char* inet_ntop(int, in void*, char*, socklen_t); -int inet_pton(int, in char*, void*); +char* inet_ntop(int, const scope void*, char*, socklen_t); +int inet_pton(int, const scope char*, void*); */ version (CRuntime_Glibc) @@ -78,10 +78,10 @@ version (CRuntime_Glibc) uint16_t ntohs(uint16_t); } - in_addr_t inet_addr(in char*); + in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); - const(char)* inet_ntop(int, in void*, char*, socklen_t); - int inet_pton(int, in char*, void*); + const(char)* inet_ntop(int, const scope void*, char*, socklen_t); + int inet_pton(int, const scope char*, void*); } else version (Darwin) { @@ -103,10 +103,10 @@ else version (Darwin) uint16_t ntohs(uint16_t); } - in_addr_t inet_addr(in char*); + in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); - const(char)* inet_ntop(int, in void*, char*, socklen_t); - int inet_pton(int, in char*, void*); + const(char)* inet_ntop(int, const scope void*, char*, socklen_t); + int inet_pton(int, const scope char*, void*); } else version (FreeBSD) { @@ -128,10 +128,10 @@ else version (FreeBSD) uint16_t ntohs(uint16_t); } - in_addr_t inet_addr(in char*); + in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); - const(char)* inet_ntop(int, in void*, char*, socklen_t); - int inet_pton(int, in char*, void*); + const(char)* inet_ntop(int, const scope void*, char*, socklen_t); + int inet_pton(int, const scope char*, void*); } else version (NetBSD) { @@ -153,10 +153,10 @@ else version (NetBSD) uint16_t ntohs(uint16_t); } - in_addr_t inet_addr(in char*); + in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); - const(char)* inet_ntop(int, in void*, char*, socklen_t); - int inet_pton(int, in char*, void*); + const(char)* inet_ntop(int, const scope void*, char*, socklen_t); + int inet_pton(int, const scope char*, void*); } else version (OpenBSD) { @@ -194,10 +194,10 @@ else version (OpenBSD) uint16_t ntohs(uint16_t x) { return __swap16(x); } } - in_addr_t inet_addr(in char*); + in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); - const(char)* inet_ntop(int, in void*, char*, socklen_t); - int inet_pton(int, in char*, void*); + const(char)* inet_ntop(int, const scope void*, char*, socklen_t); + int inet_pton(int, const scope char*, void*); } else version (DragonFlyBSD) { @@ -219,10 +219,10 @@ else version (DragonFlyBSD) uint16_t ntohs(uint16_t); } - in_addr_t inet_addr(in char*); + in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); - const(char)* inet_ntop(int, in void*, char*, socklen_t); - int inet_pton(int, in char*, void*); + const(char)* inet_ntop(int, const scope void*, char*, socklen_t); + int inet_pton(int, const scope char*, void*); } else version (Solaris) { @@ -243,10 +243,10 @@ else version (Solaris) uint16_t ntohs(uint16_t); } - in_addr_t inet_addr(in char*); + in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); - const(char)* inet_ntop(int, in void*, char*, socklen_t); - int inet_pton(int, in char*, void*); + const(char)* inet_ntop(int, const scope void*, char*, socklen_t); + int inet_pton(int, const scope char*, void*); } else version (CRuntime_Bionic) { @@ -283,10 +283,10 @@ else version (CRuntime_Bionic) uint16_t ntohs(uint16_t x) { return __swap16(x); } } - in_addr_t inet_addr(in char*); + in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); - const(char)* inet_ntop(int, in void*, char*, size_t); - int inet_pton(int, in char*, void*); + const(char)* inet_ntop(int, const scope void*, char*, size_t); + int inet_pton(int, const scope char*, void*); } else version (CRuntime_Musl) { @@ -308,10 +308,10 @@ else version (CRuntime_Musl) uint16_t ntohs(uint16_t); } - in_addr_t inet_addr(in char*); + in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); - const(char)* inet_ntop(int, in void*, char*, socklen_t); - int inet_pton(int, in char*, void*); + const(char)* inet_ntop(int, const scope void*, char*, socklen_t); + int inet_pton(int, const scope char*, void*); } else version (CRuntime_UClibc) { @@ -333,10 +333,10 @@ else version (CRuntime_UClibc) uint16_t ntohs(uint16_t); } - in_addr_t inet_addr(in char*); + in_addr_t inet_addr(const scope char*); char* inet_ntoa(in_addr); - const(char)* inet_ntop(int, in void*, char*, socklen_t); - int inet_pton(int, in char*, void*); + const(char)* inet_ntop(int, const scope void*, char*, socklen_t); + int inet_pton(int, const scope char*, void*); } // diff --git a/libphobos/libdruntime/core/sys/posix/config.d b/libphobos/libdruntime/core/sys/posix/config.d index 20e711cb72d..c02debffadd 100644 --- a/libphobos/libdruntime/core/sys/posix/config.d +++ b/libphobos/libdruntime/core/sys/posix/config.d @@ -19,6 +19,7 @@ public import core.stdc.config; version (Posix): extern (C) nothrow @nogc: +@system: enum _XOPEN_SOURCE = 600; enum _POSIX_SOURCE = true; diff --git a/libphobos/libdruntime/core/sys/posix/dirent.d b/libphobos/libdruntime/core/sys/posix/dirent.d index b12d6b157d5..8a2440e1fa4 100644 --- a/libphobos/libdruntime/core/sys/posix/dirent.d +++ b/libphobos/libdruntime/core/sys/posix/dirent.d @@ -15,7 +15,7 @@ */ module core.sys.posix.dirent; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for ino_t version (OSX) @@ -31,6 +31,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // Required @@ -44,7 +45,7 @@ struct dirent } int closedir(DIR*); -DIR* opendir(in char*); +DIR* opendir(const scope char*); dirent* readdir(DIR*); void rewinddir(DIR*); */ @@ -129,7 +130,12 @@ else version (Darwin) // Other Darwin variants (iOS, TVOS, WatchOS) only support 64-bit inodes, // no suffix needed version (OSX) - pragma(mangle, "readdir$INODE64") dirent* readdir(DIR*); + { + version (AArch64) + dirent* readdir(DIR*); + else + pragma(mangle, "readdir$INODE64") dirent* readdir(DIR*); + } else dirent* readdir(DIR*); } @@ -180,7 +186,17 @@ else version (FreeBSD) alias void* DIR; - dirent* readdir(DIR*); + version (GNU) + { + dirent* readdir(DIR*); + } + else + { + static if (__FreeBSD_version >= 1200000) + pragma(mangle, "readdir@FBSD_1.5") dirent* readdir(DIR*); + else + pragma(mangle, "readdir@FBSD_1.0") dirent* readdir(DIR*); + } } else version (NetBSD) { @@ -434,10 +450,16 @@ else // in else below. version (OSX) { - version (D_LP64) + version (AArch64) + { + int closedir(DIR*); + DIR* opendir(const scope char*); + void rewinddir(DIR*); + } + else version (D_LP64) { int closedir(DIR*); - pragma(mangle, "opendir$INODE64") DIR* opendir(in char*); + pragma(mangle, "opendir$INODE64") DIR* opendir(const scope char*); pragma(mangle, "rewinddir$INODE64") void rewinddir(DIR*); } else @@ -445,21 +467,21 @@ version (OSX) // 32-bit mangles __DARWIN_UNIX03 specific functions with $UNIX2003 to // maintain backward compatibility with binaries build pre 10.5 pragma(mangle, "closedir$UNIX2003") int closedir(DIR*); - pragma(mangle, "opendir$INODE64$UNIX2003") DIR* opendir(in char*); + pragma(mangle, "opendir$INODE64$UNIX2003") DIR* opendir(const scope char*); pragma(mangle, "rewinddir$INODE64$UNIX2003") void rewinddir(DIR*); } } else version (NetBSD) { int closedir(DIR*); - DIR* __opendir30(in char*); + DIR* __opendir30(const scope char*); alias __opendir30 opendir; void rewinddir(DIR*); } else { int closedir(DIR*); - DIR* opendir(in char*); + DIR* opendir(const scope char*); //dirent* readdir(DIR*); void rewinddir(DIR*); } @@ -492,7 +514,17 @@ else version (Darwin) } else version (FreeBSD) { - int readdir_r(DIR*, dirent*, dirent**); + version (GNU) + { + int readdir_r(DIR*, dirent*, dirent**); + } + else + { + static if (__FreeBSD_version >= 1200000) + pragma(mangle, "readdir_r@FBSD_1.5") int readdir_r(DIR*, dirent*, dirent**); + else + pragma(mangle, "readdir_r@FBSD_1.0") int readdir_r(DIR*, dirent*, dirent**); + } } else version (DragonFlyBSD) { @@ -559,8 +591,16 @@ version (CRuntime_Glibc) } else version (FreeBSD) { - void seekdir(DIR*, c_long); - c_long telldir(DIR*); + version (GNU) + { + void seekdir(DIR*, c_long); + c_long telldir(DIR*); + } + else + { + pragma(mangle, "seekdir@@FBSD_1.0") void seekdir(DIR*, c_long); + pragma(mangle, "telldir@@FBSD_1.0") c_long telldir(DIR*); + } } else version (NetBSD) { diff --git a/libphobos/libdruntime/core/sys/posix/dlfcn.d b/libphobos/libdruntime/core/sys/posix/dlfcn.d index 11113d36269..e97c7ea3960 100644 --- a/libphobos/libdruntime/core/sys/posix/dlfcn.d +++ b/libphobos/libdruntime/core/sys/posix/dlfcn.d @@ -14,7 +14,7 @@ */ module core.sys.posix.dlfcn; -private import core.sys.posix.config; +import core.sys.posix.config; version (OSX) version = Darwin; @@ -45,6 +45,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // XOpen (XSI) @@ -57,8 +58,8 @@ RTLD_LOCAL int dlclose(void*); char* dlerror(); -void* dlopen(in char*, int); -void* dlsym(void*, in char*); +void* dlopen(const scope char*, int); +void* dlsym(void*, const scope char*); */ version (CRuntime_Glibc) @@ -124,8 +125,8 @@ version (CRuntime_Glibc) int dlclose(void*); char* dlerror(); - void* dlopen(in char*, int); - void* dlsym(void*, in char*); + void* dlopen(const scope char*, int); + void* dlsym(void*, const scope char*); } else version (Darwin) { @@ -136,8 +137,8 @@ else version (Darwin) int dlclose(void*); char* dlerror(); - void* dlopen(in char*, int); - void* dlsym(void*, in char*); + void* dlopen(const scope char*, int); + void* dlsym(void*, const scope char*); int dladdr(void* addr, Dl_info* info); struct Dl_info @@ -180,8 +181,8 @@ else version (NetBSD) int dlclose(void*); char* dlerror(); - void* dlopen(in char*, int); - void* dlsym(void*, in char*); + void* dlopen(const scope char*, int); + void* dlsym(void*, const scope char*); int dladdr(const(void)* addr, Dl_info* info); struct Dl_info @@ -201,8 +202,8 @@ else version (OpenBSD) int dlclose(void*); char* dlerror(); - void* dlopen(in char*, int); - void* dlsym(void*, in char*); + void* dlopen(const scope char*, int); + void* dlsym(void*, const scope char*); int dladdr(const(void)* addr, Dl_info* info); struct Dl_info @@ -222,8 +223,8 @@ else version (DragonFlyBSD) int dlclose(void*); char* dlerror(); - void* dlopen(in char*, int); - void* dlsym(void*, in char*); + void* dlopen(const scope char*, int); + void* dlsym(void*, const scope char*); int dladdr(const(void)* addr, Dl_info* info); struct Dl_info @@ -243,8 +244,8 @@ else version (Solaris) int dlclose(void*); char* dlerror(); - void* dlopen(in char*, int); - void* dlsym(void*, in char*); + void* dlopen(const scope char*, int); + void* dlsym(void*, const scope char*); int dladdr(const(void)* addr, Dl_info* info); struct Dl_info @@ -265,11 +266,11 @@ else version (CRuntime_Bionic) RTLD_GLOBAL = 2 } - int dladdr(in void*, Dl_info*); + int dladdr(const scope void*, Dl_info*); int dlclose(void*); const(char)* dlerror(); - void* dlopen(in char*, int); - void* dlsym(void*, in char*); + void* dlopen(const scope char*, int); + void* dlsym(void*, const scope char*); struct Dl_info { @@ -291,8 +292,8 @@ else version (CRuntime_Musl) } int dlclose(void*); const(char)* dlerror(); - void* dlopen(in char*, int); - void* dlsym(void*, in char*); + void* dlopen(const scope char*, int); + void* dlsym(void*, const scope char*); } else version (CRuntime_UClibc) { @@ -331,6 +332,6 @@ else version (CRuntime_UClibc) int dlclose(void*); char* dlerror(); - void* dlopen(in char*, int); - void* dlsym(void*, in char*); + void* dlopen(const scope char*, int); + void* dlsym(void*, const scope char*); } diff --git a/libphobos/libdruntime/core/sys/posix/fcntl.d b/libphobos/libdruntime/core/sys/posix/fcntl.d index 9febcff849b..59df921ba41 100644 --- a/libphobos/libdruntime/core/sys/posix/fcntl.d +++ b/libphobos/libdruntime/core/sys/posix/fcntl.d @@ -14,8 +14,8 @@ */ module core.sys.posix.fcntl; -private import core.sys.posix.config; -private import core.stdc.stdint; +import core.sys.posix.config; +import core.stdc.stdint; public import core.sys.posix.sys.types; // for off_t, mode_t public import core.sys.posix.sys.stat; // for S_IFMT, etc. @@ -49,6 +49,7 @@ extern (C): nothrow: @nogc: +@system: // // Required @@ -96,9 +97,9 @@ struct flock pid_t l_pid; } -int creat(in char*, mode_t); +int creat(const scope char*, mode_t); int fcntl(int, int, ...); -int open(in char*, int, ...); +int open(const scope char*, int, ...); */ version (CRuntime_Glibc) { @@ -272,16 +273,16 @@ version (CRuntime_Glibc) static if ( __USE_FILE_OFFSET64 ) { - int creat64(in char*, mode_t); + int creat64(const scope char*, mode_t); alias creat64 creat; - int open64(in char*, int, ...); + int open64(const scope char*, int, ...); alias open64 open; } else { - int creat(in char*, mode_t); - int open(in char*, int, ...); + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); } enum AT_SYMLINK_NOFOLLOW = 0x100; @@ -331,8 +332,8 @@ else version (Darwin) short l_whence; } - int creat(in char*, mode_t); - int open(in char*, int, ...); + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); } else version (FreeBSD) { @@ -392,8 +393,8 @@ else version (FreeBSD) short l_whence; } - int creat(in char*, mode_t); - int open(in char*, int, ...); + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); enum AT_SYMLINK_NOFOLLOW = 0x200; enum AT_FDCWD = -100; @@ -457,8 +458,8 @@ else version (OpenBSD) short l_whence; } - int creat(in char*, mode_t); - int open(in char*, int, ...); + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); enum AT_FDCWD = -100; @@ -517,8 +518,8 @@ else version (NetBSD) } - int creat(in char*, mode_t); - int open(in char*, int, ...); + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); } else version (DragonFlyBSD) { @@ -604,8 +605,8 @@ else version (DragonFlyBSD) alias oflock = flock; - int creat(in char*, mode_t); - int open(in char*, int, ...); + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); //int fcntl(int, int, ...); /*defined below*/ //int flock(int, int); } @@ -694,8 +695,8 @@ else version (Solaris) version (D_LP64) { - int creat(in char*, mode_t); - int open(in char*, int, ...); + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); static if (__USE_LARGEFILE64) { @@ -707,16 +708,16 @@ else version (Solaris) { static if (__USE_LARGEFILE64) { - int creat64(in char*, mode_t); + int creat64(const scope char*, mode_t); alias creat64 creat; - int open64(in char*, int, ...); + int open64(const scope char*, int, ...); alias open64 open; } else { - int creat(in char*, mode_t); - int open(in char*, int, ...); + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); } } } @@ -772,8 +773,8 @@ else version (CRuntime_Bionic) pid_t l_pid; } - int creat(in char*, mode_t); - int open(in char*, int, ...); + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); enum AT_FDCWD = -100; } @@ -925,9 +926,13 @@ else version (CRuntime_Musl) pid_t l_pid; } enum FD_CLOEXEC = 1; - int open(in char*, int, ...); + int open(const scope char*, int, ...); enum AT_FDCWD = -100; + enum AT_SYMLINK_NOFOLLOW = 0x100; + enum AT_REMOVEDIR = 0x200; + enum AT_SYMLINK_FOLLOW = 0x400; + enum AT_EACCESS = 0x200; } else version (CRuntime_UClibc) { @@ -1037,16 +1042,16 @@ else version (CRuntime_UClibc) static if ( __USE_FILE_OFFSET64 ) { - int creat64(in char*, mode_t); + int creat64(const scope char*, mode_t); alias creat64 creat; - int open64(in char*, int, ...); + int open64(const scope char*, int, ...); alias open64 open; } else { - int creat(in char*, mode_t); - int open(in char*, int, ...); + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); } enum AT_SYMLINK_NOFOLLOW = 0x100; @@ -1057,9 +1062,9 @@ else static assert(false, "Unsupported platform"); } -//int creat(in char*, mode_t); +//int creat(const scope char*, mode_t); int fcntl(int, int, ...); -//int open(in char*, int, ...); +//int open(const scope char*, int, ...); // Generic Posix fallocate int posix_fallocate(int, off_t, off_t); diff --git a/libphobos/libdruntime/core/sys/posix/grp.d b/libphobos/libdruntime/core/sys/posix/grp.d index 41afeebf28b..92dcf34ee31 100644 --- a/libphobos/libdruntime/core/sys/posix/grp.d +++ b/libphobos/libdruntime/core/sys/posix/grp.d @@ -14,7 +14,7 @@ */ module core.sys.posix.grp; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for gid_t, uid_t version (OSX) @@ -30,6 +30,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // Required @@ -43,7 +44,7 @@ struct group char** gr_mem; } -group* getgrnam(in char*); +group* getgrnam(const scope char*); group* getgrgid(gid_t); */ @@ -152,50 +153,50 @@ else static assert(false, "Unsupported platform"); } -group* getgrnam(in char*); +group* getgrnam(const scope char*); group* getgrgid(gid_t); // // Thread-Safe Functions (TSF) // /* -int getgrnam_r(in char*, group*, char*, size_t, group**); +int getgrnam_r(const scope char*, group*, char*, size_t, group**); int getgrgid_r(gid_t, group*, char*, size_t, group**); */ version (CRuntime_Glibc) { - int getgrnam_r(in char*, group*, char*, size_t, group**); + int getgrnam_r(const scope char*, group*, char*, size_t, group**); int getgrgid_r(gid_t, group*, char*, size_t, group**); } else version (Darwin) { - int getgrnam_r(in char*, group*, char*, size_t, group**); + int getgrnam_r(const scope char*, group*, char*, size_t, group**); int getgrgid_r(gid_t, group*, char*, size_t, group**); } else version (FreeBSD) { - int getgrnam_r(in char*, group*, char*, size_t, group**); + int getgrnam_r(const scope char*, group*, char*, size_t, group**); int getgrgid_r(gid_t, group*, char*, size_t, group**); } else version (NetBSD) { - int getgrnam_r(in char*, group*, char*, size_t, group**); + int getgrnam_r(const scope char*, group*, char*, size_t, group**); int getgrgid_r(gid_t, group*, char*, size_t, group**); } else version (OpenBSD) { - int getgrnam_r(in char*, group*, char*, size_t, group**); + int getgrnam_r(const scope char*, group*, char*, size_t, group**); int getgrgid_r(gid_t, group*, char*, size_t, group**); } else version (DragonFlyBSD) { - int getgrnam_r(in char*, group*, char*, size_t, group**); + int getgrnam_r(const scope char*, group*, char*, size_t, group**); int getgrgid_r(gid_t, group*, char*, size_t, group**); } else version (Solaris) { - int getgrnam_r(in char*, group*, char*, int, group**); + int getgrnam_r(const scope char*, group*, char*, int, group**); int getgrgid_r(gid_t, group*, char*, int, group**); } else version (CRuntime_Bionic) @@ -203,12 +204,12 @@ else version (CRuntime_Bionic) } else version (CRuntime_UClibc) { - int getgrnam_r(in char*, group*, char*, size_t, group**); + int getgrnam_r(const scope char*, group*, char*, size_t, group**); int getgrgid_r(gid_t, group*, char*, size_t, group**); } else version (CRuntime_Musl) { - int getgrnam_r(in char*, group*, char*, size_t, group**); + int getgrnam_r(const scope char*, group*, char*, size_t, group**); int getgrgid_r(gid_t, group*, char*, size_t, group**); } else diff --git a/libphobos/libdruntime/core/sys/posix/iconv.d b/libphobos/libdruntime/core/sys/posix/iconv.d index 9ba6fddee7e..cea89870eca 100644 --- a/libphobos/libdruntime/core/sys/posix/iconv.d +++ b/libphobos/libdruntime/core/sys/posix/iconv.d @@ -34,18 +34,19 @@ version (Posix): extern (C): nothrow: @nogc: +@system: alias void* iconv_t; /// Allocate descriptor for code conversion from codeset FROMCODE to /// codeset TOCODE. -iconv_t iconv_open (in char* tocode, in char* fromcode); +iconv_t iconv_open (const scope char* tocode, const scope char* fromcode); /// Convert at most *INBYTESLEFT bytes from *INBUF according to the /// code conversion algorithm specified by CD and place up to /// *OUTBYTESLEFT bytes in buffer at *OUTBUF. -size_t iconv (iconv_t cd, in char** inbuf, +size_t iconv (iconv_t cd, const scope char** inbuf, size_t* inbytesleft, char** outbuf, size_t* outbytesleft); diff --git a/libphobos/libdruntime/core/sys/posix/inttypes.d b/libphobos/libdruntime/core/sys/posix/inttypes.d index 15863b4f35e..4bde28f015d 100644 --- a/libphobos/libdruntime/core/sys/posix/inttypes.d +++ b/libphobos/libdruntime/core/sys/posix/inttypes.d @@ -14,11 +14,12 @@ */ module core.sys.posix.inttypes; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.stdc.inttypes; version (Posix): extern (C) nothrow @nogc: +@system: // // Required @@ -26,15 +27,15 @@ extern (C) nothrow @nogc: /* intmax_t imaxabs(intmax_t); imaxdiv_t imaxdiv(intmax_t, intmax_t); -intmax_t strtoimax(in char*, char**, int); -uintmax_t strtoumax(in char*, char**, int); -intmax_t wcstoimax(in wchar_t*, wchar_t**, int); -uintmax_t wcstoumax(in wchar_t*, wchar_t**, int); +intmax_t strtoimax(const scope char*, char**, int); +uintmax_t strtoumax(const scope char*, char**, int); +intmax_t wcstoimax(const scope wchar_t*, wchar_t**, int); +uintmax_t wcstoumax(const scope wchar_t*, wchar_t**, int); */ intmax_t imaxabs(intmax_t); imaxdiv_t imaxdiv(intmax_t, intmax_t); -intmax_t strtoimax(in char*, char**, int); -uintmax_t strtoumax(in char*, char**, int); -intmax_t wcstoimax(in wchar_t*, wchar_t**, int); -uintmax_t wcstoumax(in wchar_t*, wchar_t**, int); +intmax_t strtoimax(const scope char*, char**, int); +uintmax_t strtoumax(const scope char*, char**, int); +intmax_t wcstoimax(const scope wchar_t*, wchar_t**, int); +uintmax_t wcstoumax(const scope wchar_t*, wchar_t**, int); diff --git a/libphobos/libdruntime/core/sys/posix/libgen.d b/libphobos/libdruntime/core/sys/posix/libgen.d index 6770cd828b3..b90765fcf80 100644 --- a/libphobos/libdruntime/core/sys/posix/libgen.d +++ b/libphobos/libdruntime/core/sys/posix/libgen.d @@ -15,6 +15,7 @@ module core.sys.posix.libgen; @nogc nothrow: +@system: extern (C): version (Posix): diff --git a/libphobos/libdruntime/core/sys/posix/locale.d b/libphobos/libdruntime/core/sys/posix/locale.d new file mode 100644 index 00000000000..172e9aa583c --- /dev/null +++ b/libphobos/libdruntime/core/sys/posix/locale.d @@ -0,0 +1,175 @@ +/** + * D header file for POSIX's . + * + * See_Also: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/locale.h.html + * Copyright: D Language Foundation, 2019 + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Authors: Mathias 'Geod24' Lang + * Standards: The Open Group Base Specifications Issue 7, 2018 edition + * Source: $(DRUNTIMESRC core/sys/posix/_locale.d) + */ +module core.sys.posix.locale; + +version (Posix): +extern(C): +@system: +nothrow: +@nogc: + +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + +version (Darwin) + version = DarwinBSDLocale; +version (FreeBSD) + version = DarwinBSDLocale; +version (NetBSD) + version = DarwinBSDLocale; +version (DragonflyBSD) + version = DarwinBSDLocale; + +/// +struct lconv +{ + char* currency_symbol; + char* decimal_point; + char frac_digits; + char* grouping; + char* int_curr_symbol; + char int_frac_digits; + char int_n_cs_precedes; + char int_n_sep_by_space; + char int_n_sign_posn; + char int_p_cs_precedes; + char int_p_sep_by_space; + char int_p_sign_posn; + char* mon_decimal_point; + char* mon_grouping; + char* mon_thousands_sep; + char* negative_sign; + char n_cs_precedes; + char n_sep_by_space; + char n_sign_posn; + char* positive_sign; + char p_cs_precedes; + char p_sep_by_space; + char p_sign_posn; + char* thousands_sep; +} + +/// Duplicate existing locale +locale_t duplocale(locale_t locale); +/// Free an allocated locale +void freelocale(locale_t locale); +/// Natural language formatting for C +lconv* localeconv(); +/// Create a new locale +locale_t newlocale(int mask, const char* locale, locale_t base); +/// Set the C library's notion of natural language formatting style +char* setlocale(int category, const char* locale); +/// Set the per-thread locale +locale_t uselocale (locale_t locale); + +version (DarwinBSDLocale) +{ + /// + enum + { + LC_ALL = 0, + LC_COLLATE = 1, + LC_CTYPE = 2, + LC_MESSAGES = 6, + LC_MONETARY = 3, + LC_NUMERIC = 4, + LC_TIME = 5, + } + + private struct _xlocale; + + /// + alias locale_t = _xlocale*; + + version (NetBSD) + enum LC_ALL_MASK = (cast(int)~0); + else + enum LC_ALL_MASK = ( + LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | + LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK); + + + /// + enum + { + LC_COLLATE_MASK = (1 << 0), + LC_CTYPE_MASK = (1 << 1), + LC_MESSAGES_MASK = (1 << 2), + LC_MONETARY_MASK = (1 << 3), + LC_NUMERIC_MASK = (1 << 4), + LC_TIME_MASK = (1 << 5), + } + + /// + enum LC_GLOBAL_LOCALE = (cast(locale_t)-1); +} + +version (linux) +{ + /// + enum + { + LC_ALL = 6, + LC_COLLATE = 3, + LC_CTYPE = 0, + LC_MESSAGES = 5, + LC_MONETARY = 4, + LC_NUMERIC = 1, + LC_TIME = 2, + + // Linux-specific + LC_PAPER = 7, + LC_NAME = 8, + LC_ADDRESS = 9, + LC_TELEPHONE = 10, + LC_MEASUREMENT = 11, + LC_IDENTIFICATION = 12, + } + + /// + enum + { + LC_ALL_MASK = (LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK | + LC_COLLATE_MASK | LC_MONETARY_MASK | LC_MESSAGES_MASK | + LC_PAPER_MASK | LC_NAME_MASK | LC_ADDRESS_MASK | + LC_TELEPHONE_MASK | LC_MEASUREMENT_MASK | + LC_IDENTIFICATION_MASK), + + LC_COLLATE_MASK = (1 << LC_COLLATE), + LC_CTYPE_MASK = (1 << LC_CTYPE), + LC_MESSAGES_MASK = (1 << LC_MESSAGES), + LC_MONETARY_MASK = (1 << LC_MONETARY), + LC_NUMERIC_MASK = (1 << LC_NUMERIC), + LC_TIME_MASK = (1 << LC_TIME), + + // Linux specific + LC_PAPER_MASK = (1 << LC_PAPER), + LC_NAME_MASK = (1 << LC_NAME), + LC_ADDRESS_MASK = (1 << LC_ADDRESS), + LC_TELEPHONE_MASK = (1 << LC_TELEPHONE), + LC_MEASUREMENT_MASK = (1 << LC_MEASUREMENT), + LC_IDENTIFICATION_MASK = (1 << LC_IDENTIFICATION), + } + + private struct __locale_struct; + + /// + alias locale_t = __locale_struct*; + + /// + enum LC_GLOBAL_LOCALE = (cast(locale_t)-1); +} diff --git a/libphobos/libdruntime/core/sys/posix/mqueue.d b/libphobos/libdruntime/core/sys/posix/mqueue.d index d5543768004..3b447a1a434 100644 --- a/libphobos/libdruntime/core/sys/posix/mqueue.d +++ b/libphobos/libdruntime/core/sys/posix/mqueue.d @@ -30,6 +30,7 @@ version (Posix): version (CRuntime_Glibc): extern (C): @nogc nothrow: +@system: /// Message queue descriptor. diff --git a/libphobos/libdruntime/core/sys/posix/net/if_.d b/libphobos/libdruntime/core/sys/posix/net/if_.d index e6eb57b7b47..3713673e4bc 100644 --- a/libphobos/libdruntime/core/sys/posix/net/if_.d +++ b/libphobos/libdruntime/core/sys/posix/net/if_.d @@ -14,7 +14,7 @@ */ module core.sys.posix.net.if_; -private import core.sys.posix.config; +import core.sys.posix.config; version (OSX) version = Darwin; @@ -40,7 +40,7 @@ struct if_nameindex // renamed to if_nameindex_t IF_NAMESIZE -uint if_nametoindex(in char*); +uint if_nametoindex(const scope char*); char* if_indextoname(uint, char*); if_nameindex_t* if_nameindex(); void if_freenameindex(if_nameindex_t*); @@ -56,7 +56,7 @@ version (CRuntime_Glibc) enum IF_NAMESIZE = 16; - uint if_nametoindex(in char*); + uint if_nametoindex(const scope char*); char* if_indextoname(uint, char*); if_nameindex_t* if_nameindex(); void if_freenameindex(if_nameindex_t*); @@ -71,7 +71,7 @@ else version (Darwin) enum IF_NAMESIZE = 16; - uint if_nametoindex(in char*); + uint if_nametoindex(const scope char*); char* if_indextoname(uint, char*); if_nameindex_t* if_nameindex(); void if_freenameindex(if_nameindex_t*); @@ -86,7 +86,7 @@ else version (FreeBSD) enum IF_NAMESIZE = 16; - uint if_nametoindex(in char*); + uint if_nametoindex(const scope char*); char* if_indextoname(uint, char*); if_nameindex_t* if_nameindex(); void if_freenameindex(if_nameindex_t*); @@ -101,7 +101,7 @@ else version (NetBSD) enum IF_NAMESIZE = 16; - uint if_nametoindex(in char*); + uint if_nametoindex(const scope char*); char* if_indextoname(uint, char*); if_nameindex_t* if_nameindex(); void if_freenameindex(if_nameindex_t*); @@ -116,7 +116,7 @@ else version (OpenBSD) enum IF_NAMESIZE = 16; - uint if_nametoindex(in char*); + uint if_nametoindex(const scope char*); char* if_indextoname(uint, char*); if_nameindex_t* if_nameindex(); void if_freenameindex(if_nameindex_t*); @@ -131,7 +131,7 @@ else version (DragonFlyBSD) enum IF_NAMESIZE = 16; - uint if_nametoindex(in char*); + uint if_nametoindex(const scope char*); char* if_indextoname(uint, char*); if_nameindex_t* if_nameindex(); void if_freenameindex(if_nameindex_t*); @@ -140,7 +140,7 @@ else version (CRuntime_Bionic) { enum IF_NAMESIZE = 16; - uint if_nametoindex(in char*); + uint if_nametoindex(const scope char*); char* if_indextoname(uint, char*); } else version (CRuntime_UClibc) @@ -153,7 +153,7 @@ else version (CRuntime_UClibc) enum IF_NAMESIZE = 16; - uint if_nametoindex(in char*); + uint if_nametoindex(const scope char*); char* if_indextoname(uint, char*); if_nameindex_t* if_nameindex(); void if_freenameindex(if_nameindex_t*); diff --git a/libphobos/libdruntime/core/sys/posix/netdb.d b/libphobos/libdruntime/core/sys/posix/netdb.d index f1251839b16..bede63843d8 100644 --- a/libphobos/libdruntime/core/sys/posix/netdb.d +++ b/libphobos/libdruntime/core/sys/posix/netdb.d @@ -14,7 +14,7 @@ */ module core.sys.posix.netdb; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.stdc.inttypes; // for uint32_t public import core.sys.posix.netinet.in_; // for in_port_t, in_addr_t public import core.sys.posix.sys.types; // for ino_t @@ -33,6 +33,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/netinet/in_.d b/libphobos/libdruntime/core/sys/posix/netinet/in_.d index ef20a8f9453..a58fa850d5d 100644 --- a/libphobos/libdruntime/core/sys/posix/netinet/in_.d +++ b/libphobos/libdruntime/core/sys/posix/netinet/in_.d @@ -14,7 +14,7 @@ */ module core.sys.posix.netinet.in_; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.stdc.inttypes; // for uint32_t, uint16_t, uint8_t public import core.sys.posix.arpa.inet; public import core.sys.posix.sys.socket; // for sa_family_t @@ -804,7 +804,7 @@ else version (FreeBSD) } // macros - extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -812,7 +812,7 @@ else version (FreeBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0); } - extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -820,7 +820,7 @@ else version (FreeBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1)); } - extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -829,58 +829,58 @@ else version (FreeBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1)); } - extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff)); } - extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80; } - extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0; } - extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xff; } - extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure + extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure { return a.s6_addr[1] & 0x0f; } - extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL; } - extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL; } - extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL; } - extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL; } - extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL; @@ -943,7 +943,7 @@ else version (NetBSD) } // macros - extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -951,7 +951,7 @@ else version (NetBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0); } - extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -959,7 +959,7 @@ else version (NetBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1)); } - extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -968,58 +968,58 @@ else version (NetBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1)); } - extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff)); } - extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80; } - extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0; } - extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xff; } - extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure + extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure { return a.s6_addr[1] & 0x0f; } - extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL; } - extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL; } - extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL; } - extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL; } - extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL; @@ -1082,7 +1082,7 @@ else version (OpenBSD) } // macros - extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -1090,7 +1090,7 @@ else version (OpenBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0); } - extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -1098,7 +1098,7 @@ else version (OpenBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1)); } - extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -1107,58 +1107,58 @@ else version (OpenBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1)); } - extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff)); } - extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80; } - extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0; } - extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xff; } - extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure + extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure { return a.s6_addr[1] & 0x0f; } - extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL; } - extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL; } - extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL; } - extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL; } - extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL; @@ -1221,7 +1221,7 @@ else version (DragonFlyBSD) } // macros - extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -1229,7 +1229,7 @@ else version (DragonFlyBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0); } - extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -1237,7 +1237,7 @@ else version (DragonFlyBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1)); } - extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -1246,58 +1246,58 @@ else version (DragonFlyBSD) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1)); } - extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff)); } - extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80; } - extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0; } - extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure { return a.s6_addr[0] == 0xff; } - extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure + extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure { return a.s6_addr[1] & 0x0f; } - extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL; } - extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL; } - extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL; } - extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL; } - extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure { return IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL; @@ -1350,67 +1350,67 @@ else version (Solaris) } // macros - extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure { return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) && (a.s6_addr32[2] == 0) && (a.s6_addr32[3] == 0); } - extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure { return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) && (a.s6_addr32[2] == 0) && (a.s6_addr32[3] == ntohl(1)); } - extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure { return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) && (a.s6_addr32[2] == 0) && (a.s6_addr32[3] != 0) && (a.s6_addr32[3] != ntohl(1)); } - extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure { return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) && (a.s6_addr32[2] == ntohl(0x0000ffff)); } - extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure { return a.s6_addr8[0] == 0xfe && (a.s6_addr8[1] & 0xc0) == 0x80; } - extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure { return a.s6_addr8[0] == 0xfe && (a.s6_addr8[1] & 0xc0) == 0xc0; } - extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure { return a.s6_addr8[0] == 0xff; } - extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure { return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x01; } - extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure { return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x02; } - extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure { return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x05; } - extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure { return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x08; } - extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure + extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure { return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x0e; } @@ -1470,7 +1470,7 @@ else version (CRuntime_Bionic) extern (D) pure { - bool IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) + bool IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -1478,7 +1478,7 @@ else version (CRuntime_Bionic) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0); } - bool IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) + bool IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -1486,7 +1486,7 @@ else version (CRuntime_Bionic) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1)); } - bool IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) + bool IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && @@ -1495,63 +1495,63 @@ else version (CRuntime_Bionic) (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1)); } - bool IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) + bool IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) { return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) && (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff)); } - bool IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) + bool IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) { return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80; } - bool IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) + bool IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) { return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0; } - bool IN6_IS_ADDR_ULA( in in6_addr* a ) + bool IN6_IS_ADDR_ULA( const scope in6_addr* a ) { return (a.s6_addr[0] & 0xfe) == 0xfc; } - bool IN6_IS_ADDR_MULTICAST( in in6_addr* a ) + bool IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) { return a.s6_addr[0] == 0xff; } - uint8_t IPV6_ADDR_MC_SCOPE( in in6_addr* a ) + uint8_t IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) { return a.s6_addr[1] & 0x0f; } - bool IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) + bool IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) { return IN6_IS_ADDR_MULTICAST(a) && IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL; } - bool IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) + bool IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) { return IN6_IS_ADDR_MULTICAST(a) && IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL; } - bool IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) + bool IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) { return IN6_IS_ADDR_MULTICAST(a) && IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL; } - bool IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) + bool IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) { return IN6_IS_ADDR_MULTICAST(a) && IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL; } - bool IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) + bool IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) { return IN6_IS_ADDR_MULTICAST(a) && IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL; diff --git a/libphobos/libdruntime/core/sys/posix/netinet/tcp.d b/libphobos/libdruntime/core/sys/posix/netinet/tcp.d index 134e133d1eb..d400d2d9a86 100644 --- a/libphobos/libdruntime/core/sys/posix/netinet/tcp.d +++ b/libphobos/libdruntime/core/sys/posix/netinet/tcp.d @@ -14,7 +14,7 @@ */ module core.sys.posix.netinet.tcp; -private import core.sys.posix.config; +import core.sys.posix.config; version (OSX) version = Darwin; diff --git a/libphobos/libdruntime/core/sys/posix/poll.d b/libphobos/libdruntime/core/sys/posix/poll.d index 9070eeed573..fdc41764a78 100644 --- a/libphobos/libdruntime/core/sys/posix/poll.d +++ b/libphobos/libdruntime/core/sys/posix/poll.d @@ -14,7 +14,7 @@ */ module core.sys.posix.poll; -private import core.sys.posix.config; +import core.sys.posix.config; version (OSX) version = Darwin; @@ -29,6 +29,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // XOpen (XSI) @@ -91,7 +92,7 @@ else version (Darwin) int fd; short events; short revents; - }; + } alias uint nfds_t; @@ -127,7 +128,7 @@ else version (FreeBSD) int fd; short events; short revents; - }; + } enum { @@ -161,7 +162,7 @@ else version (NetBSD) int fd; short events; short revents; - }; + } enum { @@ -195,7 +196,7 @@ else version (OpenBSD) int fd; short events; short revents; - }; + } enum { @@ -226,7 +227,7 @@ else version (DragonFlyBSD) int fd; short events; short revents; - }; + } enum { diff --git a/libphobos/libdruntime/core/sys/posix/pthread.d b/libphobos/libdruntime/core/sys/posix/pthread.d index 1d0d294f251..577fb71ace1 100644 --- a/libphobos/libdruntime/core/sys/posix/pthread.d +++ b/libphobos/libdruntime/core/sys/posix/pthread.d @@ -14,7 +14,7 @@ */ module core.sys.posix.pthread; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; public import core.sys.posix.sched; public import core.sys.posix.time; @@ -33,6 +33,7 @@ else version (WatchOS) version (Posix): extern (C) nothrow: +@system: // // Required @@ -55,23 +56,23 @@ PTHREAD_PROCESS_PRIVATE int pthread_atfork(void function(), void function(), void function()); int pthread_attr_destroy(pthread_attr_t*); -int pthread_attr_getdetachstate(in pthread_attr_t*, int*); -int pthread_attr_getschedparam(in pthread_attr_t*, sched_param*); +int pthread_attr_getdetachstate(const scope pthread_attr_t*, int*); +int pthread_attr_getschedparam(const scope pthread_attr_t*, sched_param*); int pthread_attr_init(pthread_attr_t*); int pthread_attr_setdetachstate(pthread_attr_t*, int); -int pthread_attr_setschedparam(in pthread_attr_t*, sched_param*); +int pthread_attr_setschedparam(const scope pthread_attr_t*, sched_param*); int pthread_cancel(pthread_t); void pthread_cleanup_push(void function(void*), void*); void pthread_cleanup_pop(int); int pthread_cond_broadcast(pthread_cond_t*); int pthread_cond_destroy(pthread_cond_t*); -int pthread_cond_init(in pthread_cond_t*, pthread_condattr_t*); +int pthread_cond_init(const scope pthread_cond_t*, pthread_condattr_t*); int pthread_cond_signal(pthread_cond_t*); -int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, in timespec*); +int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, const scope timespec*); int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*); int pthread_condattr_destroy(pthread_condattr_t*); int pthread_condattr_init(pthread_condattr_t*); -int pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*); +int pthread_create(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*); int pthread_detach(pthread_t); int pthread_equal(pthread_t, pthread_t); void pthread_exit(void*); @@ -88,7 +89,7 @@ int pthread_mutexattr_destroy(pthread_mutexattr_t*); int pthread_mutexattr_init(pthread_mutexattr_t*); int pthread_once(pthread_once_t*, void function()); int pthread_rwlock_destroy(pthread_rwlock_t*); -int pthread_rwlock_init(pthread_rwlock_t*, in pthread_rwlockattr_t*); +int pthread_rwlock_init(pthread_rwlock_t*, const scope pthread_rwlockattr_t*); int pthread_rwlock_rdlock(pthread_rwlock_t*); int pthread_rwlock_tryrdlock(pthread_rwlock_t*); int pthread_rwlock_trywrlock(pthread_rwlock_t*); @@ -99,7 +100,7 @@ int pthread_rwlockattr_init(pthread_rwlockattr_t*); pthread_t pthread_self(); int pthread_setcancelstate(int, int*); int pthread_setcanceltype(int, int*); -int pthread_setspecific(pthread_key_t, in void*); +int pthread_setspecific(pthread_key_t, const scope void*); void pthread_testcancel(); */ version (CRuntime_Glibc) @@ -330,7 +331,7 @@ else version (DragonFlyBSD) enum PTHREAD_MUTEX_INITIALIZER = null; //enum PTHREAD_ONCE_INIT = { PTHREAD_NEEDS_INIT, NULL }; - enum PTHREAD_ONCE_INIT = pthread_once_t.init;; + enum PTHREAD_ONCE_INIT = pthread_once_t.init; enum PTHREAD_COND_INITIALIZER = null; enum PTHREAD_RWLOCK_INITIALIZER = null; } @@ -444,11 +445,11 @@ int pthread_atfork(void function(), void function(), void function()); @nogc { int pthread_atfork(void function() @nogc, void function() @nogc, void function() @nogc); int pthread_attr_destroy(pthread_attr_t*); - int pthread_attr_getdetachstate(in pthread_attr_t*, int*); - int pthread_attr_getschedparam(in pthread_attr_t*, sched_param*); + int pthread_attr_getdetachstate(const scope pthread_attr_t*, int*); + int pthread_attr_getschedparam(const scope pthread_attr_t*, sched_param*); int pthread_attr_init(pthread_attr_t*); int pthread_attr_setdetachstate(pthread_attr_t*, int); - int pthread_attr_setschedparam(in pthread_attr_t*, sched_param*); + int pthread_attr_setschedparam(const scope pthread_attr_t*, sched_param*); int pthread_cancel(pthread_t); } @@ -716,13 +717,13 @@ else int pthread_cond_broadcast(pthread_cond_t*); int pthread_cond_destroy(pthread_cond_t*); -int pthread_cond_init(in pthread_cond_t*, pthread_condattr_t*) @trusted; +int pthread_cond_init(const scope pthread_cond_t*, pthread_condattr_t*) @trusted; int pthread_cond_signal(pthread_cond_t*); -int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, in timespec*); +int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, const scope timespec*); int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*); int pthread_condattr_destroy(pthread_condattr_t*); int pthread_condattr_init(pthread_condattr_t*); -int pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*); +int pthread_create(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*); int pthread_detach(pthread_t); int pthread_equal(pthread_t, pthread_t); void pthread_exit(void*); @@ -742,7 +743,7 @@ int pthread_mutexattr_destroy(pthread_mutexattr_t*); int pthread_mutexattr_init(pthread_mutexattr_t*) @trusted; int pthread_once(pthread_once_t*, void function()); int pthread_rwlock_destroy(pthread_rwlock_t*); -int pthread_rwlock_init(pthread_rwlock_t*, in pthread_rwlockattr_t*); +int pthread_rwlock_init(pthread_rwlock_t*, const scope pthread_rwlockattr_t*); int pthread_rwlock_rdlock(pthread_rwlock_t*); int pthread_rwlock_tryrdlock(pthread_rwlock_t*); int pthread_rwlock_trywrlock(pthread_rwlock_t*); @@ -753,7 +754,7 @@ int pthread_rwlockattr_init(pthread_rwlockattr_t*); pthread_t pthread_self(); int pthread_setcancelstate(int, int*); int pthread_setcanceltype(int, int*); -int pthread_setspecific(pthread_key_t, in void*); +int pthread_setspecific(pthread_key_t, const scope void*); void pthread_testcancel(); // @@ -763,10 +764,10 @@ void pthread_testcancel(); PTHREAD_BARRIER_SERIAL_THREAD int pthread_barrier_destroy(pthread_barrier_t*); -int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); +int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); -int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); (BAR|TSH) +int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); (BAR|TSH) int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); (BAR|TSH) */ @@ -776,10 +777,10 @@ version (CRuntime_Glibc) enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); - int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); + int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); - int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); + int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } @@ -788,10 +789,10 @@ else version (FreeBSD) enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); - int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); + int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); - int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); + int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } @@ -803,10 +804,10 @@ else version (DragonFlyBSD) enum PTHREAD_THREADS_MAX = c_ulong.max; int pthread_barrier_destroy(pthread_barrier_t*); - int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); + int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); - int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); + int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } @@ -815,10 +816,10 @@ else version (NetBSD) enum PTHREAD_BARRIER_SERIAL_THREAD = 1234567; int pthread_barrier_destroy(pthread_barrier_t*); - int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); + int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); - int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); + int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } @@ -827,10 +828,10 @@ else version (OpenBSD) enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); - int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); + int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); - int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); + int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } @@ -842,10 +843,10 @@ else version (Solaris) enum PTHREAD_BARRIER_SERIAL_THREAD = -2; int pthread_barrier_destroy(pthread_barrier_t*); - int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); + int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); - int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); + int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } @@ -857,10 +858,10 @@ else version (CRuntime_Musl) enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); - int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); + int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); - int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); + int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } @@ -869,10 +870,10 @@ else version (CRuntime_UClibc) enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); - int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); + int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); - int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); + int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } @@ -885,22 +886,22 @@ else // Clock (CS) // /* -int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*); +int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); int pthread_condattr_setclock(pthread_condattr_t*, clockid_t); */ version (CRuntime_Glibc) { - int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*); + int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); int pthread_condattr_setclock(pthread_condattr_t*, clockid_t); } else version (FreeBSD) { - int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*); + int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); int pthread_condattr_setclock(pthread_condattr_t*, clockid_t); } else version (DragonFlyBSD) { - int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*); + int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); int pthread_condattr_setclock(pthread_condattr_t*, clockid_t); } else version (NetBSD) @@ -909,7 +910,7 @@ else version (NetBSD) } else version (OpenBSD) { - int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*); + int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); int pthread_condattr_setclock(pthread_condattr_t*, clockid_t); } else version (Darwin) @@ -917,7 +918,7 @@ else version (Darwin) } else version (Solaris) { - int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*); + int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); int pthread_condattr_setclock(pthread_condattr_t*, clockid_t); } else version (CRuntime_Bionic) @@ -925,12 +926,12 @@ else version (CRuntime_Bionic) } else version (CRuntime_Musl) { - int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*); + int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); int pthread_condattr_setclock(pthread_condattr_t*, clockid_t); } else version (CRuntime_UClibc) { - int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*); + int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); int pthread_condattr_setclock(pthread_condattr_t*, clockid_t); } else @@ -1033,10 +1034,10 @@ PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_RECURSIVE -int pthread_attr_getguardsize(in pthread_attr_t*, size_t*); +int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); int pthread_attr_setguardsize(pthread_attr_t*, size_t); int pthread_getconcurrency(); -int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*); +int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_settype(pthread_mutexattr_t*, int); int pthread_setconcurrency(int); */ @@ -1048,10 +1049,10 @@ version (CRuntime_Glibc) enum PTHREAD_MUTEX_ERRORCHECK = 2; enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL; - int pthread_attr_getguardsize(in pthread_attr_t*, size_t*); + int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); int pthread_attr_setguardsize(pthread_attr_t*, size_t); int pthread_getconcurrency(); - int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted; int pthread_setconcurrency(int); } @@ -1062,10 +1063,10 @@ else version (Darwin) enum PTHREAD_MUTEX_RECURSIVE = 2; enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL; - int pthread_attr_getguardsize(in pthread_attr_t*, size_t*); + int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); int pthread_attr_setguardsize(pthread_attr_t*, size_t); int pthread_getconcurrency(); - int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted; int pthread_setconcurrency(int); } @@ -1081,7 +1082,7 @@ else version (FreeBSD) } enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK; - int pthread_attr_getguardsize(in pthread_attr_t*, size_t*); + int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); int pthread_attr_setguardsize(pthread_attr_t*, size_t); int pthread_getconcurrency(); int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*); @@ -1099,7 +1100,7 @@ else version (NetBSD) } enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK; - int pthread_attr_getguardsize(in pthread_attr_t*, size_t*); + int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); int pthread_attr_setguardsize(pthread_attr_t*, size_t); int pthread_getconcurrency(); int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*); @@ -1118,7 +1119,7 @@ else version (OpenBSD) } enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK; - int pthread_attr_getguardsize(in pthread_attr_t*, size_t*); + int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); int pthread_attr_setguardsize(pthread_attr_t*, size_t); int pthread_getconcurrency(); int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*); @@ -1136,7 +1137,7 @@ else version (DragonFlyBSD) } enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK; - int pthread_attr_getguardsize(in pthread_attr_t*, size_t*); + int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); int pthread_attr_setguardsize(pthread_attr_t*, size_t); int pthread_getconcurrency(); int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*); @@ -1154,7 +1155,7 @@ else version (Solaris) enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL; - int pthread_attr_getguardsize(in pthread_attr_t*, size_t*); + int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); int pthread_attr_setguardsize(pthread_attr_t*, size_t); int pthread_getconcurrency(); int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*); @@ -1168,9 +1169,9 @@ else version (CRuntime_Bionic) enum PTHREAD_MUTEX_ERRORCHECK = 2; enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL; - int pthread_attr_getguardsize(in pthread_attr_t*, size_t*); + int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); int pthread_attr_setguardsize(pthread_attr_t*, size_t); - int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted; } else version (CRuntime_Musl) @@ -1198,10 +1199,10 @@ else version (CRuntime_UClibc) PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP } - int pthread_attr_getguardsize(in pthread_attr_t*, size_t*); + int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); int pthread_attr_setguardsize(pthread_attr_t*, size_t); int pthread_getconcurrency(); - int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted; int pthread_setconcurrency(int); } @@ -1263,69 +1264,69 @@ else // Timeouts (TMO) // /* -int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*); -int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); -int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); +int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); +int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); +int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); */ version (CRuntime_Glibc) { - int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*); - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); + int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } else version (Darwin) { - int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*); - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); + int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } else version (FreeBSD) { - int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*); - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); + int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } else version (NetBSD) { - int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*); - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); + int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } else version (OpenBSD) { - int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*); - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); + int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } else version (DragonFlyBSD) { - int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*); - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); + int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } else version (Solaris) { - int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*); - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); + int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } else version (CRuntime_Bionic) { - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } else version (CRuntime_Musl) { - int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*); - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); + int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } else version (CRuntime_UClibc) { - int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*); - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*); + int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } else { @@ -1340,10 +1341,10 @@ PTHREAD_PRIO_INHERIT (TPI) PTHREAD_PRIO_NONE (TPP|TPI) PTHREAD_PRIO_PROTECT (TPI) -int pthread_mutex_getprioceiling(in pthread_mutex_t*, int*); (TPP) +int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*); (TPP) int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*); (TPP) int pthread_mutexattr_getprioceiling(pthread_mutexattr_t*, int*); (TPP) -int pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*); (TPI|TPP) +int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*); (TPI|TPP) int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int); (TPP) int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int); (TPI|TPP) */ @@ -1356,10 +1357,10 @@ version (Darwin) PTHREAD_PRIO_PROTECT } - int pthread_mutex_getprioceiling(in pthread_mutex_t*, int*); + int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*); int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*); - int pthread_mutexattr_getprioceiling(in pthread_mutexattr_t*, int*); - int pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_getprioceiling(const scope pthread_mutexattr_t*, int*); + int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int); int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int); } @@ -1372,10 +1373,10 @@ else version (Solaris) PTHREAD_PRIO_PROTECT = 0x20, } - int pthread_mutex_getprioceiling(in pthread_mutex_t*, int*); + int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*); int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*); - int pthread_mutexattr_getprioceiling(in pthread_mutexattr_t*, int*); - int pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_getprioceiling(const scope pthread_mutexattr_t*, int*); + int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int); int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int); } @@ -1387,14 +1388,14 @@ else version (Solaris) PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_SYSTEM -int pthread_attr_getinheritsched(in pthread_attr_t*, int*); -int pthread_attr_getschedpolicy(in pthread_attr_t*, int*); -int pthread_attr_getscope(in pthread_attr_t*, int*); +int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*); +int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); +int pthread_attr_getscope(const scope pthread_attr_t*, int*); int pthread_attr_setinheritsched(pthread_attr_t*, int); int pthread_attr_setschedpolicy(pthread_attr_t*, int); int pthread_attr_setscope(pthread_attr_t*, int); int pthread_getschedparam(pthread_t, int*, sched_param*); -int pthread_setschedparam(pthread_t, int, in sched_param*); +int pthread_setschedparam(pthread_t, int, const scope sched_param*); int pthread_setschedprio(pthread_t, int); */ @@ -1406,14 +1407,14 @@ version (CRuntime_Glibc) PTHREAD_SCOPE_PROCESS } - int pthread_attr_getinheritsched(in pthread_attr_t*, int*); - int pthread_attr_getschedpolicy(in pthread_attr_t*, int*); - int pthread_attr_getscope(in pthread_attr_t*, int*); + int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*); + int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); + int pthread_attr_getscope(const scope pthread_attr_t*, int*); int pthread_attr_setinheritsched(pthread_attr_t*, int); int pthread_attr_setschedpolicy(pthread_attr_t*, int); int pthread_attr_setscope(pthread_attr_t*, int); int pthread_getschedparam(pthread_t, int*, sched_param*); - int pthread_setschedparam(pthread_t, int, in sched_param*); + int pthread_setschedparam(pthread_t, int, const scope sched_param*); int pthread_setschedprio(pthread_t, int); } else version (Darwin) @@ -1424,14 +1425,14 @@ else version (Darwin) PTHREAD_SCOPE_PROCESS = 2 } - int pthread_attr_getinheritsched(in pthread_attr_t*, int*); - int pthread_attr_getschedpolicy(in pthread_attr_t*, int*); - int pthread_attr_getscope(in pthread_attr_t*, int*); + int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*); + int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); + int pthread_attr_getscope(const scope pthread_attr_t*, int*); int pthread_attr_setinheritsched(pthread_attr_t*, int); int pthread_attr_setschedpolicy(pthread_attr_t*, int); int pthread_attr_setscope(pthread_attr_t*, int); int pthread_getschedparam(pthread_t, int*, sched_param*); - int pthread_setschedparam(pthread_t, int, in sched_param*); + int pthread_setschedparam(pthread_t, int, const scope sched_param*); // int pthread_setschedprio(pthread_t, int); // not implemented } else version (FreeBSD) @@ -1442,12 +1443,12 @@ else version (FreeBSD) PTHREAD_SCOPE_SYSTEM = 0x2 } - int pthread_attr_getinheritsched(in pthread_attr_t*, int*); - int pthread_attr_getschedpolicy(in pthread_attr_t*, int*); - int pthread_attr_getscope(in pthread_attr_t*, int*); + int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*); + int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); + int pthread_attr_getscope(const scope pthread_attr_t*, int*); int pthread_attr_setinheritsched(pthread_attr_t*, int); int pthread_attr_setschedpolicy(pthread_attr_t*, int); - int pthread_attr_setscope(in pthread_attr_t*, int); + int pthread_attr_setscope(const scope pthread_attr_t*, int); int pthread_getschedparam(pthread_t, int*, sched_param*); int pthread_setschedparam(pthread_t, int, sched_param*); // int pthread_setschedprio(pthread_t, int); // not implemented @@ -1460,12 +1461,12 @@ else version (NetBSD) PTHREAD_SCOPE_SYSTEM = 0x1 } - int pthread_attr_getinheritsched(in pthread_attr_t*, int*); - int pthread_attr_getschedpolicy(in pthread_attr_t*, int*); - int pthread_attr_getscope(in pthread_attr_t*, int*); + int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*); + int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); + int pthread_attr_getscope(const scope pthread_attr_t*, int*); int pthread_attr_setinheritsched(pthread_attr_t*, int); int pthread_attr_setschedpolicy(pthread_attr_t*, int); - int pthread_attr_setscope(in pthread_attr_t*, int); + int pthread_attr_setscope(const scope pthread_attr_t*, int); int pthread_getschedparam(pthread_t, int*, sched_param*); int pthread_setschedparam(pthread_t, int, sched_param*); //int pthread_setschedprio(pthread_t, int); @@ -1478,12 +1479,12 @@ else version (OpenBSD) PTHREAD_SCOPE_SYSTEM = 0x2 } - int pthread_attr_getinheritsched(in pthread_attr_t*, int*); - int pthread_attr_getschedpolicy(in pthread_attr_t*, int*); - int pthread_attr_getscope(in pthread_attr_t*, int*); + int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*); + int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); + int pthread_attr_getscope(const scope pthread_attr_t*, int*); int pthread_attr_setinheritsched(pthread_attr_t*, int); int pthread_attr_setschedpolicy(pthread_attr_t*, int); - int pthread_attr_setscope(in pthread_attr_t*, int); + int pthread_attr_setscope(const scope pthread_attr_t*, int); int pthread_getschedparam(pthread_t, int*, sched_param*); int pthread_setschedparam(pthread_t, int, sched_param*); // int pthread_setschedprio(pthread_t, int); // not implemented @@ -1496,12 +1497,12 @@ else version (DragonFlyBSD) PTHREAD_SCOPE_SYSTEM = 0x2 } - int pthread_attr_getinheritsched(in pthread_attr_t*, int*); - int pthread_attr_getschedpolicy(in pthread_attr_t*, int*); - int pthread_attr_getscope(in pthread_attr_t*, int*); + int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*); + int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); + int pthread_attr_getscope(const scope pthread_attr_t*, int*); int pthread_attr_setinheritsched(pthread_attr_t*, int); int pthread_attr_setschedpolicy(pthread_attr_t*, int); - int pthread_attr_setscope(in pthread_attr_t*, int); + int pthread_attr_setscope(const scope pthread_attr_t*, int); int pthread_getschedparam(pthread_t, int*, sched_param*); int pthread_setschedparam(pthread_t, int, sched_param*); } @@ -1513,12 +1514,12 @@ else version (Solaris) PTHREAD_SCOPE_SYSTEM = 1, } - int pthread_attr_getinheritsched(in pthread_attr_t*, int*); - int pthread_attr_getschedpolicy(in pthread_attr_t*, int*); - int pthread_attr_getscope(in pthread_attr_t*, int*); + int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*); + int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); + int pthread_attr_getscope(const scope pthread_attr_t*, int*); int pthread_attr_setinheritsched(pthread_attr_t*, int); int pthread_attr_setschedpolicy(pthread_attr_t*, int); - int pthread_attr_setscope(in pthread_attr_t*, int); + int pthread_attr_setscope(const scope pthread_attr_t*, int); int pthread_getschedparam(pthread_t, int*, sched_param*); int pthread_setschedparam(pthread_t, int, sched_param*); int pthread_setschedprio(pthread_t, int); @@ -1531,12 +1532,12 @@ else version (CRuntime_Bionic) PTHREAD_SCOPE_PROCESS } - int pthread_attr_getschedpolicy(in pthread_attr_t*, int*); - int pthread_attr_getscope(in pthread_attr_t*); + int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); + int pthread_attr_getscope(const scope pthread_attr_t*); int pthread_attr_setschedpolicy(pthread_attr_t*, int); int pthread_attr_setscope(pthread_attr_t*, int); int pthread_getschedparam(pthread_t, int*, sched_param*); - int pthread_setschedparam(pthread_t, int, in sched_param*); + int pthread_setschedparam(pthread_t, int, const scope sched_param*); } else version (CRuntime_Musl) { @@ -1547,7 +1548,7 @@ else version (CRuntime_Musl) } int pthread_getschedparam(pthread_t, int*, sched_param*); - int pthread_setschedparam(pthread_t, int, in sched_param*); + int pthread_setschedparam(pthread_t, int, const scope sched_param*); int pthread_setschedprio(pthread_t, int); } else version (CRuntime_UClibc) @@ -1558,14 +1559,14 @@ else version (CRuntime_UClibc) PTHREAD_SCOPE_PROCESS } - int pthread_attr_getinheritsched(in pthread_attr_t*, int*); - int pthread_attr_getschedpolicy(in pthread_attr_t*, int*); - int pthread_attr_getscope(in pthread_attr_t*, int*); + int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*); + int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); + int pthread_attr_getscope(const scope pthread_attr_t*, int*); int pthread_attr_setinheritsched(pthread_attr_t*, int); int pthread_attr_setschedpolicy(pthread_attr_t*, int); int pthread_attr_setscope(pthread_attr_t*, int); int pthread_getschedparam(pthread_t, int*, sched_param*); - int pthread_setschedparam(pthread_t, int, in sched_param*); + int pthread_setschedparam(pthread_t, int, const scope sched_param*); int pthread_setschedprio(pthread_t, int); } else @@ -1577,9 +1578,9 @@ else // Stack (TSA|TSS) // /* -int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); (TSA|TSS) -int pthread_attr_getstackaddr(in pthread_attr_t*, void**); (TSA) -int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); (TSS) +int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); (TSA|TSS) +int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); (TSA) +int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); (TSS) int pthread_attr_setstack(pthread_attr_t*, void*, size_t); (TSA|TSS) int pthread_attr_setstackaddr(pthread_attr_t*, void*); (TSA) int pthread_attr_setstacksize(pthread_attr_t*, size_t); (TSS) @@ -1587,86 +1588,86 @@ int pthread_attr_setstacksize(pthread_attr_t*, size_t); (TSS) version (CRuntime_Glibc) { - int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); - int pthread_attr_getstackaddr(in pthread_attr_t*, void**); - int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); + int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); + int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); int pthread_attr_setstack(pthread_attr_t*, void*, size_t); int pthread_attr_setstackaddr(pthread_attr_t*, void*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); } else version (Darwin) { - int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); - int pthread_attr_getstackaddr(in pthread_attr_t*, void**); - int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); + int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); + int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); int pthread_attr_setstack(pthread_attr_t*, void*, size_t); int pthread_attr_setstackaddr(pthread_attr_t*, void*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); } else version (FreeBSD) { - int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); - int pthread_attr_getstackaddr(in pthread_attr_t*, void**); - int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); + int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); + int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); int pthread_attr_setstack(pthread_attr_t*, void*, size_t); int pthread_attr_setstackaddr(pthread_attr_t*, void*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); } else version (NetBSD) { - int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); - int pthread_attr_getstackaddr(in pthread_attr_t*, void**); - int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); + int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); + int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); int pthread_attr_setstack(pthread_attr_t*, void*, size_t); int pthread_attr_setstackaddr(pthread_attr_t*, void*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); } else version (OpenBSD) { - int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); - int pthread_attr_getstackaddr(in pthread_attr_t*, void**); - int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); + int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); + int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); int pthread_attr_setstack(pthread_attr_t*, void*, size_t); int pthread_attr_setstackaddr(pthread_attr_t*, void*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); } else version (DragonFlyBSD) { - int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); - int pthread_attr_getstackaddr(in pthread_attr_t*, void**); - int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); + int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); + int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); int pthread_attr_setstack(pthread_attr_t*, void*, size_t); int pthread_attr_setstackaddr(pthread_attr_t*, void*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); } else version (Solaris) { - int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); - int pthread_attr_getstackaddr(in pthread_attr_t*, void**); - int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); + int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); + int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); int pthread_attr_setstack(pthread_attr_t*, void*, size_t); int pthread_attr_setstackaddr(pthread_attr_t*, void*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); } else version (CRuntime_Bionic) { - int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); - int pthread_attr_getstackaddr(in pthread_attr_t*, void**); - int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); + int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); + int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); int pthread_attr_setstack(pthread_attr_t*, void*, size_t); int pthread_attr_setstackaddr(pthread_attr_t*, void*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); } else version (CRuntime_Musl) { - int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); } else version (CRuntime_UClibc) { - int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); - int pthread_attr_getstackaddr(in pthread_attr_t*, void**); - int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); + int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); + int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); int pthread_attr_setstack(pthread_attr_t*, void*, size_t); int pthread_attr_setstackaddr(pthread_attr_t*, void*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); @@ -1680,39 +1681,39 @@ else // Shared Synchronization (TSH) // /* -int pthread_condattr_getpshared(in pthread_condattr_t*, int*); +int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*); int pthread_condattr_setpshared(pthread_condattr_t*, int); -int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*); +int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); -int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*); +int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); */ version (CRuntime_Glibc) { - int pthread_condattr_getpshared(in pthread_condattr_t*, int*); + int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*); int pthread_condattr_setpshared(pthread_condattr_t*, int); - int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); - int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*); + int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); } else version (FreeBSD) { - int pthread_condattr_getpshared(in pthread_condattr_t*, int*); + int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*); int pthread_condattr_setpshared(pthread_condattr_t*, int); - int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); - int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*); + int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); } else version (NetBSD) { - int pthread_condattr_getpshared(in pthread_condattr_t*, int*); + int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*); int pthread_condattr_setpshared(pthread_condattr_t*, int); - int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); - int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*); + int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); } else version (OpenBSD) @@ -1720,29 +1721,29 @@ else version (OpenBSD) } else version (DragonFlyBSD) { - int pthread_condattr_getpshared(in pthread_condattr_t*, int*); + int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*); int pthread_condattr_setpshared(pthread_condattr_t*, int); - int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); - int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*); + int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); } else version (Darwin) { - int pthread_condattr_getpshared(in pthread_condattr_t*, int*); + int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*); int pthread_condattr_setpshared(pthread_condattr_t*, int); - int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); - int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*); + int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); } else version (Solaris) { - int pthread_condattr_getpshared(in pthread_condattr_t*, int*); + int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*); int pthread_condattr_setpshared(pthread_condattr_t*, int); - int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); - int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*); + int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); } else version (CRuntime_Bionic) @@ -1765,11 +1766,11 @@ else version (CRuntime_Musl) } else version (CRuntime_UClibc) { - int pthread_condattr_getpshared(in pthread_condattr_t*, int*); + int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*); int pthread_condattr_setpshared(pthread_condattr_t*, int); - int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*); + int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*); int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); - int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*); + int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); } else diff --git a/libphobos/libdruntime/core/sys/posix/pwd.d b/libphobos/libdruntime/core/sys/posix/pwd.d index 9d9aaa3b361..e7ddda79973 100644 --- a/libphobos/libdruntime/core/sys/posix/pwd.d +++ b/libphobos/libdruntime/core/sys/posix/pwd.d @@ -14,7 +14,7 @@ */ module core.sys.posix.pwd; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for gid_t, uid_t version (OSX) @@ -30,6 +30,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // Required @@ -44,7 +45,7 @@ struct passwd char* pw_shell; } -passwd* getpwnam(in char*); +passwd* getpwnam(const scope char*); passwd* getpwuid(uid_t); */ @@ -201,47 +202,47 @@ else static assert(false, "Unsupported platform"); } -passwd* getpwnam(in char*); +passwd* getpwnam(const scope char*); passwd* getpwuid(uid_t); // // Thread-Safe Functions (TSF) // /* -int getpwnam_r(in char*, passwd*, char*, size_t, passwd**); +int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**); int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); */ version (CRuntime_Glibc) { - int getpwnam_r(in char*, passwd*, char*, size_t, passwd**); + int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**); int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); } else version (Darwin) { - int getpwnam_r(in char*, passwd*, char*, size_t, passwd**); + int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**); int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); } else version (FreeBSD) { - int getpwnam_r(in char*, passwd*, char*, size_t, passwd**); + int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**); int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); } else version (NetBSD) { - int __getpwnam_r50(in char*, passwd*, char*, size_t, passwd**); + int __getpwnam_r50(const scope char*, passwd*, char*, size_t, passwd**); alias __getpwnam_r50 getpwnam_r; int __getpwuid_r50(uid_t, passwd*, char*, size_t, passwd**); alias __getpwuid_r50 getpwuid_r; } else version (OpenBSD) { - int getpwnam_r(in char*, passwd*, char*, size_t, passwd**); + int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**); int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); } else version (DragonFlyBSD) { - int getpwnam_r(in char*, passwd*, char*, size_t, passwd**); + int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**); int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); } else version (Solaris) @@ -250,7 +251,7 @@ else version (Solaris) alias getpwuid_r = __posix_getpwuid_r; // POSIX.1c standard version of the functions - int __posix_getpwnam_r(in char*, passwd*, char*, size_t, passwd**); + int __posix_getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**); int __posix_getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); } else version (CRuntime_Bionic) @@ -258,12 +259,12 @@ else version (CRuntime_Bionic) } else version (CRuntime_Musl) { - int getpwnam_r(in char*, passwd*, char*, size_t, passwd**); + int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**); int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); } else version (CRuntime_UClibc) { - int getpwnam_r(in char*, passwd*, char*, size_t, passwd**); + int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**); int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); } else diff --git a/libphobos/libdruntime/core/sys/posix/sched.d b/libphobos/libdruntime/core/sys/posix/sched.d index 9cf80bd7cf3..f9d286217fb 100644 --- a/libphobos/libdruntime/core/sys/posix/sched.d +++ b/libphobos/libdruntime/core/sys/posix/sched.d @@ -15,7 +15,7 @@ */ module core.sys.posix.sched; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.time; public import core.sys.posix.sys.types; @@ -32,6 +32,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // Required @@ -53,8 +54,8 @@ SCHED_OTHER int sched_getparam(pid_t, sched_param*); int sched_getscheduler(pid_t); -int sched_setparam(pid_t, in sched_param*); -int sched_setscheduler(pid_t, int, in sched_param*); +int sched_setparam(pid_t, const scope sched_param*); +int sched_setscheduler(pid_t, int, const scope sched_param*); */ version (CRuntime_Glibc) @@ -189,8 +190,8 @@ else int sched_getparam(pid_t, sched_param*); int sched_getscheduler(pid_t); -int sched_setparam(pid_t, in sched_param*); -int sched_setscheduler(pid_t, int, in sched_param*); +int sched_setparam(pid_t, const scope sched_param*); +int sched_setscheduler(pid_t, int, const scope sched_param*); // // Thread (THR) diff --git a/libphobos/libdruntime/core/sys/posix/semaphore.d b/libphobos/libdruntime/core/sys/posix/semaphore.d index cae47773989..4f6f63988ff 100644 --- a/libphobos/libdruntime/core/sys/posix/semaphore.d +++ b/libphobos/libdruntime/core/sys/posix/semaphore.d @@ -14,8 +14,8 @@ */ module core.sys.posix.semaphore; -private import core.sys.posix.config; -private import core.sys.posix.time; +import core.sys.posix.config; +import core.sys.posix.time; version (OSX) version = Darwin; @@ -30,6 +30,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // Required @@ -42,10 +43,10 @@ int sem_close(sem_t*); int sem_destroy(sem_t*); int sem_getvalue(sem_t*, int*); int sem_init(sem_t*, int, uint); -sem_t* sem_open(in char*, int, ...); +sem_t* sem_open(const scope char*, int, ...); int sem_post(sem_t*); int sem_trywait(sem_t*); -int sem_unlink(in char*); +int sem_unlink(const scope char*); int sem_wait(sem_t*); */ @@ -169,58 +170,58 @@ int sem_close(sem_t*); int sem_destroy(sem_t*); int sem_getvalue(sem_t*, int*); int sem_init(sem_t*, int, uint); -sem_t* sem_open(in char*, int, ...); +sem_t* sem_open(const scope char*, int, ...); int sem_post(sem_t*); int sem_trywait(sem_t*); -int sem_unlink(in char*); +int sem_unlink(const scope char*); int sem_wait(sem_t*); // // Timeouts (TMO) // /* -int sem_timedwait(sem_t*, in timespec*); +int sem_timedwait(sem_t*, const scope timespec*); */ version (CRuntime_Glibc) { - int sem_timedwait(sem_t*, in timespec*); + int sem_timedwait(sem_t*, const scope timespec*); } else version (Darwin) { - int sem_timedwait(sem_t*, in timespec*); + int sem_timedwait(sem_t*, const scope timespec*); } else version (FreeBSD) { - int sem_timedwait(sem_t*, in timespec*); + int sem_timedwait(sem_t*, const scope timespec*); } else version (NetBSD) { - int sem_timedwait(sem_t*, in timespec*); + int sem_timedwait(sem_t*, const scope timespec*); } else version (OpenBSD) { - int sem_timedwait(sem_t*, in timespec*); + int sem_timedwait(sem_t*, const scope timespec*); } else version (DragonFlyBSD) { - int sem_timedwait(sem_t*, in timespec*); + int sem_timedwait(sem_t*, const scope timespec*); } else version (Solaris) { - int sem_timedwait(sem_t*, in timespec*); + int sem_timedwait(sem_t*, const scope timespec*); } else version (CRuntime_Bionic) { - int sem_timedwait(sem_t*, in timespec*); + int sem_timedwait(sem_t*, const scope timespec*); } else version (CRuntime_Musl) { - int sem_timedwait(sem_t*, in timespec*); + int sem_timedwait(sem_t*, const scope timespec*); } else version (CRuntime_UClibc) { - int sem_timedwait(sem_t*, in timespec*); + int sem_timedwait(sem_t*, const scope timespec*); } else { diff --git a/libphobos/libdruntime/core/sys/posix/setjmp.d b/libphobos/libdruntime/core/sys/posix/setjmp.d index 38d4f7086f2..b98d321a883 100644 --- a/libphobos/libdruntime/core/sys/posix/setjmp.d +++ b/libphobos/libdruntime/core/sys/posix/setjmp.d @@ -14,11 +14,12 @@ */ module core.sys.posix.setjmp; -private import core.sys.posix.config; -private import core.sys.posix.signal; // for sigset_t +import core.sys.posix.config; +import core.sys.posix.signal; // for sigset_t version (Posix): extern (C) nothrow @nogc: +@system: version (RISCV32) version = RISCV_Any; version (RISCV64) version = RISCV_Any; @@ -151,7 +152,8 @@ version (CRuntime_Glibc) c_long __pc; c_long[12] __regs; c_long __sp; - double[12] __fpregs; + static if (__traits(getTargetInfo, "floatAbi") == "double") + double[12] __fpregs; } alias __jmp_buf = __riscv_jmp_buf[1]; } @@ -210,7 +212,7 @@ else version (FreeBSD) { enum _JBLEN = 31; // __int128_t - struct _jmp_buf { long[2][_JBLEN + 1] _jb; }; + struct _jmp_buf { long[2][_JBLEN + 1] _jb; } } else version (PPC_Any) { @@ -362,7 +364,7 @@ else version (CRuntime_UClibc) double[8] __fpregs; else double[6] __fpregs; - }; + } } else static assert(0, "unimplemented"); @@ -422,7 +424,7 @@ else version (FreeBSD) else version (AArch64) { // __int128_t - struct _sigjmp_buf { long[2][_JBLEN + 1] _jb; }; + struct _sigjmp_buf { long[2][_JBLEN + 1] _jb; } } else version (PPC_Any) { diff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d index 9a97709b473..44f45f2e0c3 100644 --- a/libphobos/libdruntime/core/sys/posix/signal.d +++ b/libphobos/libdruntime/core/sys/posix/signal.d @@ -11,7 +11,7 @@ module core.sys.posix.signal; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.stdc.signal; public import core.sys.posix.sys.types; // for pid_t //public import core.sys.posix.time; // for timespec, now defined here @@ -43,7 +43,8 @@ version (X86_64) version = X86_Any; version (Posix): extern (C): -//nothrow: // this causes Issue 12738 +//nothrow: // this causes http://issues.dlang.org/show_bug.cgi?id=12738 (which has been fixed) +//@system: // // Required @@ -150,30 +151,6 @@ version (Solaris) return sig; } } -else version (CRuntime_Glibc) -{ - private extern (C) nothrow @nogc - { - int __libc_current_sigrtmin(); - int __libc_current_sigrtmax(); - } - - @property int SIGRTMIN() nothrow @nogc { - __gshared static int sig = -1; - if (sig == -1) { - sig = __libc_current_sigrtmin(); - } - return sig; - } - - @property int SIGRTMAX() nothrow @nogc { - __gshared static int sig = -1; - if (sig == -1) { - sig = __libc_current_sigrtmax(); - } - return sig; - } -} else version (FreeBSD) { // Note: it appears that FreeBSD (prior to 7) and OSX do not support realtime signals // https://github.com/freebsd/freebsd/blob/e79c62ff68fc74d88cb6f479859f6fae9baa5101/sys/sys/signal.h#L117 @@ -189,9 +166,11 @@ else version (NetBSD) enum SIGRTMIN = 33; enum SIGRTMAX = 63; } -else version (CRuntime_Bionic) +else version (linux) { - // Switched to calling these functions since Lollipop + // Note: CRuntime_Bionic switched to calling these functions + // since Lollipop, and Glibc, UClib and Musl all implement them + // the same way since it's part of LSB. private extern (C) nothrow @nogc { int __libc_current_sigrtmin(); @@ -214,24 +193,6 @@ else version (CRuntime_Bionic) return sig; } } -else version (CRuntime_UClibc) -{ - private extern (C) nothrow @nogc - { - int __libc_current_sigrtmin(); - int __libc_current_sigrtmax(); - } - - @property int SIGRTMIN() nothrow @nogc - { - return __libc_current_sigrtmin(); - } - - @property int SIGRTMAX() nothrow @nogc - { - return __libc_current_sigrtmax(); - } -} version (linux) { @@ -874,16 +835,16 @@ SI_ASYNCIO SI_MESGQ int kill(pid_t, int); -int sigaction(int, in sigaction_t*, sigaction_t*); +int sigaction(int, const scope sigaction_t*, sigaction_t*); int sigaddset(sigset_t*, int); int sigdelset(sigset_t*, int); int sigemptyset(sigset_t*); int sigfillset(sigset_t*); -int sigismember(in sigset_t*, int); +int sigismember(const scope sigset_t*, int); int sigpending(sigset_t*); -int sigprocmask(int, in sigset_t*, sigset_t*); -int sigsuspend(in sigset_t*); -int sigwait(in sigset_t*, int*); +int sigprocmask(int, const scope sigset_t*, sigset_t*); +int sigsuspend(const scope sigset_t*); +int sigwait(const scope sigset_t*, int*); */ nothrow @nogc @@ -1007,16 +968,16 @@ version (CRuntime_Glibc) } int kill(pid_t, int); - int sigaction(int, in sigaction_t*, sigaction_t*); + int sigaction(int, const scope sigaction_t*, sigaction_t*); int sigaddset(sigset_t*, int); int sigdelset(sigset_t*, int); int sigemptyset(sigset_t*); int sigfillset(sigset_t*); - int sigismember(in sigset_t*, int); + int sigismember(const scope sigset_t*, int); int sigpending(sigset_t*); - int sigprocmask(int, in sigset_t*, sigset_t*); - int sigsuspend(in sigset_t*); - int sigwait(in sigset_t*, int*); + int sigprocmask(int, const scope sigset_t*, sigset_t*); + int sigsuspend(const scope sigset_t*); + int sigwait(const scope sigset_t*, int*); } else version (Darwin) { @@ -1059,16 +1020,16 @@ else version (Darwin) enum SI_MESGQ = 0x10005; int kill(pid_t, int); - int sigaction(int, in sigaction_t*, sigaction_t*); + int sigaction(int, const scope sigaction_t*, sigaction_t*); int sigaddset(sigset_t*, int); int sigdelset(sigset_t*, int); int sigemptyset(sigset_t*); int sigfillset(sigset_t*); - int sigismember(in sigset_t*, int); + int sigismember(const scope sigset_t*, int); int sigpending(sigset_t*); - int sigprocmask(int, in sigset_t*, sigset_t*); - int sigsuspend(in sigset_t*); - int sigwait(in sigset_t*, int*); + int sigprocmask(int, const scope sigset_t*, sigset_t*); + int sigsuspend(const scope sigset_t*); + int sigwait(const scope sigset_t*, int*); } else version (FreeBSD) { @@ -1137,16 +1098,16 @@ else version (FreeBSD) enum SI_MESGQ = 0x10005; int kill(pid_t, int); - int sigaction(int, in sigaction_t*, sigaction_t*); + int sigaction(int, const scope sigaction_t*, sigaction_t*); int sigaddset(sigset_t*, int); int sigdelset(sigset_t*, int); int sigemptyset(sigset_t *); int sigfillset(sigset_t *); - int sigismember(in sigset_t*, int); + int sigismember(const scope sigset_t*, int); int sigpending(sigset_t *); - int sigprocmask(int, in sigset_t*, sigset_t*); - int sigsuspend(in sigset_t*); - int sigwait(in sigset_t*, int*); + int sigprocmask(int, const scope sigset_t*, sigset_t*); + int sigsuspend(const scope sigset_t*); + int sigwait(const scope sigset_t*, int*); } else version (NetBSD) { @@ -1223,16 +1184,16 @@ else version (NetBSD) enum SI_MESGQ = -4; int kill(pid_t, int); - int __sigaction14(int, in sigaction_t*, sigaction_t*); + int __sigaction14(int, const scope sigaction_t*, sigaction_t*); int __sigaddset14(sigset_t*, int); int __sigdelset14(sigset_t*, int); int __sigemptyset14(sigset_t *); int __sigfillset14(sigset_t *); - int __sigismember14(in sigset_t*, int); + int __sigismember14(const scope sigset_t*, int); int __sigpending14(sigset_t *); - int __sigprocmask14(int, in sigset_t*, sigset_t*); - int __sigsuspend14(in sigset_t*); - int sigwait(in sigset_t*, int*); + int __sigprocmask14(int, const scope sigset_t*, sigset_t*); + int __sigsuspend14(const scope sigset_t*); + int sigwait(const scope sigset_t*, int*); alias __sigaction14 sigaction; alias __sigaddset14 sigaddset; @@ -1309,16 +1270,16 @@ else version (OpenBSD) enum SI_TIMER = -3; int kill(pid_t, int); - int sigaction(int, in sigaction_t*, sigaction_t*); + int sigaction(int, const scope sigaction_t*, sigaction_t*); int sigaddset(sigset_t*, int); int sigdelset(sigset_t*, int); int sigemptyset(sigset_t *); int sigfillset(sigset_t *); - int sigismember(in sigset_t*, int); + int sigismember(const scope sigset_t*, int); int sigpending(sigset_t *); - int sigprocmask(int, in sigset_t*, sigset_t*); - int sigsuspend(in sigset_t*); - int sigwait(in sigset_t*, int*); + int sigprocmask(int, const scope sigset_t*, sigset_t*); + int sigsuspend(const scope sigset_t*); + int sigwait(const scope sigset_t*, int*); } else version (DragonFlyBSD) { @@ -1358,16 +1319,16 @@ else version (DragonFlyBSD) enum SI_MESGQ = -4; int kill(pid_t, int); - int sigaction(int, in sigaction_t*, sigaction_t*); + int sigaction(int, const scope sigaction_t*, sigaction_t*); int sigaddset(sigset_t*, int); int sigdelset(sigset_t*, int); int sigemptyset(sigset_t *); int sigfillset(sigset_t *); - int sigismember(in sigset_t*, int); + int sigismember(const scope sigset_t*, int); int sigpending(sigset_t *); - int sigprocmask(int, in sigset_t*, sigset_t*); - int sigsuspend(in sigset_t*); - int sigwait(in sigset_t*, int*); + int sigprocmask(int, const scope sigset_t*, sigset_t*); + int sigsuspend(const scope sigset_t*); + int sigwait(const scope sigset_t*, int*); } else version (Solaris) { @@ -1467,21 +1428,21 @@ else version (Solaris) } int kill(pid_t, int); - int sigaction(int, in sigaction_t*, sigaction_t*); + int sigaction(int, const scope sigaction_t*, sigaction_t*); int sigaddset(sigset_t*, int); int sigdelset(sigset_t*, int); int sigemptyset(sigset_t*); int sigfillset(sigset_t*); - int sigismember(in sigset_t*, int); + int sigismember(const scope sigset_t*, int); int sigpending(sigset_t*); - int sigprocmask(int, in sigset_t*, sigset_t*); - int sigsuspend(in sigset_t*); - int sigwait(in sigset_t*, int*); + int sigprocmask(int, const scope sigset_t*, sigset_t*); + int sigsuspend(const scope sigset_t*); + int sigwait(const scope sigset_t*, int*); } else version (CRuntime_Bionic) { public import core.sys.posix.time: timer_t; - private import core.stdc.string : memset; + import core.stdc.string : memset; version (X86) { @@ -1581,7 +1542,7 @@ else version (CRuntime_Bionic) } int kill(pid_t, int); - int sigaction(int, in sigaction_t*, sigaction_t*); + int sigaction(int, const scope sigaction_t*, sigaction_t*); // These functions are defined inline in bionic. int sigaddset(sigset_t* set, int signum) @@ -1612,9 +1573,9 @@ else version (CRuntime_Bionic) } int sigpending(sigset_t*); - int sigprocmask(int, in sigset_t*, sigset_t*); - int sigsuspend(in sigset_t*); - int sigwait(in sigset_t*, int*); + int sigprocmask(int, const scope sigset_t*, sigset_t*); + int sigsuspend(const scope sigset_t*); + int sigwait(const scope sigset_t*, int*); } else version (CRuntime_Musl) { @@ -1724,16 +1685,16 @@ else version (CRuntime_Musl) } int kill(pid_t, int); - int sigaction(int, in sigaction_t*, sigaction_t*); + int sigaction(int, const scope sigaction_t*, sigaction_t*); int sigaddset(sigset_t*, int); int sigdelset(sigset_t*, int); int sigemptyset(sigset_t*); int sigfillset(sigset_t*); - int sigismember(in sigset_t*, int); + int sigismember(const scope sigset_t*, int); int sigpending(sigset_t*); - int sigprocmask(int, in sigset_t*, sigset_t*); - int sigsuspend(in sigset_t*); - int sigwait(in sigset_t*, int*); + int sigprocmask(int, const scope sigset_t*, sigset_t*); + int sigsuspend(const scope sigset_t*); + int sigwait(const scope sigset_t*, int*); } else version (CRuntime_UClibc) { @@ -1967,16 +1928,16 @@ else version (CRuntime_UClibc) } int kill(pid_t, int); - int sigaction(int, in sigaction_t*, sigaction_t*); + int sigaction(int, const scope sigaction_t*, sigaction_t*); int sigaddset(sigset_t*, int); int sigdelset(sigset_t*, int); int sigemptyset(sigset_t*); int sigfillset(sigset_t*); - int sigismember(in sigset_t*, int); + int sigismember(const scope sigset_t*, int); int sigpending(sigset_t*); - int sigprocmask(int, in sigset_t*, sigset_t*); - int sigsuspend(in sigset_t*); - int sigwait(in sigset_t*, int*); + int sigprocmask(int, const scope sigset_t*, sigset_t*); + int sigsuspend(const scope sigset_t*); + int sigwait(const scope sigset_t*, int*); } else { @@ -2069,7 +2030,7 @@ sigfn_t bsd_signal(int sig, sigfn_t func); sigfn_t sigset(int sig, sigfn_t func); int killpg(pid_t, int); -int sigaltstack(in stack_t*, stack_t*); +int sigaltstack(const scope stack_t*, stack_t*); int sighold(int); int sigignore(int); int siginterrupt(int, int); @@ -2261,7 +2222,7 @@ version (CRuntime_Glibc) sigfn_t2 sigset(int sig, sigfn_t2 func); int killpg(pid_t, int); - int sigaltstack(in stack_t*, stack_t*); + int sigaltstack(const scope stack_t*, stack_t*); int sighold(int); int sigignore(int); int siginterrupt(int, int); @@ -2371,7 +2332,7 @@ else version (Darwin) sigfn_t2 sigset(int sig, sigfn_t2 func); int killpg(pid_t, int); - int sigaltstack(in stack_t*, stack_t*); + int sigaltstack(const scope stack_t*, stack_t*); int sighold(int); int sigignore(int); int siginterrupt(int, int); @@ -2406,7 +2367,7 @@ else version (FreeBSD) enum MINSIGSTKSZ = 512 * 4; enum SIGSTKSZ = (MINSIGSTKSZ + 32768); -; + //ucontext_t (defined in core.sys.posix.ucontext) //mcontext_t (defined in core.sys.posix.ucontext) @@ -2495,7 +2456,7 @@ else version (FreeBSD) sigfn_t2 sigset(int sig, sigfn_t2 func); int killpg(pid_t, int); - int sigaltstack(in stack_t*, stack_t*); + int sigaltstack(const scope stack_t*, stack_t*); int sighold(int); int sigignore(int); int siginterrupt(int, int); @@ -2530,7 +2491,7 @@ else version (NetBSD) enum MINSIGSTKSZ = 8192; enum SIGSTKSZ = (MINSIGSTKSZ + 32768); -; + //ucontext_t (defined in core.sys.posix.ucontext) //mcontext_t (defined in core.sys.posix.ucontext) @@ -2619,7 +2580,7 @@ else version (NetBSD) sigfn_t2 sigset(int sig, sigfn_t2 func); int killpg(pid_t, int); - int sigaltstack(in stack_t*, stack_t*); + int sigaltstack(const scope stack_t*, stack_t*); int sighold(int); int sigignore(int); int siginterrupt(int, int); @@ -2738,7 +2699,7 @@ else version (OpenBSD) nothrow: @nogc: int killpg(pid_t, int); - int sigaltstack(in stack_t*, stack_t*); + int sigaltstack(const scope stack_t*, stack_t*); int siginterrupt(int, int); int sigpause(int); } @@ -2770,7 +2731,7 @@ else version (DragonFlyBSD) enum MINSIGSTKSZ = 8192; enum SIGSTKSZ = (MINSIGSTKSZ + 32768); -; + //ucontext_t (defined in core.sys.posix.ucontext) //mcontext_t (defined in core.sys.posix.ucontext) @@ -2859,7 +2820,7 @@ else version (DragonFlyBSD) sigfn_t2 sigset(int sig, sigfn_t2 func); int killpg(pid_t, int); - int sigaltstack(in stack_t*, stack_t*); + int sigaltstack(const scope stack_t*, stack_t*); int sighold(int); int sigignore(int); int siginterrupt(int, int); @@ -2983,7 +2944,7 @@ else version (Solaris) sigfn_t2 sigset(int sig, sigfn_t2 func); int killpg(pid_t, int); - int sigaltstack(in stack_t*, stack_t*); + int sigaltstack(const scope stack_t*, stack_t*); int sighold(int); int sigignore(int); int siginterrupt(int, int); @@ -3088,7 +3049,7 @@ else version (CRuntime_Bionic) sigfn_t2 bsd_signal(int, sigfn_t2); int killpg(int, int); - int sigaltstack(in stack_t*, stack_t*); + int sigaltstack(const scope stack_t*, stack_t*); int siginterrupt(int, int); } else version (CRuntime_Musl) @@ -3258,7 +3219,7 @@ else version (CRuntime_Musl) sigfn_t2 sigset(int sig, sigfn_t2 func); int killpg(pid_t, int); - int sigaltstack(in stack_t*, stack_t*); + int sigaltstack(const scope stack_t*, stack_t*); int sighold(int); int sigignore(int); int siginterrupt(int, int); @@ -3440,7 +3401,7 @@ else version (CRuntime_UClibc) sigfn_t2 sigset(int sig, sigfn_t2 func); int killpg(pid_t, int); - int sigaltstack(in stack_t*, stack_t*); + int sigaltstack(const scope stack_t*, stack_t*); int sighold(int); int sigignore(int); int siginterrupt(int, int); @@ -3543,8 +3504,8 @@ struct sigevent } int sigqueue(pid_t, int, in sigval); -int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*); -int sigwaitinfo(in sigset_t*, siginfo_t*); +int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); +int sigwaitinfo(const scope sigset_t*, siginfo_t*); */ nothrow: @@ -3583,8 +3544,8 @@ version (CRuntime_Glibc) } int sigqueue(pid_t, int, in sigval); - int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*); - int sigwaitinfo(in sigset_t*, siginfo_t*); + int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); + int sigwaitinfo(const scope sigset_t*, siginfo_t*); } else version (FreeBSD) { @@ -3606,8 +3567,8 @@ else version (FreeBSD) } int sigqueue(pid_t, int, in sigval); - int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*); - int sigwaitinfo(in sigset_t*, siginfo_t*); + int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); + int sigwaitinfo(const scope sigset_t*, siginfo_t*); } else version (NetBSD) { @@ -3621,8 +3582,8 @@ else version (NetBSD) } int sigqueue(pid_t, int, in sigval); - int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*); - int sigwaitinfo(in sigset_t*, siginfo_t*); + int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); + int sigwaitinfo(const scope sigset_t*, siginfo_t*); } else version (OpenBSD) { @@ -3636,14 +3597,14 @@ else version (DragonFlyBSD) int sigev_signo; int sigev_notify_kqueue; void /*pthread_attr_t*/ * sigev_notify_attributes; - }; + } union _sigval_t { int sival_int; void * sival_ptr; int sigval_int; void * sigval_ptr; - }; + } struct sigevent { int sigev_notify; @@ -3653,8 +3614,8 @@ else version (DragonFlyBSD) } int sigqueue(pid_t, int, in sigval); - int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*); - int sigwaitinfo(in sigset_t*, siginfo_t*); + int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); + int sigwaitinfo(const scope sigset_t*, siginfo_t*); } else version (Darwin) { @@ -3680,8 +3641,8 @@ else version (Solaris) } int sigqueue(pid_t, int, in sigval); - int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*); - int sigwaitinfo(in sigset_t*, siginfo_t*); + int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); + int sigwaitinfo(const scope sigset_t*, siginfo_t*); } else version (CRuntime_Bionic) { @@ -3757,8 +3718,8 @@ else version (CRuntime_UClibc) @property void* sigev_notify_attributes(ref sigevent _sigevent) { return _sigevent._sigev_un._sigev_thread._attribute; } int sigqueue(pid_t, int, in sigval); - int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*); - int sigwaitinfo(in sigset_t*, siginfo_t*); + int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); + int sigwaitinfo(const scope sigset_t*, siginfo_t*); } else { @@ -3770,58 +3731,58 @@ else // /* int pthread_kill(pthread_t, int); -int pthread_sigmask(int, in sigset_t*, sigset_t*); +int pthread_sigmask(int, const scope sigset_t*, sigset_t*); */ version (CRuntime_Glibc) { int pthread_kill(pthread_t, int); - int pthread_sigmask(int, in sigset_t*, sigset_t*); + int pthread_sigmask(int, const scope sigset_t*, sigset_t*); } else version (Darwin) { int pthread_kill(pthread_t, int); - int pthread_sigmask(int, in sigset_t*, sigset_t*); + int pthread_sigmask(int, const scope sigset_t*, sigset_t*); } else version (FreeBSD) { int pthread_kill(pthread_t, int); - int pthread_sigmask(int, in sigset_t*, sigset_t*); + int pthread_sigmask(int, const scope sigset_t*, sigset_t*); } else version (NetBSD) { int pthread_kill(pthread_t, int); - int pthread_sigmask(int, in sigset_t*, sigset_t*); + int pthread_sigmask(int, const scope sigset_t*, sigset_t*); } else version (OpenBSD) { int pthread_kill(pthread_t, int); - int pthread_sigmask(int, in sigset_t*, sigset_t*); + int pthread_sigmask(int, const scope sigset_t*, sigset_t*); } else version (DragonFlyBSD) { int pthread_kill(pthread_t, int); - int pthread_sigmask(int, in sigset_t*, sigset_t*); + int pthread_sigmask(int, const scope sigset_t*, sigset_t*); } else version (Solaris) { int pthread_kill(pthread_t, int); - int pthread_sigmask(int, in sigset_t*, sigset_t*); + int pthread_sigmask(int, const scope sigset_t*, sigset_t*); } else version (CRuntime_Bionic) { int pthread_kill(pthread_t, int); - int pthread_sigmask(int, in sigset_t*, sigset_t*); + int pthread_sigmask(int, const scope sigset_t*, sigset_t*); } else version (CRuntime_Musl) { int pthread_kill(pthread_t, int); - int pthread_sigmask(int, in sigset_t*, sigset_t*); + int pthread_sigmask(int, const scope sigset_t*, sigset_t*); } else version (CRuntime_UClibc) { int pthread_kill(pthread_t, int); - int pthread_sigmask(int, in sigset_t*, sigset_t*); + int pthread_sigmask(int, const scope sigset_t*, sigset_t*); int pthread_sigqueue(pthread_t, int, sigval); } else diff --git a/libphobos/libdruntime/core/sys/posix/spawn.d b/libphobos/libdruntime/core/sys/posix/spawn.d index aa59c2f0bf0..86b17517335 100644 --- a/libphobos/libdruntime/core/sys/posix/spawn.d +++ b/libphobos/libdruntime/core/sys/posix/spawn.d @@ -49,6 +49,7 @@ public import core.sys.posix.sched : sched_param; extern(C): @nogc: nothrow: +@system: int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t*, int); int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, int, int); diff --git a/libphobos/libdruntime/core/sys/posix/stdc/time.d b/libphobos/libdruntime/core/sys/posix/stdc/time.d new file mode 100644 index 00000000000..89029de09a8 --- /dev/null +++ b/libphobos/libdruntime/core/sys/posix/stdc/time.d @@ -0,0 +1,191 @@ +/** + * D header file for C99. + * + * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_time.h.html, _time.h) + * + * Copyright: Copyright Sean Kelly 2005 - 2009. + * License: Distributed under the + * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). + * (See accompanying file LICENSE) + * Authors: Sean Kelly, + * Alex Rønne Petersen + * Source: $(DRUNTIMESRC core/stdc/_time.d) + * Standards: ISO/IEC 9899:1999 (E) + */ + +module core.sys.posix.stdc.time; + +version (Posix): + +import core.stdc.config; + +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + +extern (C): +@trusted: // There are only a few functions here that use unsafe C strings. +nothrow: +@nogc: + +/// +struct tm +{ + int tm_sec; /// seconds after the minute [0-60] + int tm_min; /// minutes after the hour [0-59] + int tm_hour; /// hours since midnight [0-23] + int tm_mday; /// day of the month [1-31] + int tm_mon; /// months since January [0-11] + int tm_year; /// years since 1900 + int tm_wday; /// days since Sunday [0-6] + int tm_yday; /// days since January 1 [0-365] + int tm_isdst; /// Daylight Savings Time flag + c_long tm_gmtoff; /// offset from CUT in seconds + char* tm_zone; /// timezone abbreviation +} + +public import core.sys.posix.sys.types : time_t, clock_t; + +/// +version (OSX) +{ + enum clock_t CLOCKS_PER_SEC = 1_000_000; // was 100 until OSX 10.4/10.5 + version (X86) + extern (C) pragma(mangle, "clock$UNIX2003") clock_t clock(); + else + clock_t clock(); +} +else version (Darwin) // other Darwins (iOS, TVOS, WatchOS) +{ + enum clock_t CLOCKS_PER_SEC = 1_000_000; + clock_t clock(); +} +else version (FreeBSD) +{ + enum clock_t CLOCKS_PER_SEC = 128; + clock_t clock(); +} +else version (NetBSD) +{ + enum clock_t CLOCKS_PER_SEC = 100; + clock_t clock(); +} +else version (OpenBSD) +{ + enum clock_t CLOCKS_PER_SEC = 100; + clock_t clock(); +} +else version (DragonFlyBSD) +{ + enum clock_t CLOCKS_PER_SEC = 128; + clock_t clock(); +} +else version (Solaris) +{ + enum clock_t CLOCKS_PER_SEC = 1_000_000; + clock_t clock(); +} +else version (CRuntime_Glibc) +{ + enum clock_t CLOCKS_PER_SEC = 1_000_000; + clock_t clock(); +} +else version (CRuntime_Musl) +{ + enum clock_t CLOCKS_PER_SEC = 1_000_000; + clock_t clock(); +} +else version (CRuntime_Bionic) +{ + enum clock_t CLOCKS_PER_SEC = 1_000_000; + clock_t clock(); +} +else version (CRuntime_UClibc) +{ + enum clock_t CLOCKS_PER_SEC = 1_000_000; + clock_t clock(); +} +else +{ + static assert(0, "unsupported system"); +} + +version (Darwin) +{ + /// + void tzset(); // non-standard + /// + extern __gshared const(char)*[2] tzname; // non-standard +} +else version (CRuntime_Glibc) +{ + /// + void tzset(); // non-standard + /// + extern __gshared const(char)*[2] tzname; // non-standard +} +else version (FreeBSD) +{ + /// + void tzset(); // non-standard + /// + extern __gshared const(char)*[2] tzname; // non-standard +} +else version (NetBSD) +{ + /// + void tzset(); // non-standard + /// + extern __gshared const(char)*[2] tzname; // non-standard +} +else version (OpenBSD) +{ + /// + void tzset(); // non-standard + /// + extern __gshared const(char)*[2] tzname; // non-standard +} +else version (DragonFlyBSD) +{ + /// + void tzset(); // non-standard + /// + extern __gshared const(char)*[2] tzname; // non-standard +} +else version (Solaris) +{ + /// + void tzset(); + /// + extern __gshared const(char)*[2] tzname; +} +else version (CRuntime_Bionic) +{ + /// + void tzset(); + /// + extern __gshared const(char)*[2] tzname; +} +else version (CRuntime_Musl) +{ + /// + void tzset(); // non-standard + /// + extern __gshared const(char)*[2] tzname; // non-standard +} +else version (CRuntime_UClibc) +{ + /// + void tzset(); + /// + extern __gshared const(char)*[2] tzname; +} +else +{ + static assert(false, "Unsupported platform"); +} diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d index bc2329e6bf8..031bcb7341f 100644 --- a/libphobos/libdruntime/core/sys/posix/stdio.d +++ b/libphobos/libdruntime/core/sys/posix/stdio.d @@ -14,7 +14,7 @@ */ module core.sys.posix.stdio; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.stdc.stdio; public import core.sys.posix.sys.types; // for off_t @@ -32,6 +32,7 @@ extern (C): nothrow: @nogc: +@system: // // Required (defined in core.stdc.stdio) @@ -65,44 +66,44 @@ int fflush(FILE*); int fgetc(FILE*); int fgetpos(FILE*, fpos_t *); char* fgets(char*, int, FILE*); -FILE* fopen(in char*, in char*); -int fprintf(FILE*, in char*, ...); +FILE* fopen(const scope char*, const scope char*); +int fprintf(FILE*, const scope char*, ...); int fputc(int, FILE*); -int fputs(in char*, FILE*); +int fputs(const scope char*, FILE*); size_t fread(void *, size_t, size_t, FILE*); -FILE* freopen(in char*, in char*, FILE*); -int fscanf(FILE*, in char*, ...); +FILE* freopen(const scope char*, const scope char*, FILE*); +int fscanf(FILE*, const scope char*, ...); int fseek(FILE*, c_long, int); -int fsetpos(FILE*, in fpos_t*); +int fsetpos(FILE*, const scope fpos_t*); c_long ftell(FILE*); size_t fwrite(in void *, size_t, size_t, FILE*); int getc(FILE*); int getchar(); char* gets(char*); -void perror(in char*); -int printf(in char*, ...); +void perror(const scope char*); +int printf(const scope char*, ...); int putc(int, FILE*); int putchar(int); -int puts(in char*); -int remove(in char*); -int rename(in char*, in char*); +int puts(const scope char*); +int remove(const scope char*); +int rename(const scope char*, const scope char*); void rewind(FILE*); -int scanf(in char*, ...); +int scanf(const scope char*, ...); void setbuf(FILE*, char*); int setvbuf(FILE*, char*, int, size_t); -int snprintf(char*, size_t, in char*, ...); -int sprintf(char*, in char*, ...); -int sscanf(in char*, in char*, int ...); +int snprintf(char*, size_t, const scope char*, ...); +int sprintf(char*, const scope char*, ...); +int sscanf(const scope char*, const scope char*, int ...); FILE* tmpfile(); char* tmpnam(char*); int ungetc(int, FILE*); -int vfprintf(FILE*, in char*, va_list); -int vfscanf(FILE*, in char*, va_list); -int vprintf(in char*, va_list); -int vscanf(in char*, va_list); -int vsnprintf(char*, size_t, in char*, va_list); -int vsprintf(char*, in char*, va_list); -int vsscanf(in char*, in char*, va_list arg); +int vfprintf(FILE*, const scope char*, va_list); +int vfscanf(FILE*, const scope char*, va_list); +int vprintf(const scope char*, va_list); +int vscanf(const scope char*, va_list); +int vsnprintf(char*, size_t, const scope char*, va_list); +int vsprintf(char*, const scope char*, va_list); +int vsscanf(const scope char*, const scope char*, va_list arg); */ version (CRuntime_Glibc) @@ -117,15 +118,15 @@ version (CRuntime_Glibc) int fgetpos64(FILE*, fpos_t *); alias fgetpos64 fgetpos; - FILE* fopen64(in char*, in char*); + FILE* fopen64(const scope char*, const scope char*); alias fopen64 fopen; - FILE* freopen64(in char*, in char*, FILE*); + FILE* freopen64(const scope char*, const scope char*, FILE*); alias freopen64 freopen; int fseek(FILE*, c_long, int); - int fsetpos64(FILE*, in fpos_t*); + int fsetpos64(FILE*, const scope fpos_t*); alias fsetpos64 fsetpos; FILE* tmpfile64(); @@ -134,20 +135,20 @@ version (CRuntime_Glibc) else { int fgetpos(FILE*, fpos_t *); - FILE* fopen(in char*, in char*); - FILE* freopen(in char*, in char*, FILE*); + FILE* fopen(const scope char*, const scope char*); + FILE* freopen(const scope char*, const scope char*, FILE*); int fseek(FILE*, c_long, int); - int fsetpos(FILE*, in fpos_t*); + int fsetpos(FILE*, const scope fpos_t*); FILE* tmpfile(); } } else version (CRuntime_Bionic) { int fgetpos(FILE*, fpos_t *); - FILE* fopen(in char*, in char*); - FILE* freopen(in char*, in char*, FILE*); + FILE* fopen(const scope char*, const scope char*); + FILE* freopen(const scope char*, const scope char*, FILE*); int fseek(FILE*, c_long, int); - int fsetpos(FILE*, in fpos_t*); + int fsetpos(FILE*, const scope fpos_t*); } else version (CRuntime_UClibc) { @@ -156,15 +157,15 @@ else version (CRuntime_UClibc) int fgetpos64(FILE*, fpos_t *); alias fgetpos64 fgetpos; - FILE* fopen64(in char*, in char*); + FILE* fopen64(const scope char*, const scope char*); alias fopen64 fopen; - FILE* freopen64(in char*, in char*, FILE*); + FILE* freopen64(const scope char*, const scope char*, FILE*); alias freopen64 freopen; int fseek(FILE*, c_long, int); - int fsetpos64(FILE*, in fpos_t*); + int fsetpos64(FILE*, const scope fpos_t*); alias fsetpos64 fsetpos; FILE* tmpfile64(); @@ -173,10 +174,10 @@ else version (CRuntime_UClibc) else { int fgetpos(FILE*, fpos_t *); - FILE* fopen(in char*, in char*); - FILE* freopen(in char*, in char*, FILE*); + FILE* fopen(const scope char*, const scope char*); + FILE* freopen(const scope char*, const scope char*, FILE*); int fseek(FILE*, c_long, int); - int fsetpos(FILE*, in fpos_t*); + int fsetpos(FILE*, const scope fpos_t*); FILE* tmpfile(); } } @@ -187,15 +188,15 @@ else version (CRuntime_Musl) int fgetpos64(FILE*, fpos_t *); alias fgetpos64 fgetpos; - FILE* fopen64(in char*, in char*); + FILE* fopen64(const scope char*, const scope char*); alias fopen64 fopen; - FILE* freopen64(in char*, in char*, FILE*); + FILE* freopen64(const scope char*, const scope char*, FILE*); alias freopen64 freopen; int fseek(FILE*, c_long, int); - int fsetpos64(FILE*, in fpos_t*); + int fsetpos64(FILE*, const scope fpos_t*); alias fsetpos64 fsetpos; FILE* tmpfile64(); @@ -204,10 +205,10 @@ else version (CRuntime_Musl) else { int fgetpos(FILE*, fpos_t *); - FILE* fopen(in char*, in char*); - FILE* freopen(in char*, in char*, FILE*); + FILE* fopen(const scope char*, const scope char*); + FILE* freopen(const scope char*, const scope char*, FILE*); int fseek(FILE*, c_long, int); - int fsetpos(FILE*, in fpos_t*); + int fsetpos(FILE*, const scope fpos_t*); FILE* tmpfile(); } } @@ -218,15 +219,15 @@ else version (Solaris) int fgetpos64(FILE*, fpos_t *); alias fgetpos = fgetpos64; - FILE* fopen64(in char*, in char*); + FILE* fopen64(const scope char*, const scope char*); alias fopen = fopen64; - FILE* freopen64(in char*, in char*, FILE*); + FILE* freopen64(const scope char*, const scope char*, FILE*); alias freopen = freopen64; int fseek(FILE*, c_long, int); - int fsetpos64(FILE*, in fpos_t*); + int fsetpos64(FILE*, const scope fpos_t*); alias fsetpos = fsetpos64; FILE* tmpfile64(); @@ -235,10 +236,10 @@ else version (Solaris) else { int fgetpos(FILE*, fpos_t *); - FILE* fopen(in char*, in char*); - FILE* freopen(in char*, in char*, FILE*); + FILE* fopen(const scope char*, const scope char*); + FILE* freopen(const scope char*, const scope char*, FILE*); int fseek(FILE*, c_long, int); - int fsetpos(FILE*, in fpos_t*); + int fsetpos(FILE*, const scope fpos_t*); FILE* tmpfile(); } } @@ -249,64 +250,72 @@ else version (Solaris) /* L_ctermid -char* ctermid(char*); -FILE* fdopen(int, in char*); -int fileno(FILE*); -int fseeko(FILE*, off_t, int); -off_t ftello(FILE*); -char* gets(char*); -int pclose(FILE*); -FILE* popen(in char*, in char*); +char* ctermid(char*); +FILE* fdopen(int, const scope char*); +int fileno(FILE*); +int fseeko(FILE*, off_t, int); +off_t ftello(FILE*); +ssize_t getdelim(char**, size_t*, int, FILE*); +ssize_t getline(char**, size_t*, FILE*); +char* gets(char*); +int pclose(FILE*); +FILE* popen(const scope char*, const scope char*); */ version (CRuntime_Glibc) { enum L_ctermid = 9; - static if ( __USE_FILE_OFFSET64 ) - { - int fseeko64(FILE*, off_t, int); - alias fseeko64 fseeko; - } - else - { - int fseeko(FILE*, off_t, int); - } - - static if ( __USE_FILE_OFFSET64 ) - { - off_t ftello64(FILE*); - alias ftello64 ftello; - } - else - { - off_t ftello(FILE*); - } + static if ( __USE_FILE_OFFSET64 ) + { + int fseeko64(FILE*, off_t, int); + alias fseeko64 fseeko; + } + else + { + int fseeko(FILE*, off_t, int); + } + + static if ( __USE_FILE_OFFSET64 ) + { + off_t ftello64(FILE*); + alias ftello64 ftello; + } + else + { + off_t ftello(FILE*); + } + + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); } else version (CRuntime_UClibc) { enum L_ctermid = 9; enum L_cuserid = 9; - static if ( __USE_FILE_OFFSET64 ) - { - int fseeko64(FILE*, off_t, int); - alias fseeko64 fseeko; - } - else - { - int fseeko(FILE*, off_t, int); - } - - static if ( __USE_FILE_OFFSET64 ) - { - off_t ftello64(FILE*); - alias ftello64 ftello; - } - else - { - off_t ftello(FILE*); - } + static if ( __USE_FILE_OFFSET64 ) + { + int fseeko64(FILE*, off_t, int); + alias fseeko64 fseeko; + } + else + { + int fseeko(FILE*, off_t, int); + } + + static if ( __USE_FILE_OFFSET64 ) + { + off_t ftello64(FILE*); + alias ftello64 ftello; + } + else + { + off_t ftello(FILE*); + } + + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); } else version (CRuntime_Musl) { @@ -331,6 +340,91 @@ else version (CRuntime_Musl) { off_t ftello(FILE*); } + + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); +} +else version (CRuntime_Bionic) +{ + enum L_ctermid = 1024; + + static if ( __USE_FILE_OFFSET64 ) + { + int fseeko64(FILE*, off_t, int); + alias fseeko64 fseeko; + } + else + { + int fseeko(FILE*, off_t, int); + } + + static if ( __USE_FILE_OFFSET64 ) + { + off_t ftello64(FILE*); + alias ftello64 ftello; + } + else + { + off_t ftello(FILE*); + } + + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); +} +else version (Darwin) +{ + enum L_ctermid = 1024; + + int fseeko(FILE*, off_t, int); + off_t ftello(FILE*); + + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); +} +else version (FreeBSD) +{ + import core.sys.freebsd.config; + + enum L_ctermid = 1024; + + int fseeko(FILE*, off_t, int); + off_t ftello(FILE*); + + static if (__FreeBSD_version >= 800000) + { + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); + } +} +else version (NetBSD) +{ + enum L_ctermid = 1024; + + int fseeko(FILE*, off_t, int); + off_t ftello(FILE*); + + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); +} +else version (OpenBSD) +{ + enum L_ctermid = 1024; + + int fseeko(FILE*, off_t, int); + off_t ftello(FILE*); + + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); +} +else version (DragonFlyBSD) +{ + enum L_ctermid = 1024; + + int fseeko(FILE*, off_t, int); + off_t ftello(FILE*); + + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); } else version (Solaris) { @@ -356,6 +450,9 @@ else version (Solaris) { off_t ftello(FILE*); } + + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); } else version (Posix) { @@ -364,13 +461,11 @@ else version (Posix) } char* ctermid(char*); -FILE* fdopen(int, in char*); +FILE* fdopen(int, const scope char*); int fileno(FILE*); -//int fseeko(FILE*, off_t, int); -//off_t ftello(FILE*); char* gets(char*); int pclose(FILE*); -FILE* popen(in char*, in char*); +FILE* popen(const scope char*, const scope char*); // memstream functions are conforming to POSIX.1-2008. These functions are @@ -392,7 +487,7 @@ else version (CRuntime_Musl) version (HaveMemstream) { - FILE* fmemopen(in void* buf, in size_t size, in char* mode); + FILE* fmemopen(const scope void* buf, in size_t size, const scope char* mode); FILE* open_memstream(char** ptr, size_t* sizeloc); version (CRuntime_UClibc) {} else FILE* open_wmemstream(wchar_t** ptr, size_t* sizeloc); @@ -459,10 +554,10 @@ else version (CRuntime_UClibc) P_tmpdir va_list (defined in core.stdc.stdarg) -char* tempnam(in char*, in char*); +char* tempnam(const scope char*, const scope char*); */ -char* tempnam(in char*, in char*); +char* tempnam(const scope char*, const scope char*); version (CRuntime_Glibc) { @@ -546,7 +641,3 @@ unittest assert(memcmp(ptr, testdata.ptr, testdata.length*wchar_t.sizeof) == 0); assert(fclose(f) == 0); } - - -ssize_t getdelim (char** lineptr, size_t* n, int delimiter, FILE* stream); -ssize_t getline (char** lineptr, size_t* n, FILE* stream); diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d index a218f958077..4c10d4e0ed5 100644 --- a/libphobos/libdruntime/core/sys/posix/stdlib.d +++ b/libphobos/libdruntime/core/sys/posix/stdlib.d @@ -14,7 +14,7 @@ */ module core.sys.posix.stdlib; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.stdc.stdlib; public import core.sys.posix.sys.wait; @@ -31,6 +31,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // Required (defined in core.stdc.stdlib) @@ -51,37 +52,37 @@ void _Exit(int); void abort(); int abs(int); int atexit(void function()); -double atof(in char*); -int atoi(in char*); -c_long atol(in char*); -long atoll(in char*); -void* bsearch(in void*, in void*, size_t, size_t, int function(in void*, in void*)); +double atof(const scope char*); +int atoi(const scope char*); +c_long atol(const scope char*); +long atoll(const scope char*); +void* bsearch(const scope void*, const scope void*, size_t, size_t, int function(const scope void*, const scope void*)); void* calloc(size_t, size_t); div_t div(int, int); void exit(int); void free(void*); -char* getenv(in char*); +char* getenv(const scope char*); c_long labs(c_long); ldiv_t ldiv(c_long, c_long); long llabs(long); lldiv_t lldiv(long, long); void* malloc(size_t); -int mblen(in char*, size_t); -size_t mbstowcs(wchar_t*, in char*, size_t); -int mbtowc(wchar_t*, in char*, size_t); -void qsort(void*, size_t, size_t, int function(in void*, in void*)); +int mblen(const scope char*, size_t); +size_t mbstowcs(wchar_t*, const scope char*, size_t); +int mbtowc(wchar_t*, const scope char*, size_t); +void qsort(void*, size_t, size_t, int function(const scope void*, const scope void*)); int rand(); void* realloc(void*, size_t); void srand(uint); -double strtod(in char*, char**); -float strtof(in char*, char**); -c_long strtol(in char*, char**, int); -real strtold(in char*, char**); -long strtoll(in char*, char**, int); -c_ulong strtoul(in char*, char**, int); -ulong strtoull(in char*, char**, int); -int system(in char*); -size_t wcstombs(char*, in wchar_t*, size_t); +double strtod(const scope char*, char**); +float strtof(const scope char*, char**); +c_long strtol(const scope char*, char**, int); +real strtold(const scope char*, char**); +long strtoll(const scope char*, char**, int); +c_ulong strtoul(const scope char*, char**, int); +ulong strtoull(const scope char*, char**, int); +int system(const scope char*); +size_t wcstombs(char*, const scope wchar_t*, size_t); int wctomb(char*, wchar_t); */ @@ -138,75 +139,75 @@ else version (CRuntime_UClibc) // C Extension (CX) // /* -int setenv(in char*, in char*, int); -int unsetenv(in char*); +int setenv(const scope char*, const scope char*, int); +int unsetenv(const scope char*); */ version (CRuntime_Glibc) { - int setenv(in char*, in char*, int); - int unsetenv(in char*); + int setenv(const scope char*, const scope char*, int); + int unsetenv(const scope char*); void* valloc(size_t); // LEGACY non-standard } else version (Darwin) { - int setenv(in char*, in char*, int); - int unsetenv(in char*); + int setenv(const scope char*, const scope char*, int); + int unsetenv(const scope char*); void* valloc(size_t); // LEGACY non-standard } else version (FreeBSD) { - int setenv(in char*, in char*, int); - int unsetenv(in char*); + int setenv(const scope char*, const scope char*, int); + int unsetenv(const scope char*); void* valloc(size_t); // LEGACY non-standard } else version (NetBSD) { - int setenv(in char*, in char*, int); - int __unsetenv13(in char*); + int setenv(const scope char*, const scope char*, int); + int __unsetenv13(const scope char*); alias __unsetenv13 unsetenv; void* valloc(size_t); // LEGACY non-standard } else version (OpenBSD) { - int setenv(in char*, in char*, int); - int unsetenv(in char*); + int setenv(const scope char*, const scope char*, int); + int unsetenv(const scope char*); void* valloc(size_t); // LEGACY non-standard } else version (DragonFlyBSD) { - int setenv(in char*, in char*, int); - int unsetenv(in char*); + int setenv(const scope char*, const scope char*, int); + int unsetenv(const scope char*); void* valloc(size_t); // LEGACY non-standard } else version (CRuntime_Bionic) { - int setenv(in char*, in char*, int); - int unsetenv(in char*); + int setenv(const scope char*, const scope char*, int); + int unsetenv(const scope char*); void* valloc(size_t); } else version (Solaris) { - int setenv(in char*, in char*, int); - int unsetenv(in char*); + int setenv(const scope char*, const scope char*, int); + int unsetenv(const scope char*); void* valloc(size_t); // LEGACY non-standard } else version (CRuntime_Musl) { - int setenv(in char*, in char*, int); - int unsetenv(in char*); + int setenv(const scope char*, const scope char*, int); + int unsetenv(const scope char*); } else version (CRuntime_UClibc) { - int setenv(in char*, in char*, int); - int unsetenv(in char*); + int setenv(const scope char*, const scope char*, int); + int unsetenv(const scope char*); void* valloc(size_t); } @@ -263,14 +264,14 @@ WIFSTOPPED (defined in core.sys.posix.sys.wait) WSTOPSIG (defined in core.sys.posix.sys.wait) WTERMSIG (defined in core.sys.posix.sys.wait) -c_long a64l(in char*); +c_long a64l(const scope char*); double drand48(); char* ecvt(double, int, int *, int *); // LEGACY double erand48(ref ushort[3]); char* fcvt(double, int, int *, int *); // LEGACY char* gcvt(double, int, char*); // LEGACY // per spec: int getsubopt(char** char* const*, char**); -int getsubopt(char**, in char**, char**); +int getsubopt(char**, const scope char**, char**); int grantpt(int); char* initstate(uint, char*, size_t); c_long jrand48(ref ushort[3]); @@ -286,10 +287,10 @@ int posix_openpt(int); char* ptsname(int); int putenv(char*); c_long random(); -char* realpath(in char*, char*); +char* realpath(const scope char*, char*); ushort *seed48(ref ushort[3]); -void setkey(in char*); -char* setstate(in char*); +void setkey(const scope char*); +char* setstate(const scope char*); void srand48(c_long); void srandom(uint); int unlockpt(int); @@ -306,13 +307,13 @@ version (CRuntime_Glibc) //WSTOPSIG (defined in core.sys.posix.sys.wait) //WTERMSIG (defined in core.sys.posix.sys.wait) - c_long a64l(in char*); + c_long a64l(const scope char*); double drand48(); char* ecvt(double, int, int *, int *); // LEGACY double erand48(ref ushort[3]); char* fcvt(double, int, int *, int *); // LEGACY char* gcvt(double, int, char*); // LEGACY - int getsubopt(char**, in char**, char**); + int getsubopt(char**, const scope char**, char**); int grantpt(int); char* initstate(uint, char*, size_t); c_long jrand48(ref ushort[3]); @@ -328,10 +329,10 @@ version (CRuntime_Glibc) char* ptsname(int); int putenv(char*); c_long random(); - char* realpath(in char*, char*); + char* realpath(const scope char*, char*); ushort *seed48(ref ushort[3]); - void setkey(in char*); - char* setstate(in char*); + void setkey(const scope char*); + char* setstate(const scope char*); void srand48(c_long); void srandom(uint); int unlockpt(int); @@ -357,13 +358,13 @@ else version (Darwin) //WSTOPSIG (defined in core.sys.posix.sys.wait) //WTERMSIG (defined in core.sys.posix.sys.wait) - c_long a64l(in char*); + c_long a64l(const scope char*); double drand48(); char* ecvt(double, int, int *, int *); // LEGACY double erand48(ref ushort[3]); char* fcvt(double, int, int *, int *); // LEGACY char* gcvt(double, int, char*); // LEGACY - int getsubopt(char**, in char**, char**); + int getsubopt(char**, const scope char**, char**); int grantpt(int); char* initstate(uint, char*, size_t); c_long jrand48(ref ushort[3]); @@ -379,10 +380,10 @@ else version (Darwin) char* ptsname(int); int putenv(char*); c_long random(); - char* realpath(in char*, char*); + char* realpath(const scope char*, char*); ushort *seed48(ref ushort[3]); - void setkey(in char*); - char* setstate(in char*); + void setkey(const scope char*); + char* setstate(const scope char*); void srand48(c_long); void srandom(uint); int unlockpt(int); @@ -398,13 +399,13 @@ else version (FreeBSD) //WSTOPSIG (defined in core.sys.posix.sys.wait) //WTERMSIG (defined in core.sys.posix.sys.wait) - c_long a64l(in char*); + c_long a64l(const scope char*); double drand48(); //char* ecvt(double, int, int *, int *); // LEGACY double erand48(ref ushort[3]); //char* fcvt(double, int, int *, int *); // LEGACY //char* gcvt(double, int, char*); // LEGACY - int getsubopt(char**, in char**, char**); + int getsubopt(char**, const scope char**, char**); int grantpt(int); char* initstate(uint, char*, size_t); c_long jrand48(ref ushort[3]); @@ -420,10 +421,10 @@ else version (FreeBSD) char* ptsname(int); int putenv(char*); c_long random(); - char* realpath(in char*, char*); + char* realpath(const scope char*, char*); ushort *seed48(ref ushort[3]); - void setkey(in char*); - char* setstate(in char*); + void setkey(const scope char*); + char* setstate(const scope char*); void srand48(c_long); void srandom(uint); int unlockpt(int); @@ -439,13 +440,13 @@ else version (NetBSD) //WSTOPSIG (defined in core.sys.posix.sys.wait) //WTERMSIG (defined in core.sys.posix.sys.wait) - c_long a64l(in char*); + c_long a64l(const scope char*); double drand48(); //char* ecvt(double, int, int *, int *); // LEGACY double erand48(ref ushort[3]); //char* fcvt(double, int, int *, int *); // LEGACY //char* gcvt(double, int, char*); // LEGACY - int getsubopt(char**, in char**, char**); + int getsubopt(char**, const scope char**, char**); int grantpt(int); char* initstate(uint, char*, size_t); c_long jrand48(ref ushort[3]); @@ -461,10 +462,10 @@ else version (NetBSD) char* ptsname(int); int putenv(char*); c_long random(); - char* realpath(in char*, char*); + char* realpath(const scope char*, char*); ushort *seed48(ref ushort[3]); - void setkey(in char*); - char* setstate(in char*); + void setkey(const scope char*); + char* setstate(const scope char*); void srand48(c_long); void srandom(uint); int unlockpt(int); @@ -480,13 +481,13 @@ else version (OpenBSD) //WSTOPSIG (defined in core.sys.posix.sys.wait) //WTERMSIG (defined in core.sys.posix.sys.wait) - c_long a64l(in char*); + c_long a64l(const scope char*); double drand48(); //char* ecvt(double, int, int *, int *); // LEGACY double erand48(ref ushort[3]); //char* fcvt(double, int, int *, int *); // LEGACY //char* gcvt(double, int, char*); // LEGACY - int getsubopt(char**, in char**, char**); + int getsubopt(char**, const scope char**, char**); int grantpt(int); char* initstate(uint, char*, size_t); c_long jrand48(ref ushort[3]); @@ -502,10 +503,10 @@ else version (OpenBSD) char* ptsname(int); int putenv(char*); c_long random(); - char* realpath(in char*, char*); + char* realpath(const scope char*, char*); ushort *seed48(ref ushort[3]); - // void setkey(in char*); // not implemented - char* setstate(in char*); + // void setkey(const scope char*); // not implemented + char* setstate(const scope char*); void srand48(c_long); void srandom(uint); int unlockpt(int); @@ -521,13 +522,13 @@ else version (DragonFlyBSD) //WSTOPSIG (defined in core.sys.posix.sys.wait) //WTERMSIG (defined in core.sys.posix.sys.wait) - c_long a64l(in char*); + c_long a64l(const scope char*); double drand48(); //char* ecvt(double, int, int *, int *); // LEGACY double erand48(ref ushort[3]); //char* fcvt(double, int, int *, int *); // LEGACY //char* gcvt(double, int, char*); // LEGACY - int getsubopt(char**, in char**, char**); + int getsubopt(char**, const scope char**, char**); int grantpt(int); char* initstate(uint, char*, size_t); c_long jrand48(ref ushort[3]); @@ -543,10 +544,10 @@ else version (DragonFlyBSD) char* ptsname(int); int putenv(char*); c_long random(); - char* realpath(in char*, char*); + char* realpath(const scope char*, char*); ushort *seed48(ref ushort[3]); - void setkey(in char*); - char* setstate(in char*); + void setkey(const scope char*); + char* setstate(const scope char*); void srand48(c_long); void srandom(uint); int unlockpt(int); @@ -564,9 +565,9 @@ else version (CRuntime_Bionic) c_long mrand48(); c_long nrand48(ref ushort[3]); char* ptsname(int); - int putenv(in char*); + int putenv(const scope char*); c_long random() { return lrand48(); } - char* realpath(in char*, char*); + char* realpath(const scope char*, char*); ushort* seed48(ref ushort[3]); void srand48(c_long); void srandom(uint s) { srand48(s); } @@ -574,13 +575,13 @@ else version (CRuntime_Bionic) } else version (CRuntime_Musl) { - c_long a64l(in char*); + c_long a64l(const scope char*); double drand48(); char* ecvt(double, int, int *, int *); // LEGACY double erand48(ref ushort[3]); char* fcvt(double, int, int *, int *); // LEGACY char* gcvt(double, int, char*); // LEGACY - int getsubopt(char**, in char**, char**); + int getsubopt(char**, const scope char**, char**); int grantpt(int); char* initstate(uint, char*, size_t); c_long jrand48(ref ushort[3]); @@ -596,10 +597,10 @@ else version (CRuntime_Musl) char* ptsname(int); int putenv(char*); c_long random(); - char* realpath(in char*, char*); + char* realpath(const scope char*, char*); ushort *seed48(ref ushort[3]); - void setkey(in char*); - char* setstate(in char*); + void setkey(const scope char*); + char* setstate(const scope char*); void srand48(c_long); void srandom(uint); int unlockpt(int); @@ -626,13 +627,13 @@ else version (Solaris) //WSTOPSIG (defined in core.sys.posix.sys.wait) //WTERMSIG (defined in core.sys.posix.sys.wait) - c_long a64l(in char*); + c_long a64l(const scope char*); double drand48(); char* ecvt(double, int, int *, int *); // LEGACY double erand48(ref ushort[3]); char* fcvt(double, int, int *, int *); // LEGACY char* gcvt(double, int, char*); // LEGACY - int getsubopt(char**, in char**, char**); + int getsubopt(char**, const scope char**, char**); int grantpt(int); char* initstate(uint, char*, size_t); c_long jrand48(ref ushort[3]); @@ -648,10 +649,10 @@ else version (Solaris) char* ptsname(int); int putenv(char*); c_long random(); - char* realpath(in char*, char*); + char* realpath(const scope char*, char*); ushort *seed48(ref ushort[3]); - void setkey(in char*); - char* setstate(in char*); + void setkey(const scope char*); + char* setstate(const scope char*); void srand48(c_long); void srandom(uint); int unlockpt(int); @@ -675,13 +676,13 @@ else version (Solaris) } else version (CRuntime_UClibc) { - c_long a64l(in char*); + c_long a64l(const scope char*); double drand48(); char* ecvt(double, int, int *, int *); double erand48(ref ushort[3]); char* fcvt(double, int, int *, int *); char* gcvt(double, int, char*); - int getsubopt(char**, in char**, char**); + int getsubopt(char**, const scope char**, char**); int grantpt(int); char* initstate(uint, char*, size_t); c_long jrand48(ref ushort[3]); @@ -696,10 +697,10 @@ else version (CRuntime_UClibc) char* ptsname(int); int putenv(char*); c_long random(); - char* realpath(in char*, char*); + char* realpath(const scope char*, char*); ushort* seed48(ref ushort[3]); - void setkey(in char*); - char* setstate(in char*); + void setkey(const scope char*); + char* setstate(const scope char*); void srand48(c_long); void srandom(uint); int unlockpt(int); diff --git a/libphobos/libdruntime/core/sys/posix/string.d b/libphobos/libdruntime/core/sys/posix/string.d new file mode 100644 index 00000000000..e17dfc66d33 --- /dev/null +++ b/libphobos/libdruntime/core/sys/posix/string.d @@ -0,0 +1,52 @@ +/** + * D header file for POSIX's . + * + * Note: + * - The header shall define NULL and size_t as described in . + * However, D has builtin `null` and `size_t` is defined in `object`. + * + * See_Also: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/string.h.html + * Copyright: D Language Foundation, 2019 + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Authors: Mathias 'Geod24' Lang + * Standards: The Open Group Base Specifications Issue 7, 2018 edition + * Source: $(DRUNTIMESRC core/sys/posix/_string.d) + */ +module core.sys.posix.string; + +version (Posix): +extern(C): +@system: +nothrow: +@nogc: + +/// Exposes `locale_t` as defined in `core.sys.posix.locale` (``) +public import core.sys.posix.locale : locale_t; + +/** + * Exposes the C99 functions + * + * C extensions and XSI extensions are missing + */ +public import core.stdc.string; + +/// Copy string until character found +void* memccpy(return void* dst, scope const void* src, int c, size_t n); +/// Copy string (including terminating '\0') +char* stpcpy(return char* dst, scope const char* src); +/// Ditto +char* stpncpy(return char* dst, const char* src, size_t len); +/// Compare strings according to current collation +int strcoll_l(scope const char* s1, scope const char* s2, locale_t locale); +/// +char* strerror_l(int, locale_t); +/// Save a copy of a string +char* strndup(scope const char* str, size_t len); +/// Find length of string up to `maxlen` +size_t strnlen(scope const char* str, size_t maxlen); +/// System signal messages +const(char)* strsignal(int); +/// Isolate sequential tokens in a null-terminated string +char* strtok_r(return char* str, scope const char* sep, char** context) pure; +/// Transform a string under locale +size_t strxfrm_l(char* s1, scope const char* s2, size_t n, locale_t locale); diff --git a/libphobos/libdruntime/core/sys/posix/strings.d b/libphobos/libdruntime/core/sys/posix/strings.d new file mode 100644 index 00000000000..96fbcccaee7 --- /dev/null +++ b/libphobos/libdruntime/core/sys/posix/strings.d @@ -0,0 +1,34 @@ +/** + * D header file for POSIX's . + * + * Note: Do not mistake this module for (singular), + * available at `core.sys.posix.string`. + * + * See_Also: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/strings.h.html + * Copyright: D Language Foundation, 2019 + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Authors: Mathias 'Geod24' Lang + * Standards: The Open Group Base Specifications Issue 7, 2018 edition + * Source: $(DRUNTIMESRC core/sys/posix/_strings.d) + */ +module core.sys.posix.strings; + +version (Posix): +extern(C): +@system: +nothrow: +@nogc: + +/// +public import core.sys.posix.locale : locale_t; + +/// Find first bit set in a word +int ffs(int i) @safe pure; +/// Compare two strings ignoring case +int strcasecmp(scope const char* s1, scope const char* s2); +/// Compare two strings ignoring case, with the specified locale +int strcasecmp_l(scope const char* s1, scope const char* s2, scope locale_t locale); +/// Compare two strings ignoring case, up to n characters +int strncasecmp(scope const char* s1, scope const char* s2, size_t n); +/// Compare two strings ignoring case, with the specified locale, up to n characters +int strncasecmp_l(scope const char* s1, const char* s2, size_t n, locale_t locale); diff --git a/libphobos/libdruntime/core/sys/posix/sys/filio.d b/libphobos/libdruntime/core/sys/posix/sys/filio.d index 3574bc69ada..afb6f82d978 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/filio.d +++ b/libphobos/libdruntime/core/sys/posix/sys/filio.d @@ -20,6 +20,7 @@ else version (WatchOS) version (Posix): nothrow @nogc: +@system: version (Darwin) { diff --git a/libphobos/libdruntime/core/sys/posix/sys/ioccom.d b/libphobos/libdruntime/core/sys/posix/sys/ioccom.d old mode 100644 new mode 100755 index 51f1d2272aa..4c1a820161c --- a/libphobos/libdruntime/core/sys/posix/sys/ioccom.d +++ b/libphobos/libdruntime/core/sys/posix/sys/ioccom.d @@ -18,6 +18,7 @@ else version (WatchOS) version (Posix): nothrow @nogc: +@system: version (Darwin) { diff --git a/libphobos/libdruntime/core/sys/posix/sys/ioctl.d b/libphobos/libdruntime/core/sys/posix/sys/ioctl.d index 7c77e803ce9..0266200c811 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/ioctl.d +++ b/libphobos/libdruntime/core/sys/posix/sys/ioctl.d @@ -29,6 +29,7 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: +@system: version (CRuntime_Glibc) { @@ -213,7 +214,7 @@ version (CRuntime_Glibc) enum TIOCGSID = 0x5429; enum TCGETS2 = _IOR!termios2('T', 0x2A); - enum TCSETS2 = _IOR!termios2('T', 0x2B); + enum TCSETS2 = _IOW!termios2('T', 0x2B); enum TCSETSW2 = _IOW!termios2('T', 0x2C); enum TCSETSF2 = _IOW!termios2('T', 0x2D); @@ -624,7 +625,7 @@ else version (CRuntime_UClibc) enum TIOCGSID = 0x5429; enum TCGETS2 = _IOR!termios2('T', 0x2A); - enum TCSETS2 = _IOR!termios2('T', 0x2B); + enum TCSETS2 = _IOW!termios2('T', 0x2B); enum TCSETSW2 = _IOW!termios2('T', 0x2C); enum TCSETSF2 = _IOW!termios2('T', 0x2D); diff --git a/libphobos/libdruntime/core/sys/posix/sys/ipc.d b/libphobos/libdruntime/core/sys/posix/sys/ipc.d index 04601f2eef1..d397a28ec5a 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/ipc.d +++ b/libphobos/libdruntime/core/sys/posix/sys/ipc.d @@ -14,7 +14,7 @@ */ module core.sys.posix.sys.ipc; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for uid_t, gid_t, mode_t, key_t version (OSX) @@ -28,6 +28,7 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: +@system: // // XOpen (XSI) @@ -52,7 +53,7 @@ IPC_RMID IPC_SET IPC_STAT -key_t ftok(in char*, int); +key_t ftok(const scope char*, int); */ version (CRuntime_Glibc) @@ -82,7 +83,7 @@ version (CRuntime_Glibc) enum IPC_SET = 1; enum IPC_STAT = 2; - key_t ftok(in char*, int); + key_t ftok(const scope char*, int); } else version (Darwin) { @@ -122,7 +123,7 @@ else version (FreeBSD) enum IPC_SET = 1; enum IPC_STAT = 2; - key_t ftok(in char*, int); + key_t ftok(const scope char*, int); } else version (NetBSD) { @@ -147,7 +148,7 @@ else version (NetBSD) enum IPC_SET = 1; enum IPC_STAT = 2; - key_t ftok(in char*, int); + key_t ftok(const scope char*, int); } else version (OpenBSD) { @@ -172,7 +173,7 @@ else version (OpenBSD) enum IPC_SET = 1; enum IPC_STAT = 2; - key_t ftok(in char*, int); + key_t ftok(const scope char*, int); } else version (DragonFlyBSD) { @@ -197,7 +198,7 @@ else version (DragonFlyBSD) enum IPC_SET = 1; enum IPC_STAT = 2; - key_t ftok(in char*, int); + key_t ftok(const scope char*, int); } else version (CRuntime_Bionic) { @@ -240,7 +241,7 @@ else version (CRuntime_Bionic) enum IPC_SET = 1; enum IPC_STAT = 2; - key_t ftok(in char*, int); + key_t ftok(const scope char*, int); } else version (CRuntime_UClibc) { @@ -270,5 +271,5 @@ else version (CRuntime_UClibc) enum IPC_STAT = 2; enum IPC_INFO = 3; - key_t ftok(in char*, int); + key_t ftok(const scope char*, int); } diff --git a/libphobos/libdruntime/core/sys/posix/sys/mman.d b/libphobos/libdruntime/core/sys/posix/sys/mman.d index f682320a359..a74a213691c 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/mman.d +++ b/libphobos/libdruntime/core/sys/posix/sys/mman.d @@ -14,7 +14,7 @@ */ module core.sys.posix.sys.mman; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for off_t, mode_t version (OSX) @@ -45,6 +45,7 @@ version (X86_64) version = X86_Any; version (Posix): extern (C) nothrow @nogc: +@system: // // Advisory Information (ADV) @@ -511,7 +512,7 @@ else version (CRuntime_Bionic) enum MS_ASYNC = 1; enum MS_INVALIDATE = 2; - int msync(in void*, size_t, int); + int msync(const scope void*, size_t, int); } else version (CRuntime_Musl) { @@ -694,59 +695,59 @@ else // Range Memory Locking (MLR) // /* -int mlock(in void*, size_t); -int munlock(in void*, size_t); +int mlock(const scope void*, size_t); +int munlock(const scope void*, size_t); */ version (CRuntime_Glibc) { - int mlock(in void*, size_t); - int munlock(in void*, size_t); + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); } else version (Darwin) { - int mlock(in void*, size_t); - int munlock(in void*, size_t); + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); } else version (FreeBSD) { - int mlock(in void*, size_t); - int munlock(in void*, size_t); + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); } else version (NetBSD) { - int mlock(in void*, size_t); - int munlock(in void*, size_t); + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); } else version (OpenBSD) { - int mlock(in void*, size_t); - int munlock(in void*, size_t); + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); } else version (DragonFlyBSD) { - int mlock(in void*, size_t); - int munlock(in void*, size_t); + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); } else version (Solaris) { - int mlock(in void*, size_t); - int munlock(in void*, size_t); + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); } else version (CRuntime_Bionic) { - int mlock(in void*, size_t); - int munlock(in void*, size_t); + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); } else version (CRuntime_Musl) { - int mlock(in void*, size_t); - int munlock(in void*, size_t); + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); } else version (CRuntime_UClibc) { - int mlock(in void*, size_t); - int munlock(in void*, size_t); + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); } else { @@ -790,7 +791,7 @@ else version (Solaris) } else version (CRuntime_Bionic) { - int mprotect(in void*, size_t, int); + int mprotect(const scope void*, size_t, int); } else version (CRuntime_Musl) { @@ -809,57 +810,57 @@ else // Shared Memory Objects (SHM) // /* -int shm_open(in char*, int, mode_t); -int shm_unlink(in char*); +int shm_open(const scope char*, int, mode_t); +int shm_unlink(const scope char*); */ version (CRuntime_Glibc) { - int shm_open(in char*, int, mode_t); - int shm_unlink(in char*); + int shm_open(const scope char*, int, mode_t); + int shm_unlink(const scope char*); } else version (Darwin) { - int shm_open(in char*, int, mode_t); - int shm_unlink(in char*); + int shm_open(const scope char*, int, mode_t); + int shm_unlink(const scope char*); } else version (FreeBSD) { - int shm_open(in char*, int, mode_t); - int shm_unlink(in char*); + int shm_open(const scope char*, int, mode_t); + int shm_unlink(const scope char*); } else version (NetBSD) { - int shm_open(in char*, int, mode_t); - int shm_unlink(in char*); + int shm_open(const scope char*, int, mode_t); + int shm_unlink(const scope char*); } else version (OpenBSD) { - int shm_open(in char*, int, mode_t); - int shm_unlink(in char*); + int shm_open(const scope char*, int, mode_t); + int shm_unlink(const scope char*); } else version (DragonFlyBSD) { - int shm_open(in char*, int, mode_t); - int shm_unlink(in char*); + int shm_open(const scope char*, int, mode_t); + int shm_unlink(const scope char*); } else version (Solaris) { - int shm_open(in char*, int, mode_t); - int shm_unlink(in char*); + int shm_open(const scope char*, int, mode_t); + int shm_unlink(const scope char*); } else version (CRuntime_Bionic) { } else version (CRuntime_Musl) { - int shm_open(in char*, int, mode_t); - int shm_unlink(in char*); + int shm_open(const scope char*, int, mode_t); + int shm_unlink(const scope char*); } else version (CRuntime_UClibc) { - int shm_open(in char*, int, mode_t); - int shm_unlink(in char*); + int shm_open(const scope char*, int, mode_t); + int shm_unlink(const scope char*); } else { @@ -879,7 +880,7 @@ struct posix_typed_mem_info size_t posix_tmi_length; } -int posix_mem_offset(in void*, size_t, off_t *, size_t *, int *); +int posix_mem_offset(const scope void*, size_t, off_t *, size_t *, int *); int posix_typed_mem_get_info(int, struct posix_typed_mem_info *); -int posix_typed_mem_open(in char*, int, int); +int posix_typed_mem_open(const scope char*, int, int); */ diff --git a/libphobos/libdruntime/core/sys/posix/sys/msg.d b/libphobos/libdruntime/core/sys/posix/sys/msg.d index 208e5c2dd47..4760f2e22f6 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/msg.d +++ b/libphobos/libdruntime/core/sys/posix/sys/msg.d @@ -14,6 +14,7 @@ import core.stdc.config; version (CRuntime_Glibc): // Some of these may be from linux kernel headers. extern (C): +@system: version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/posix/sys/resource.d b/libphobos/libdruntime/core/sys/posix/sys/resource.d index 56a8fd428e8..c5d584c5804 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/resource.d +++ b/libphobos/libdruntime/core/sys/posix/sys/resource.d @@ -23,6 +23,7 @@ else version (WatchOS) version = Darwin; nothrow @nogc extern(C): +@system: // // XOpen (XSI) @@ -528,7 +529,7 @@ else version (CRuntime_Musl) enum RLIM_INFINITY = cast(c_ulong)(~0UL); int getrlimit(int, rlimit*); - int setrlimit(int, in rlimit*); + int setrlimit(int, const scope rlimit*); alias getrlimit getrlimit64; alias setrlimit setrlimit64; enum @@ -677,14 +678,14 @@ version (CRuntime_Glibc) static if (__USE_FILE_OFFSET64) { int getrlimit64(int, rlimit*); - int setrlimit64(int, in rlimit*); + int setrlimit64(int, const scope rlimit*); alias getrlimit = getrlimit64; alias setrlimit = setrlimit64; } else { int getrlimit(int, rlimit*); - int setrlimit(int, in rlimit*); + int setrlimit(int, const scope rlimit*); } int getrusage(int, rusage*); } @@ -692,57 +693,57 @@ else version (CRuntime_Bionic) { int getrlimit(int, rlimit*); int getrusage(int, rusage*); - int setrlimit(int, in rlimit*); + int setrlimit(int, const scope rlimit*); } else version (Darwin) { int getrlimit(int, rlimit*); int getrusage(int, rusage*); - int setrlimit(int, in rlimit*); + int setrlimit(int, const scope rlimit*); } else version (FreeBSD) { int getrlimit(int, rlimit*); int getrusage(int, rusage*); - int setrlimit(int, in rlimit*); + int setrlimit(int, const scope rlimit*); } else version (NetBSD) { int getrlimit(int, rlimit*); int getrusage(int, rusage*); - int setrlimit(int, in rlimit*); + int setrlimit(int, const scope rlimit*); } else version (OpenBSD) { int getrlimit(int, rlimit*); int getrusage(int, rusage*); - int setrlimit(int, in rlimit*); + int setrlimit(int, const scope rlimit*); } else version (DragonFlyBSD) { int getrlimit(int, rlimit*); int getrusage(int, rusage*); - int setrlimit(int, in rlimit*); + int setrlimit(int, const scope rlimit*); } else version (Solaris) { int getrlimit(int, rlimit*); int getrusage(int, rusage*); - int setrlimit(int, in rlimit*); + int setrlimit(int, const scope rlimit*); } else version (CRuntime_UClibc) { static if (__USE_FILE_OFFSET64) { int getrlimit64(int, rlimit*); - int setrlimit64(int, in rlimit*); + int setrlimit64(int, const scope rlimit*); alias getrlimit = getrlimit64; alias setrlimit = setrlimit64; } else { int getrlimit(int, rlimit*); - int setrlimit(int, in rlimit*); + int setrlimit(int, const scope rlimit*); } int getrusage(int, rusage*); } diff --git a/libphobos/libdruntime/core/sys/posix/sys/select.d b/libphobos/libdruntime/core/sys/posix/sys/select.d index 83e47582f84..2a659c30dc0 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/select.d +++ b/libphobos/libdruntime/core/sys/posix/sys/select.d @@ -8,7 +8,7 @@ */ module core.sys.posix.sys.select; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.stdc.time; // for timespec public import core.sys.posix.sys.time; // for timeval public import core.sys.posix.sys.types; // for time_t @@ -27,6 +27,7 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: +@system: // // Required @@ -46,7 +47,7 @@ void FD_ZERO(fd_set* fdset); FD_SETSIZE -int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); +int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); */ @@ -130,7 +131,7 @@ version (CRuntime_Glibc) __result; })) +/ - int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); } else version (Darwin) @@ -168,7 +169,7 @@ else version (Darwin) fdset.fds_bits[0 .. $] = 0; } - int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); } else version (FreeBSD) @@ -217,7 +218,7 @@ else version (FreeBSD) _p.__fds_bits[--_n] = 0; } - int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); } else version (NetBSD) @@ -266,7 +267,7 @@ else version (NetBSD) _p.__fds_bits[--_n] = 0; } - int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); } else version (OpenBSD) @@ -313,7 +314,7 @@ else version (OpenBSD) _p.__fds_bits[--_n] = 0; } - int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); } else version (DragonFlyBSD) @@ -362,7 +363,7 @@ else version (DragonFlyBSD) _p.__fds_bits[--_n] = 0; } - int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); } else version (Solaris) @@ -406,7 +407,7 @@ else version (Solaris) } int select(int, fd_set*, fd_set*, fd_set*, timeval*); - int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); } else version (CRuntime_Bionic) { @@ -454,7 +455,7 @@ else version (CRuntime_Bionic) fdset.fds_bits[0 .. $] = 0; } - int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); } else version (CRuntime_Musl) @@ -501,7 +502,7 @@ else version (CRuntime_Musl) { fdset.fds_bits[0 .. $] = 0; } - int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); } else version (CRuntime_UClibc) @@ -549,7 +550,7 @@ else version (CRuntime_UClibc) fdset.fds_bits[0 .. $] = 0; } - int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*); + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); } else diff --git a/libphobos/libdruntime/core/sys/posix/sys/shm.d b/libphobos/libdruntime/core/sys/posix/sys/shm.d index 8902451d951..2e85096ba4a 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/shm.d +++ b/libphobos/libdruntime/core/sys/posix/sys/shm.d @@ -14,7 +14,7 @@ */ module core.sys.posix.sys.shm; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for pid_t, time_t, key_t public import core.sys.posix.sys.ipc; @@ -29,6 +29,7 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: +@system: // // XOpen (XSI) @@ -53,9 +54,9 @@ struct shmid_ds time_t shm_ctime; } -void* shmat(int, in void*, int); +void* shmat(int, const scope void*, int); int shmctl(int, int, shmid_ds*); -int shmdt(in void*); +int shmdt(const scope void*); int shmget(key_t, size_t, int); */ @@ -87,9 +88,9 @@ version (CRuntime_Glibc) c_ulong __unused5; } - void* shmat(int, in void*, int); + void* shmat(int, const scope void*, int); int shmctl(int, int, shmid_ds*); - int shmdt(in void*); + int shmdt(const scope void*); int shmget(key_t, size_t, int); } else version (FreeBSD) @@ -125,9 +126,9 @@ else version (FreeBSD) time_t shm_ctime; } - void* shmat(int, in void*, int); + void* shmat(int, const scope void*, int); int shmctl(int, int, shmid_ds*); - int shmdt(in void*); + int shmdt(const scope void*); int shmget(key_t, size_t, int); } else version (NetBSD) @@ -151,9 +152,9 @@ else version (NetBSD) void* shm_internal; } - void* shmat(int, in void*, int); + void* shmat(int, const scope void*, int); int shmctl(int, int, shmid_ds*); - int shmdt(in void*); + int shmdt(const scope void*); int shmget(key_t, size_t, int); } else version (OpenBSD) @@ -180,9 +181,9 @@ else version (OpenBSD) void* shm_internal; } - void* shmat(int, in void*, int); + void* shmat(int, const scope void*, int); int shmctl(int, int, shmid_ds*); - int shmdt(in void*); + int shmdt(const scope void*); int shmget(key_t, size_t, int); } else version (DragonFlyBSD) @@ -206,9 +207,9 @@ else version (DragonFlyBSD) private void* shm_internal; } - void* shmat(int, in void*, int); + void* shmat(int, const scope void*, int); int shmctl(int, int, shmid_ds*); - int shmdt(in void*); + int shmdt(const scope void*); int shmget(key_t, size_t, int); } else version (Darwin) @@ -273,8 +274,8 @@ else version (CRuntime_UClibc) c_ulong swap_successes; } - void* shmat(int, in void*, int); + void* shmat(int, const scope void*, int); int shmctl(int, int, shmid_ds*); - int shmdt(in void*); + int shmdt(const scope void*); int shmget(key_t, size_t, int); } diff --git a/libphobos/libdruntime/core/sys/posix/sys/socket.d b/libphobos/libdruntime/core/sys/posix/sys/socket.d index 05f52fc76af..430d0c0d1e3 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/socket.d +++ b/libphobos/libdruntime/core/sys/posix/sys/socket.d @@ -14,7 +14,7 @@ */ module core.sys.posix.sys.socket; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for ssize_t public import core.sys.posix.sys.uio; // for iovec @@ -45,6 +45,7 @@ version (X86_64) version = X86_Any; version (Posix): extern (C) nothrow @nogc: +@system: // // Required @@ -138,8 +139,8 @@ SHUT_RDWR SHUT_WR int accept(int, sockaddr*, socklen_t*); -int bind(int, in sockaddr*, socklen_t); -int connect(int, in sockaddr*, socklen_t); +int bind(int, const scope sockaddr*, socklen_t); +int connect(int, const scope sockaddr*, socklen_t); int getpeername(int, sockaddr*, socklen_t*); int getsockname(int, sockaddr*, socklen_t*); int getsockopt(int, int, int, void*, socklen_t*); @@ -147,10 +148,10 @@ int listen(int, int); ssize_t recv(int, void*, size_t, int); ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*); ssize_t recvmsg(int, msghdr*, int); -ssize_t send(int, in void*, size_t, int); -ssize_t sendmsg(int, in msghdr*, int); -ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); -int setsockopt(int, int, int, in void*, socklen_t); +ssize_t send(int, const scope void*, size_t, int); +ssize_t sendmsg(int, const scope msghdr*, int); +ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); +int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int); int socket(int, int, int); int sockatmark(int); @@ -216,7 +217,7 @@ version (CRuntime_Glibc) } else { - extern (D) inout(ubyte)* CMSG_DATA( inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); } + extern (D) inout(ubyte)* CMSG_DATA( return inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); } } private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc; @@ -571,8 +572,8 @@ version (CRuntime_Glibc) } int accept(int, scope sockaddr*, scope socklen_t*); - int bind(int, in sockaddr*, socklen_t); - int connect(int, in sockaddr*, socklen_t); + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); int getpeername(int, scope sockaddr*, scope socklen_t*); int getsockname(int, scope sockaddr*, scope socklen_t*); int getsockopt(int, int, int, scope void*, scope socklen_t*); @@ -580,10 +581,10 @@ version (CRuntime_Glibc) ssize_t recv(int, scope void*, size_t, int); ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*); ssize_t recvmsg(int, scope msghdr*, int); - ssize_t send(int, in void*, size_t, int); - ssize_t sendmsg(int, in msghdr*, int); - ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); - int setsockopt(int, int, int, in void*, socklen_t); + ssize_t send(int, const scope void*, size_t, int); + ssize_t sendmsg(int, const scope msghdr*, int); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int) @safe; int socket(int, int, int) @safe; int sockatmark(int) @safe; @@ -727,8 +728,8 @@ else version (Darwin) } int accept(int, scope sockaddr*, scope socklen_t*); - int bind(int, in sockaddr*, socklen_t); - int connect(int, in sockaddr*, socklen_t); + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); int getpeername(int, scope sockaddr*, scope socklen_t*); int getsockname(int, scope sockaddr*, scope socklen_t*); int getsockopt(int, int, int, scope void*, scope socklen_t*); @@ -736,10 +737,10 @@ else version (Darwin) ssize_t recv(int, scope void*, size_t, int); ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*); ssize_t recvmsg(int, scope msghdr*, int); - ssize_t send(int, in void*, size_t, int); - ssize_t sendmsg(int, in msghdr*, int); - ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); - int setsockopt(int, int, int, in void*, socklen_t); + ssize_t send(int, const scope void*, size_t, int); + ssize_t sendmsg(int, const scope msghdr*, int); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int) @safe; int socket(int, int, int) @safe; int sockatmark(int) @safe; @@ -904,8 +905,8 @@ else version (FreeBSD) } int accept(int, scope sockaddr*, scope socklen_t*); - int bind(int, in sockaddr*, socklen_t); - int connect(int, in sockaddr*, socklen_t); + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); int getpeername(int, scope sockaddr*, scope socklen_t*); int getsockname(int, scope sockaddr*, scope socklen_t*); int getsockopt(int, int, int, scope void*, scope socklen_t*); @@ -913,10 +914,10 @@ else version (FreeBSD) ssize_t recv(int, scope void*, size_t, int); ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*); ssize_t recvmsg(int, scope msghdr*, int); - ssize_t send(int, in void*, size_t, int); - ssize_t sendmsg(int, in msghdr*, int); - ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); - int setsockopt(int, int, int, in void*, socklen_t); + ssize_t send(int, const scope void*, size_t, int); + ssize_t sendmsg(int, const scope msghdr*, int); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int) @safe; int socket(int, int, int) @safe; int sockatmark(int) @safe; @@ -1101,8 +1102,8 @@ else version (NetBSD) } int accept(int, scope sockaddr*, scope socklen_t*); - int bind(int, in sockaddr*, socklen_t); - int connect(int, in sockaddr*, socklen_t); + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); int getpeername(int, scope sockaddr*, scope socklen_t*); int getsockname(int, scope sockaddr*, scope socklen_t*); int getsockopt(int, int, int, scope void*, scope socklen_t*); @@ -1110,10 +1111,10 @@ else version (NetBSD) ssize_t recv(int, scope void*, size_t, int); ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*); ssize_t recvmsg(int, scope msghdr*, int); - ssize_t send(int, in void*, size_t, int); - ssize_t sendmsg(int, in msghdr*, int); - ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); - int setsockopt(int, int, int, in void*, socklen_t); + ssize_t send(int, const scope void*, size_t, int); + ssize_t sendmsg(int, const scope msghdr*, int); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int) @safe; int socket(int, int, int) @safe; int sockatmark(int) @safe; @@ -1274,8 +1275,8 @@ else version (OpenBSD) } int accept(int, scope sockaddr*, scope socklen_t*); - int bind(int, in sockaddr*, socklen_t); - int connect(int, in sockaddr*, socklen_t); + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); int getpeername(int, scope sockaddr*, scope socklen_t*); int getsockname(int, scope sockaddr*, scope socklen_t*); int getsockopt(int, int, int, scope void*, scope socklen_t*); @@ -1283,10 +1284,10 @@ else version (OpenBSD) ssize_t recv(int, scope void*, size_t, int); ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*); ssize_t recvmsg(int, scope msghdr*, int); - ssize_t send(int, in void*, size_t, int); - ssize_t sendmsg(int, in msghdr*, int); - ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); - int setsockopt(int, int, int, in void*, socklen_t); + ssize_t send(int, const scope void*, size_t, int); + ssize_t sendmsg(int, const scope msghdr*, int); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int) @safe; int socket(int, int, int) @safe; int sockatmark(int) @safe; @@ -1446,7 +1447,7 @@ else version (DragonFlyBSD) gid_t cmcred_gid; short cmcred_ngroups; gid_t[CMGROUP_MAX] cmcred_groups; - }; + } enum : uint { @@ -1499,13 +1500,13 @@ else version (DragonFlyBSD) int hdr_cnt; iovec * trailers; int trl_cnt; - }; + } */ int accept(int, sockaddr*, socklen_t*); // int accept4(int, sockaddr*, socklen_t*, int); - int bind(int, in sockaddr*, socklen_t); - int connect(int, in sockaddr*, socklen_t); + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); // int extconnect(int, int, sockaddr*, socklen_t); int getpeername(int, sockaddr*, socklen_t*); int getsockname(int, sockaddr*, socklen_t*); @@ -1514,11 +1515,11 @@ else version (DragonFlyBSD) ssize_t recv(int, void*, size_t, int); ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*); ssize_t recvmsg(int, msghdr*, int); - ssize_t send(int, in void*, size_t, int); - ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); - ssize_t sendmsg(int, in msghdr*, int); + ssize_t send(int, const scope void*, size_t, int); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + ssize_t sendmsg(int, const scope msghdr*, int); // int sendfile(int, int, off_t, size_t, sf_hdtr *, off_t *, int); - int setsockopt(int, int, int, in void*, socklen_t); + int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int); int sockatmark(int); int socket(int, int, int); @@ -1655,8 +1656,8 @@ else version (Solaris) } int accept(int, scope sockaddr*, scope socklen_t*); - int bind(int, in sockaddr*, socklen_t); - int connect(int, in sockaddr*, socklen_t); + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); int getpeername(int, scope sockaddr*, scope socklen_t*); int getsockname(int, scope sockaddr*, scope socklen_t*); int getsockopt(int, int, int, scope void*, scope socklen_t*); @@ -1664,10 +1665,10 @@ else version (Solaris) ssize_t recv(int, scope void*, size_t, int); ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*); ssize_t recvmsg(int, scope msghdr*, int); - ssize_t send(int, in void*, size_t, int); - ssize_t sendmsg(int, in msghdr*, int); - ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); - int setsockopt(int, int, int, in void*, socklen_t); + ssize_t send(int, const scope void*, size_t, int); + ssize_t sendmsg(int, const scope msghdr*, int); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int) @safe; int socket(int, int, int) @safe; int sockatmark(int) @safe; @@ -1816,8 +1817,8 @@ else version (CRuntime_Bionic) enum SOCK_RDM = 4; int accept(int, scope sockaddr*, scope socklen_t*); - int bind(int, in sockaddr*, socklen_t); - int connect(int, in sockaddr*, socklen_t); + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); int getpeername(int, scope sockaddr*, scope socklen_t*); int getsockname(int, scope sockaddr*, scope socklen_t*); int getsockopt(int, int, int, scope void*, scope socklen_t*); @@ -1825,10 +1826,10 @@ else version (CRuntime_Bionic) ssize_t recv(int, scope void*, size_t, int); ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*); int recvmsg(int, scope msghdr*, int); - ssize_t send(int, in void*, size_t, int); - int sendmsg(int, in msghdr*, int); - ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); - int setsockopt(int, int, int, in void*, socklen_t); + ssize_t send(int, const scope void*, size_t, int); + int sendmsg(int, const scope msghdr*, int); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int) @safe; int socket(int, int, int) @safe; int sockatmark(int) @safe; @@ -1970,8 +1971,8 @@ else version (CRuntime_Musl) int msg_flags; } int accept(int, sockaddr*, socklen_t*); - int bind(int, in sockaddr*, socklen_t); - int connect(int, in sockaddr*, socklen_t); + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); int getpeername(int, sockaddr*, socklen_t*); int getsockname(int, sockaddr*, socklen_t*); int getsockopt(int, int, int, void*, socklen_t*); @@ -1979,10 +1980,10 @@ else version (CRuntime_Musl) ssize_t recv(int, void*, size_t, int); ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*); ssize_t recvmsg(int, msghdr*, int); - ssize_t send(int, in void*, size_t, int); - ssize_t sendmsg(int, in msghdr*, int); - ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); - int setsockopt(int, int, int, in void*, socklen_t); + ssize_t send(int, const scope void*, size_t, int); + ssize_t sendmsg(int, const scope msghdr*, int); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int); int socket(int, int, int); int sockatmark(int); @@ -2167,8 +2168,8 @@ else version (CRuntime_UClibc) } int accept(int, sockaddr*, socklen_t*); - int bind(int, in sockaddr*, socklen_t); - int connect(int, in sockaddr*, socklen_t); + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); int getpeername(int, sockaddr*, socklen_t*); int getsockname(int, sockaddr*, socklen_t*); int getsockopt(int, int, int, void*, socklen_t*); @@ -2176,10 +2177,10 @@ else version (CRuntime_UClibc) ssize_t recv(int, void*, size_t, int); ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*); ssize_t recvmsg(int, msghdr*, int); - ssize_t send(int, in void*, size_t, int); - ssize_t sendmsg(int, in msghdr*, int); - ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); - int setsockopt(int, int, int, in void*, socklen_t); + ssize_t send(int, const scope void*, size_t, int); + ssize_t sendmsg(int, const scope msghdr*, int); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + int setsockopt(int, int, int, const scope void*, socklen_t); int shutdown(int, int); int socket(int, int, int); int sockatmark(int); diff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d index 35b1f1cffee..6b4d022b825 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/stat.d +++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d @@ -14,9 +14,9 @@ */ module core.sys.posix.sys.stat; -private import core.sys.posix.config; -private import core.stdc.stdint; -private import core.sys.posix.time; // for timespec +import core.sys.posix.config; +import core.stdc.stdint; +import core.sys.posix.time; // for timespec public import core.sys.posix.sys.types; // for off_t, mode_t version (OSX) @@ -30,9 +30,12 @@ else version (WatchOS) version (RISCV32) version = RISCV_Any; version (RISCV64) version = RISCV_Any; +version (SPARC) version = SPARC_Any; +version (SPARC64) version = SPARC_Any; version (Posix): extern (C) nothrow @nogc: +@system: // // Required @@ -80,13 +83,13 @@ S_TYPEISMQ(buf) S_TYPEISSEM(buf) S_TYPEISSHM(buf) -int chmod(in char*, mode_t); +int chmod(const scope char*, mode_t); int fchmod(int, mode_t); int fstat(int, stat*); -int lstat(in char*, stat*); -int mkdir(in char*, mode_t); -int mkfifo(in char*, mode_t); -int stat(in char*, stat*); +int lstat(const scope char*, stat*); +int mkdir(const scope char*, mode_t); +int mkfifo(const scope char*, mode_t); +int stat(const scope char*, stat*); mode_t umask(mode_t); */ @@ -120,11 +123,11 @@ version (CRuntime_Glibc) timespec st_atim; timespec st_mtim; timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -167,11 +170,11 @@ version (CRuntime_Glibc) timespec st_atim; timespec st_mtim; timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -249,11 +252,11 @@ version (CRuntime_Glibc) __timespec st_atim; __timespec st_mtim; __timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -309,11 +312,11 @@ version (CRuntime_Glibc) timespec st_atim; timespec st_mtim; timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -373,11 +376,11 @@ version (CRuntime_Glibc) timespec st_atim; timespec st_mtim; timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -514,11 +517,11 @@ version (CRuntime_Glibc) __timespec st_atim; __timespec st_mtim; __timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -596,11 +599,11 @@ version (CRuntime_Glibc) __timespec st_atim; __timespec st_mtim; __timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -691,11 +694,11 @@ version (CRuntime_Glibc) __timespec st_atim; __timespec st_mtim; __timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -714,7 +717,7 @@ version (CRuntime_Glibc) else static assert(stat_t.sizeof == 104); } - else version (SPARC64) + else version (SPARC_Any) { private { @@ -736,8 +739,15 @@ version (CRuntime_Glibc) struct stat_t { __dev_t st_dev; - ushort __pad1; - __ino_t st_ino; + static if (__WORDSIZE == 64 || !__USE_FILE_OFFSET64) + { + ushort __pad1; + __ino_t st_ino; + } + else + { + __ino64_t st_ino; + } __mode_t st_mode; __nlink_t st_nlink; __uid_t st_uid; @@ -769,11 +779,11 @@ version (CRuntime_Glibc) __timespec st_atim; __timespec st_mtim; __timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -789,7 +799,15 @@ version (CRuntime_Glibc) c_ulong __unused4; c_ulong __unused5; } - static assert(stat_t.sizeof == 144); + static if (__USE_LARGEFILE64) alias stat_t stat64_t; + + static if (__WORDSIZE == 64) + static assert(stat_t.sizeof == 144); + else static if (__USE_FILE_OFFSET64) + static assert(stat_t.sizeof == 104); + else + static assert(stat_t.sizeof == 88); + } else version (S390) { @@ -838,11 +856,11 @@ version (CRuntime_Glibc) __timespec st_atim; __timespec st_mtim; __timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -902,11 +920,11 @@ version (CRuntime_Glibc) __timespec st_atim; __timespec st_mtim; __timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -1264,11 +1282,11 @@ else version (OpenBSD) timespec st_atim; timespec st_mtim; timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -1348,7 +1366,7 @@ else version (DragonFlyBSD) int32_t st_lspare; int64_t st_qspare1; /* was recursive change detect */ int64_t st_qspare2; - }; + } enum S_IRUSR = 0x100; // octal 0000400 enum S_IWUSR = 0x080; // octal 0000200 @@ -2001,11 +2019,11 @@ else version (CRuntime_UClibc) timespec st_atim; timespec st_mtim; timespec st_ctim; - extern(D) + extern(D) @safe @property inout pure nothrow { - @property ref time_t st_atime() { return st_atim.tv_sec; } - @property ref time_t st_mtime() { return st_mtim.tv_sec; } - @property ref time_t st_ctime() { return st_ctim.tv_sec; } + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } else @@ -2167,13 +2185,13 @@ else static assert(false, "Unsupported platform"); } -int chmod(in char*, mode_t); +int chmod(const scope char*, mode_t); int fchmod(int, mode_t); //int fstat(int, stat_t*); -//int lstat(in char*, stat_t*); -int mkdir(in char*, mode_t); -int mkfifo(in char*, mode_t); -//int stat(in char*, stat_t*); +//int lstat(const scope char*, stat_t*); +int mkdir(const scope char*, mode_t); +int mkfifo(const scope char*, mode_t); +//int stat(const scope char*, stat_t*); mode_t umask(mode_t); version (CRuntime_Glibc) @@ -2183,17 +2201,17 @@ version (CRuntime_Glibc) int fstat64(int, stat_t*) @trusted; alias fstat64 fstat; - int lstat64(in char*, stat_t*); + int lstat64(const scope char*, stat_t*); alias lstat64 lstat; - int stat64(in char*, stat_t*); + int stat64(const scope char*, stat_t*); alias stat64 stat; } else { int fstat(int, stat_t*) @trusted; - int lstat(in char*, stat_t*); - int stat(in char*, stat_t*); + int lstat(const scope char*, stat_t*); + int stat(const scope char*, stat_t*); } } else version (Solaris) @@ -2201,8 +2219,8 @@ else version (Solaris) version (D_LP64) { int fstat(int, stat_t*) @trusted; - int lstat(in char*, stat_t*); - int stat(in char*, stat_t*); + int lstat(const scope char*, stat_t*); + int stat(const scope char*, stat_t*); static if (__USE_LARGEFILE64) { @@ -2218,17 +2236,17 @@ else version (Solaris) int fstat64(int, stat_t*) @trusted; alias fstat64 fstat; - int lstat64(in char*, stat_t*); + int lstat64(const scope char*, stat_t*); alias lstat64 lstat; - int stat64(in char*, stat_t*); + int stat64(const scope char*, stat_t*); alias stat64 stat; } else { int fstat(int, stat_t*) @trusted; - int lstat(in char*, stat_t*); - int stat(in char*, stat_t*); + int lstat(const scope char*, stat_t*); + int stat(const scope char*, stat_t*); } } } @@ -2238,28 +2256,55 @@ else version (Darwin) // inode functions by appending $INODE64 to newer 64-bit inode functions. version (OSX) { - pragma(mangle, "fstat$INODE64") int fstat(int, stat_t*); - pragma(mangle, "lstat$INODE64") int lstat(in char*, stat_t*); - pragma(mangle, "stat$INODE64") int stat(in char*, stat_t*); + version (AArch64) + { + int fstat(int, stat_t*); + int lstat(const scope char*, stat_t*); + int stat(const scope char*, stat_t*); + } + else + { + pragma(mangle, "fstat$INODE64") int fstat(int, stat_t*); + pragma(mangle, "lstat$INODE64") int lstat(const scope char*, stat_t*); + pragma(mangle, "stat$INODE64") int stat(const scope char*, stat_t*); + } } else { int fstat(int, stat_t*); - int lstat(in char*, stat_t*); - int stat(in char*, stat_t*); + int lstat(const scope char*, stat_t*); + int stat(const scope char*, stat_t*); } } else version (FreeBSD) { - int fstat(int, stat_t*); - int lstat(in char*, stat_t*); - int stat(in char*, stat_t*); + version (GNU) + { + int fstat(int, stat_t*); + int lstat(const scope char*, stat_t*); + int stat(const scope char*, stat_t*); + } + else + { + static if (__FreeBSD_version >= INO64_FIRST) + { + pragma(mangle, "fstat@FBSD_1.5") int fstat(int, stat_t*); + pragma(mangle, "lstat@FBSD_1.5") int lstat(const scope char*, stat_t*); + pragma(mangle, "stat@FBSD_1.5") int stat(const scope char*, stat_t*); + } + else + { + pragma(mangle, "fstat@FBSD_1.0") int fstat(int, stat_t*); + pragma(mangle, "lstat@FBSD_1.0") int lstat(const scope char*, stat_t*); + pragma(mangle, "stat@FBSD_1.0") int stat(const scope char*, stat_t*); + } + } } else version (NetBSD) { int __fstat50(int, stat_t*); - int __lstat50(in char*, stat_t*); - int __stat50(in char*, stat_t*); + int __lstat50(const scope char*, stat_t*); + int __stat50(const scope char*, stat_t*); alias __fstat50 fstat; alias __lstat50 lstat; alias __stat50 stat; @@ -2267,26 +2312,26 @@ else version (NetBSD) else version (OpenBSD) { int fstat(int, stat_t*); - int lstat(in char*, stat_t*); - int stat(in char*, stat_t*); + int lstat(const scope char*, stat_t*); + int stat(const scope char*, stat_t*); } else version (DragonFlyBSD) { int fstat(int, stat_t*); - int lstat(in char*, stat_t*); - int stat(in char*, stat_t*); + int lstat(const scope char*, stat_t*); + int stat(const scope char*, stat_t*); } else version (CRuntime_Bionic) { int fstat(int, stat_t*) @trusted; - int lstat(in char*, stat_t*); - int stat(in char*, stat_t*); + int lstat(const scope char*, stat_t*); + int stat(const scope char*, stat_t*); } else version (CRuntime_Musl) { - int stat(in char*, stat_t*); + int stat(const scope char*, stat_t*); int fstat(int, stat_t*); - int lstat(in char*, stat_t*); + int lstat(const scope char*, stat_t*); alias fstat fstat64; alias lstat lstat64; @@ -2299,17 +2344,17 @@ else version (CRuntime_UClibc) int fstat64(int, stat_t*) @trusted; alias fstat64 fstat; - int lstat64(in char*, stat_t*); + int lstat64(const scope char*, stat_t*); alias lstat64 lstat; - int stat64(in char*, stat_t*); + int stat64(const scope char*, stat_t*); alias stat64 stat; } else { int fstat(int, stat_t*) @trusted; - int lstat(in char*, stat_t*); - int stat(in char*, stat_t*); + int lstat(const scope char*, stat_t*); + int stat(const scope char*, stat_t*); } } @@ -2347,7 +2392,7 @@ version (CRuntime_Glibc) enum S_IFLNK = 0xA000; // octal 0120000 enum S_IFSOCK = 0xC000; // octal 0140000 - int mknod(in char*, mode_t, dev_t); + int mknod(const scope char*, mode_t, dev_t); } else version (Darwin) { @@ -2360,7 +2405,7 @@ else version (Darwin) enum S_IFLNK = 0xA000; // octal 0120000 enum S_IFSOCK = 0xC000; // octal 0140000 - int mknod(in char*, mode_t, dev_t); + int mknod(const scope char*, mode_t, dev_t); } else version (FreeBSD) { @@ -2373,7 +2418,17 @@ else version (FreeBSD) enum S_IFLNK = 0xA000; // octal 0120000 enum S_IFSOCK = 0xC000; // octal 0140000 - int mknod(in char*, mode_t, dev_t); + version (GNU) + { + int mknod(const scope char*, mode_t, dev_t); + } + else + { + static if (__FreeBSD_version >= INO64_FIRST) + pragma(mangle, "mknod@FBSD_1.5") int mknod(const scope char*, mode_t, dev_t); + else + pragma(mangle, "mknod@FBSD_1.0") int mknod(const scope char*, mode_t, dev_t); + } } else version (NetBSD) { @@ -2386,7 +2441,7 @@ else version (NetBSD) enum S_IFLNK = 0xA000; // octal 0120000 enum S_IFSOCK = 0xC000; // octal 0140000 - int mknod(in char*, mode_t, dev_t); + int mknod(const scope char*, mode_t, dev_t); } else version (OpenBSD) { @@ -2399,7 +2454,7 @@ else version (OpenBSD) enum S_IFLNK = 0xA000; // octal 0120000 enum S_IFSOCK = 0xC000; // octal 0140000 - int mknod(in char*, mode_t, dev_t); + int mknod(const scope char*, mode_t, dev_t); } else version (DragonFlyBSD) { @@ -2412,7 +2467,7 @@ else version (DragonFlyBSD) enum S_IFLNK = 0xA000; // octal 0120000 enum S_IFSOCK = 0xC000; // octal 0140000 - int mknod(in char*, mode_t, dev_t); + int mknod(const scope char*, mode_t, dev_t); } else version (Solaris) { @@ -2427,7 +2482,7 @@ else version (Solaris) enum S_IFDOOR = 0xD000; enum S_IFPORT = 0xE000; - int mknod(in char*, mode_t, dev_t); + int mknod(const scope char*, mode_t, dev_t); } else version (CRuntime_Bionic) { @@ -2440,7 +2495,7 @@ else version (CRuntime_Bionic) enum S_IFLNK = 0xA000; // octal 0120000 enum S_IFSOCK = 0xC000; // octal 0140000 - int mknod(in char*, mode_t, dev_t); + int mknod(const scope char*, mode_t, dev_t); } else version (CRuntime_Musl) { @@ -2455,7 +2510,7 @@ else version (CRuntime_Musl) S_IFSOCK = 0xC000, // octal 0140000 } - int mknod(in char*, mode_t, dev_t); + int mknod(const scope char*, mode_t, dev_t); } else version (CRuntime_UClibc) { @@ -2468,7 +2523,7 @@ else version (CRuntime_UClibc) enum S_IFLNK = 0xA000; // octal 0120000 enum S_IFSOCK = 0xC000; // octal 0140000 - int mknod(in char*, mode_t, dev_t); + int mknod(const scope char*, mode_t, dev_t); } else { diff --git a/libphobos/libdruntime/core/sys/posix/sys/statvfs.d b/libphobos/libdruntime/core/sys/posix/sys/statvfs.d index 795d96d87f1..aeaf5bce3fa 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/statvfs.d +++ b/libphobos/libdruntime/core/sys/posix/sys/statvfs.d @@ -8,14 +8,15 @@ The Open Group Base Specifications Issue 7 IEEE Std 1003.1, 2018 Edition) +/ module core.sys.posix.sys.statvfs; -private import core.stdc.config; -private import core.sys.posix.config; +import core.stdc.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; version (Posix): extern (C) : nothrow: @nogc: +@system: version (CRuntime_Glibc) { static if (__WORDSIZE == 32) @@ -181,57 +182,75 @@ else version (FreeBSD) enum FFlag { // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_RDONLY = 1, /* read only filesystem */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_SYNCHRONOUS = 2, /* fs written synchronously */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_NOEXEC = 4, /* can't exec from filesystem */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_NOSUID = 8, /* don't honor setuid fs bits */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_NFS4ACLS = 16, /* enable NFS version 4 ACLs */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_UNION = 32, /* union with underlying fs */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_ASYNC = 64, /* fs written asynchronously */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_SUIDDIR = 128, /* special SUID dir handling */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_SOFTDEP = 256, /* using soft updates */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_NOSYMFOLLOW = 512, /* do not follow symlinks */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_GJOURNAL = 1024, /* GEOM journal support enabled */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_MULTILABEL = 2048, /* MAC support for objects */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_ACLS = 4096, /* ACL support enabled */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_NOATIME = 8192, /* dont update file access time */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_NOCLUSTERR = 16384, /* disable cluster read */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_NOCLUSTERW = 32768, /* disable cluster write */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_SUJ = 65536, /* using journaled soft updates */ // @@@DEPRECATED_2.091@@@ + deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h") MNT_AUTOMOUNTED = 131072 /* mounted by automountd(8) */ } @@ -259,8 +278,16 @@ else version (FreeBSD) enum uint ST_RDONLY = 0x1; enum uint ST_NOSUID = 0x2; - int fstatvfs(int, statvfs_t*); - int statvfs(const char*, statvfs_t*); + version (GNU) + { + int fstatvfs(int, statvfs_t*); + int statvfs(const char*, statvfs_t*); + } + else + { + pragma(mangle, "fstatvfs@FBSD_1.0") int fstatvfs(int, statvfs_t*); + pragma(mangle, "statvfs@FBSD_1.0") int statvfs(const char*, statvfs_t*); + } } else { diff --git a/libphobos/libdruntime/core/sys/posix/sys/time.d b/libphobos/libdruntime/core/sys/posix/sys/time.d index 4c82930ffd6..95cf88364c7 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/time.d +++ b/libphobos/libdruntime/core/sys/posix/sys/time.d @@ -14,7 +14,7 @@ */ module core.sys.posix.sys.time; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for time_t, suseconds_t public import core.sys.posix.sys.select; // for fd_set, FD_CLR() FD_ISSET() FD_SET() FD_ZERO() FD_SETSIZE, select() @@ -31,6 +31,7 @@ version (linux) public import core.sys.linux.sys.time; version (Posix): extern (C) nothrow @nogc: +@system: // // XOpen (XSI) @@ -55,8 +56,8 @@ ITIMER_PROF int getitimer(int, itimerval*); int gettimeofday(timeval*, void*); int select(int, fd_set*, fd_set*, fd_set*, timeval*); (defined in core.sys.posix.sys.signal) -int setitimer(int, in itimerval*, itimerval*); -int utimes(in char*, ref const(timeval)[2]); // LEGACY +int setitimer(int, const scope itimerval*, itimerval*); +int utimes(const scope char*, ref const(timeval)[2]); // LEGACY */ version (CRuntime_Glibc) @@ -79,8 +80,8 @@ version (CRuntime_Glibc) int getitimer(int, itimerval*); int gettimeofday(timeval*, void*); - int setitimer(int, in itimerval*, itimerval*); - int utimes(in char*, ref const(timeval)[2]); // LEGACY + int setitimer(int, const scope itimerval*, itimerval*); + int utimes(const scope char*, ref const(timeval)[2]); // LEGACY } else version (CRuntime_Musl) { @@ -90,7 +91,7 @@ else version (CRuntime_Musl) suseconds_t tv_usec; } int gettimeofday(timeval*, void*); - int utimes(in char*, ref const(timeval)[2]); + int utimes(const scope char*, ref const(timeval)[2]); } else version (Darwin) { @@ -115,8 +116,8 @@ else version (Darwin) int getitimer(int, itimerval*); int gettimeofday(timeval*, timezone_t*); // timezone_t* is normally void* - int setitimer(int, in itimerval*, itimerval*); - int utimes(in char*, ref const(timeval)[2]); + int setitimer(int, const scope itimerval*, itimerval*); + int utimes(const scope char*, ref const(timeval)[2]); } else version (FreeBSD) { @@ -141,8 +142,8 @@ else version (FreeBSD) int getitimer(int, itimerval*); int gettimeofday(timeval*, timezone_t*); // timezone_t* is normally void* - int setitimer(int, in itimerval*, itimerval*); - int utimes(in char*, ref const(timeval)[2]); + int setitimer(int, const scope itimerval*, itimerval*); + int utimes(const scope char*, ref const(timeval)[2]); } else version (NetBSD) { @@ -160,8 +161,8 @@ else version (NetBSD) int getitimer(int, itimerval*); int gettimeofday(timeval*, void*); // timezone_t* is normally void* - int setitimer(int, in itimerval*, itimerval*); - int utimes(in char*, ref const(timeval)[2]); + int setitimer(int, const scope itimerval*, itimerval*); + int utimes(const scope char*, ref const(timeval)[2]); } else version (OpenBSD) { @@ -186,8 +187,8 @@ else version (OpenBSD) int getitimer(int, itimerval*); int gettimeofday(timeval*, timezone_t*); - int setitimer(int, in itimerval*, itimerval*); - int utimes(in char*, ref const(timeval)[2]); + int setitimer(int, const scope itimerval*, itimerval*); + int utimes(const scope char*, ref const(timeval)[2]); } else version (DragonFlyBSD) { @@ -212,8 +213,8 @@ else version (DragonFlyBSD) int getitimer(int, itimerval*); int gettimeofday(timeval*, timezone_t*); // timezone_t* is normally void* - int setitimer(int, in itimerval*, itimerval*); - int utimes(in char*, ref const(timeval)[2]); + int setitimer(int, const scope itimerval*, itimerval*); + int utimes(const scope char*, ref const(timeval)[2]); } else version (Solaris) { @@ -231,8 +232,8 @@ else version (Solaris) int getitimer(int, itimerval*); int gettimeofday(timeval*, void*); - int setitimer(int, in itimerval*, itimerval*); - int utimes(in char*, ref const(timeval)[2]); + int setitimer(int, const scope itimerval*, itimerval*); + int utimes(const scope char*, ref const(timeval)[2]); } else version (CRuntime_Bionic) { @@ -260,8 +261,8 @@ else version (CRuntime_Bionic) int getitimer(int, itimerval*); int gettimeofday(timeval*, timezone_t*); - int setitimer(int, in itimerval*, itimerval*); - int utimes(in char*, ref const(timeval)[2]); + int setitimer(int, const scope itimerval*, itimerval*); + int utimes(const scope char*, ref const(timeval)[2]); } else version (CRuntime_UClibc) { @@ -283,8 +284,8 @@ else version (CRuntime_UClibc) int getitimer(int, itimerval*); int gettimeofday(timeval*, void*); - int setitimer(int, in itimerval*, itimerval*); - int utimes(in char*, ref const(timeval)[2]); + int setitimer(int, const scope itimerval*, itimerval*); + int utimes(const scope char*, ref const(timeval)[2]); } else { diff --git a/libphobos/libdruntime/core/sys/posix/sys/ttycom.d b/libphobos/libdruntime/core/sys/posix/sys/ttycom.d old mode 100644 new mode 100755 index 38abb2fcf86..1a6c11be291 --- a/libphobos/libdruntime/core/sys/posix/sys/ttycom.d +++ b/libphobos/libdruntime/core/sys/posix/sys/ttycom.d @@ -22,6 +22,7 @@ else version (WatchOS) version (Posix): nothrow @nogc: +@system: version (Darwin) { diff --git a/libphobos/libdruntime/core/sys/posix/sys/types.d b/libphobos/libdruntime/core/sys/posix/sys/types.d index 2d8ef92720e..8e84ddb4c60 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/types.d +++ b/libphobos/libdruntime/core/sys/posix/sys/types.d @@ -15,8 +15,8 @@ */ module core.sys.posix.sys.types; -private import core.sys.posix.config; -private import core.stdc.stdint; +import core.sys.posix.config; +import core.stdc.stdint; public import core.stdc.stddef; version (OSX) @@ -30,6 +30,7 @@ else version (WatchOS) version (Posix): extern (C): +@system: // // bits/typesizes.h -- underlying types for *_t. @@ -139,10 +140,33 @@ else version (CRuntime_Musl) alias int pid_t; alias uint uid_t; alias uint gid_t; + + /** + * Musl versions before v1.2.0 (up to v1.1.24) had different + * definitions for `time_t` for 32 bits. + * This was changed to always be 64 bits in v1.2.0: + * https://musl.libc.org/time64.html + * This change was only for 32 bits system and + * didn't affect 64 bits systems + * + * To check previous definitions, `grep` for `time_t` in `arch/`, + * and the result should be (in v1.1.24): + * --- + * // arch/riscv64/bits/alltypes.h.in:20:TYPEDEF long time_t; + * // arch/s390x/bits/alltypes.h.in:17:TYPEDEF long time_t; + * // arch/sh/bits/alltypes.h.in:21:TYPEDEF long time_t; + * --- + * + * In order to be compatible with old versions of Musl, + * one can recompile druntime with `CRuntime_Musl_Pre_Time64`. + */ version (D_X32) alias long time_t; - else + else version (CRuntime_Musl_Pre_Time64) alias c_long time_t; + else + alias long time_t; + alias c_long clock_t; alias c_ulong pthread_t; version (D_LP64) @@ -688,6 +712,18 @@ version (CRuntime_Glibc) enum __SIZEOF_PTHREAD_BARRIER_T = 32; enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4; } + else version (SPARC) + { + enum __SIZEOF_PTHREAD_ATTR_T = 36; + enum __SIZEOF_PTHREAD_MUTEX_T = 24; + enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4; + enum __SIZEOF_PTHREAD_COND_T = 48; + enum __SIZEOF_PTHREAD_CONDATTR_T = 4; + enum __SIZEOF_PTHREAD_RWLOCK_T = 32; + enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8; + enum __SIZEOF_PTHREAD_BARRIER_T = 20; + enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4; + } else version (SPARC64) { enum __SIZEOF_PTHREAD_ATTR_T = 56; diff --git a/libphobos/libdruntime/core/sys/posix/sys/uio.d b/libphobos/libdruntime/core/sys/posix/sys/uio.d index df34ef35c2a..2563c6df5ad 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/uio.d +++ b/libphobos/libdruntime/core/sys/posix/sys/uio.d @@ -14,7 +14,7 @@ */ module core.sys.posix.sys.uio; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for ssize_t version (OSX) @@ -28,6 +28,7 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: +@system: // // Required @@ -42,8 +43,8 @@ struct iovec ssize_t // from core.sys.posix.sys.types size_t // from core.sys.posix.sys.types -ssize_t readv(int, in iovec*, int); -ssize_t writev(int, in iovec*, int); +ssize_t readv(int, const scope iovec*, int); +ssize_t writev(int, const scope iovec*, int); */ version (CRuntime_Glibc) @@ -54,8 +55,8 @@ version (CRuntime_Glibc) size_t iov_len; } - ssize_t readv(int, in iovec*, int); - ssize_t writev(int, in iovec*, int); + ssize_t readv(int, const scope iovec*, int); + ssize_t writev(int, const scope iovec*, int); } else version (Darwin) { @@ -65,8 +66,8 @@ else version (Darwin) size_t iov_len; } - ssize_t readv(int, in iovec*, int); - ssize_t writev(int, in iovec*, int); + ssize_t readv(int, const scope iovec*, int); + ssize_t writev(int, const scope iovec*, int); } else version (FreeBSD) { @@ -76,8 +77,8 @@ else version (FreeBSD) size_t iov_len; } - ssize_t readv(int, in iovec*, int); - ssize_t writev(int, in iovec*, int); + ssize_t readv(int, const scope iovec*, int); + ssize_t writev(int, const scope iovec*, int); } else version (NetBSD) { @@ -87,8 +88,8 @@ else version (NetBSD) size_t iov_len; } - ssize_t readv(int, in iovec*, int); - ssize_t writev(int, in iovec*, int); + ssize_t readv(int, const scope iovec*, int); + ssize_t writev(int, const scope iovec*, int); } else version (OpenBSD) { @@ -98,8 +99,8 @@ else version (OpenBSD) size_t iov_len; } - ssize_t readv(int, in iovec*, int); - ssize_t writev(int, in iovec*, int); + ssize_t readv(int, const scope iovec*, int); + ssize_t writev(int, const scope iovec*, int); } else version (DragonFlyBSD) { @@ -109,8 +110,8 @@ else version (DragonFlyBSD) size_t iov_len; } - ssize_t readv(int, in iovec*, int); - ssize_t writev(int, in iovec*, int); + ssize_t readv(int, const scope iovec*, int); + ssize_t writev(int, const scope iovec*, int); } else version (Solaris) { @@ -120,8 +121,8 @@ else version (Solaris) size_t iov_len; } - ssize_t readv(int, in iovec*, int); - ssize_t writev(int, in iovec*, int); + ssize_t readv(int, const scope iovec*, int); + ssize_t writev(int, const scope iovec*, int); } else version (CRuntime_Bionic) { @@ -131,8 +132,8 @@ else version (CRuntime_Bionic) size_t iov_len; } - int readv(int, in iovec*, int); - int writev(int, in iovec*, int); + int readv(int, const scope iovec*, int); + int writev(int, const scope iovec*, int); } else version (CRuntime_Musl) { @@ -142,8 +143,8 @@ else version (CRuntime_Musl) size_t iov_len; } - ssize_t readv(int, in iovec*, int); - ssize_t writev(int, in iovec*, int); + ssize_t readv(int, const scope iovec*, int); + ssize_t writev(int, const scope iovec*, int); } else version (CRuntime_UClibc) { @@ -153,8 +154,8 @@ else version (CRuntime_UClibc) size_t iov_len; } - ssize_t readv(int, in iovec*, int); - ssize_t writev(int, in iovec*, int); + ssize_t readv(int, const scope iovec*, int); + ssize_t writev(int, const scope iovec*, int); } else { diff --git a/libphobos/libdruntime/core/sys/posix/sys/un.d b/libphobos/libdruntime/core/sys/posix/sys/un.d index 11e98a72ab2..5030e16f258 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/un.d +++ b/libphobos/libdruntime/core/sys/posix/sys/un.d @@ -25,6 +25,7 @@ else version (WatchOS) version (Posix): extern(C): +@system: public import core.sys.posix.sys.socket: sa_family_t; diff --git a/libphobos/libdruntime/core/sys/posix/sys/utsname.d b/libphobos/libdruntime/core/sys/posix/sys/utsname.d index 5de50aca465..0abbf14dfe2 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/utsname.d +++ b/libphobos/libdruntime/core/sys/posix/sys/utsname.d @@ -16,6 +16,7 @@ version (Posix): extern(C): nothrow: @nogc: +@system: version (CRuntime_Glibc) { diff --git a/libphobos/libdruntime/core/sys/posix/sys/wait.d b/libphobos/libdruntime/core/sys/posix/sys/wait.d index 322326d990b..dada64f5e1a 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/wait.d +++ b/libphobos/libdruntime/core/sys/posix/sys/wait.d @@ -14,7 +14,7 @@ */ module core.sys.posix.sys.wait; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for id_t, pid_t public import core.sys.posix.signal; // for siginfo_t (XSI) //public import core.sys.posix.resource; // for rusage (XSI) @@ -30,6 +30,7 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: +@system: // // Required @@ -52,6 +53,8 @@ pid_t waitpid(pid_t, int*, int); version (CRuntime_Glibc) { + @safe pure: + enum WNOHANG = 1; enum WUNTRACED = 2; @@ -80,6 +83,8 @@ version (CRuntime_Glibc) } else version (Darwin) { + @safe pure: + enum WNOHANG = 1; enum WUNTRACED = 2; @@ -102,6 +107,8 @@ else version (Darwin) } else version (FreeBSD) { + @safe pure: + enum WNOHANG = 1; enum WUNTRACED = 2; @@ -124,6 +131,8 @@ else version (FreeBSD) } else version (NetBSD) { + @safe pure: + enum WNOHANG = 1; enum WUNTRACED = 2; @@ -146,6 +155,8 @@ else version (NetBSD) } else version (OpenBSD) { + @safe pure: + enum WNOHANG = 1; enum WUNTRACED = 2; @@ -169,6 +180,8 @@ else version (OpenBSD) } else version (DragonFlyBSD) { + @safe pure: + enum WNOHANG = 1; enum WUNTRACED = 2; @@ -191,6 +204,8 @@ else version (DragonFlyBSD) } else version (Solaris) { + @safe pure: + enum WNOHANG = 64; enum WUNTRACED = 4; @@ -204,6 +219,8 @@ else version (Solaris) } else version (CRuntime_Bionic) { + @safe pure: + enum WNOHANG = 1; enum WUNTRACED = 2; @@ -216,6 +233,8 @@ else version (CRuntime_Bionic) } else version (CRuntime_Musl) { + @safe pure: + enum WNOHANG = 1; enum WUNTRACED = 2; @@ -229,6 +248,8 @@ else version (CRuntime_Musl) } else version (CRuntime_UClibc) { + @safe pure: + enum WNOHANG = 1; enum WUNTRACED = 2; @@ -326,8 +347,30 @@ else version (FreeBSD) enum WSTOPPED = WUNTRACED; enum WCONTINUED = 4; enum WNOWAIT = 8; + enum WEXITED = 16; + enum WTRAPPED = 32; + + enum idtype_t + { + P_UID, + P_GID, + P_SID, + P_JAILID, + P_PID, + P_PPID, + P_PGID, + P_CID, + P_ALL, + P_LWPID, + P_TASKID, + P_PROJID, + P_POOLID, + P_CTID, + P_CPUID, + P_PSETID + } - // http://www.freebsd.org/projects/c99/ + int waitid(idtype_t, id_t, siginfo_t*, int); } else version (NetBSD) { diff --git a/libphobos/libdruntime/core/sys/posix/syslog.d b/libphobos/libdruntime/core/sys/posix/syslog.d index a319b01bd0d..cf85664590c 100644 --- a/libphobos/libdruntime/core/sys/posix/syslog.d +++ b/libphobos/libdruntime/core/sys/posix/syslog.d @@ -27,6 +27,7 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: +@system: version (CRuntime_Glibc) { @@ -40,7 +41,7 @@ version (CRuntime_Glibc) LOG_NOTICE = 5, /* normal but significant condition */ LOG_INFO = 6, /* informational */ LOG_DEBUG = 7, /* debug-level messages */ - }; + } //OPTIONS enum { @@ -50,7 +51,7 @@ version (CRuntime_Glibc) LOG_NDELAY = 0x08, /* don't delay open */ LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */ LOG_PERROR = 0x20, /* log to stderr as well */ - }; + } //FACILITY enum { @@ -78,7 +79,7 @@ version (CRuntime_Glibc) LOG_LOCAL7 = (23<<3), /* reserved for local use */ LOG_NFACILITIES = 24, /* current number of facilities */ - }; + } int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */ int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */ @@ -102,7 +103,7 @@ else version (Darwin) LOG_NOTICE = 5, /* normal but significant condition */ LOG_INFO = 6, /* informational */ LOG_DEBUG = 7, /* debug-level messages */ - }; + } //OPTIONS enum { @@ -111,7 +112,7 @@ else version (Darwin) LOG_ODELAY = 0x04, /* delay open until first syslog() (default) */ LOG_NDELAY = 0x08, /* don't delay open */ LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */ - }; + } //FACILITY enum { @@ -136,7 +137,7 @@ else version (Darwin) LOG_LOCAL7 = (23<<3), /* reserved for local use */ LOG_NFACILITIES = 24, /* current number of facilities */ - }; + } int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */ int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */ @@ -160,7 +161,7 @@ else version (FreeBSD) LOG_NOTICE = 5, /* normal but significant condition */ LOG_INFO = 6, /* informational */ LOG_DEBUG = 7, /* debug-level messages */ - }; + } //OPTIONS enum { @@ -170,7 +171,7 @@ else version (FreeBSD) LOG_NDELAY = 0x08, /* don't delay open */ LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */ LOG_PERROR = 0x20, /* log to stderr as well */ - }; + } //FACILITY enum { @@ -201,7 +202,7 @@ else version (FreeBSD) LOG_LOCAL7 = (23<<3), /* reserved for local use */ LOG_NFACILITIES = 24, /* current number of facilities */ - }; + } int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */ int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */ @@ -225,7 +226,7 @@ else version (NetBSD) LOG_NOTICE = 5, /* normal but significant condition */ LOG_INFO = 6, /* informational */ LOG_DEBUG = 7, /* debug-level messages */ - }; + } //OPTIONS enum { @@ -235,7 +236,7 @@ else version (NetBSD) LOG_NDELAY = 0x08, /* don't delay open */ LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */ LOG_PERROR = 0x20, /* log to stderr as well */ - }; + } //FACILITY enum { @@ -266,7 +267,7 @@ else version (NetBSD) LOG_LOCAL7 = (23<<3), /* reserved for local use */ LOG_NFACILITIES = 24, /* current number of facilities */ - }; + } int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */ int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */ @@ -355,7 +356,7 @@ else version (DragonFlyBSD) LOG_NOTICE = 5, /* normal but significant condition */ LOG_INFO = 6, /* informational */ LOG_DEBUG = 7, /* debug-level messages */ - }; + } //OPTIONS enum { @@ -365,7 +366,7 @@ else version (DragonFlyBSD) LOG_NDELAY = 0x08, /* don't delay open */ LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */ LOG_PERROR = 0x20, /* log to stderr as well */ - }; + } //FACILITY enum { @@ -396,7 +397,7 @@ else version (DragonFlyBSD) LOG_LOCAL7 = (23<<3), /* reserved for local use */ LOG_NFACILITIES = 24, /* current number of facilities */ - }; + } int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */ int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */ @@ -420,7 +421,7 @@ else version (Solaris) LOG_NOTICE = 5, /* normal but significant condition */ LOG_INFO = 6, /* informational */ LOG_DEBUG = 7, /* debug-level messages */ - }; + } //OPTIONS enum { @@ -428,7 +429,7 @@ else version (Solaris) LOG_CONS = 0x02, /* log on the console if errors in sending */ LOG_NDELAY = 0x08, /* don't delay open */ LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */ - }; + } //FACILITY enum { @@ -456,7 +457,7 @@ else version (Solaris) LOG_LOCAL7 = (23<<3), /* reserved for local use */ LOG_NFACILITIES = 24, /* current number of facilities */ - }; + } int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */ int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */ @@ -478,7 +479,7 @@ else version (CRuntime_UClibc) LOG_NOTICE = 5, /* normal but significant condition */ LOG_INFO = 6, /* informational */ LOG_DEBUG = 7, /* debug-level messages */ - }; + } //OPTIONS enum { @@ -488,7 +489,7 @@ else version (CRuntime_UClibc) LOG_NDELAY = 0x08, /* don't delay open */ LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */ LOG_PERROR = 0x20, /* log to stderr as well */ - }; + } //FACILITY enum { @@ -516,7 +517,7 @@ else version (CRuntime_UClibc) LOG_LOCAL7 = (23<<3), /* reserved for local use */ LOG_NFACILITIES = 24, /* current number of facilities */ - }; + } int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */ int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */ @@ -538,7 +539,7 @@ else version (CRuntime_Musl) LOG_NOTICE = 5, /* normal but significant condition */ LOG_INFO = 6, /* informational */ LOG_DEBUG = 7, /* debug-level messages */ - }; + } //OPTIONS enum { @@ -548,7 +549,7 @@ else version (CRuntime_Musl) LOG_NDELAY = 0x08, /* don't delay open */ LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */ LOG_PERROR = 0x20, /* log to stderr as well */ - }; + } //FACILITY enum { @@ -576,7 +577,7 @@ else version (CRuntime_Musl) LOG_LOCAL7 = (23<<3), /* reserved for local use */ LOG_NFACILITIES = 24, /* current number of facilities */ - }; + } int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */ int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */ diff --git a/libphobos/libdruntime/core/sys/posix/termios.d b/libphobos/libdruntime/core/sys/posix/termios.d index f296a7f6f2e..5de678506d9 100644 --- a/libphobos/libdruntime/core/sys/posix/termios.d +++ b/libphobos/libdruntime/core/sys/posix/termios.d @@ -14,7 +14,7 @@ */ module core.sys.posix.termios; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for pid_t version (OSX) @@ -31,6 +31,7 @@ extern (C): nothrow: @nogc: +@system: // // Required @@ -129,8 +130,8 @@ TCION TCOOFF TCOON -speed_t cfgetispeed(in termios*); -speed_t cfgetospeed(in termios*); +speed_t cfgetispeed(const scope termios*); +speed_t cfgetospeed(const scope termios*); int cfsetispeed(termios*, speed_t); int cfsetospeed(termios*, speed_t); int tcdrain(int); @@ -138,7 +139,7 @@ int tcflow(int, int); int tcflush(int, int); int tcgetattr(int, termios*); int tcsendbreak(int, int); -int tcsetattr(int, int, in termios*); +int tcsetattr(int, int, const scope termios*); */ version (CRuntime_Glibc) @@ -239,8 +240,8 @@ version (CRuntime_Glibc) enum TCOOFF = 0; enum TCOON = 1; - speed_t cfgetispeed(in termios*); - speed_t cfgetospeed(in termios*); + speed_t cfgetispeed(const scope termios*); + speed_t cfgetospeed(const scope termios*); int cfsetispeed(termios*, speed_t); int cfsetospeed(termios*, speed_t); int tcdrain(int); @@ -248,7 +249,7 @@ version (CRuntime_Glibc) int tcflush(int, int); int tcgetattr(int, termios*); int tcsendbreak(int, int); - int tcsetattr(int, int, in termios*); + int tcsetattr(int, int, const scope termios*); } else version (Darwin) { @@ -347,8 +348,8 @@ else version (Darwin) enum TCOOFF = 1; enum TCOON = 2; - speed_t cfgetispeed(in termios*); - speed_t cfgetospeed(in termios*); + speed_t cfgetispeed(const scope termios*); + speed_t cfgetospeed(const scope termios*); int cfsetispeed(termios*, speed_t); int cfsetospeed(termios*, speed_t); int tcdrain(int); @@ -356,7 +357,7 @@ else version (Darwin) int tcflush(int, int); int tcgetattr(int, termios*); int tcsendbreak(int, int); - int tcsetattr(int, int, in termios*); + int tcsetattr(int, int, const scope termios*); } else version (FreeBSD) @@ -456,8 +457,8 @@ else version (FreeBSD) enum TCOOFF = 1; enum TCOON = 2; - speed_t cfgetispeed(in termios*); - speed_t cfgetospeed(in termios*); + speed_t cfgetispeed(const scope termios*); + speed_t cfgetospeed(const scope termios*); int cfsetispeed(termios*, speed_t); int cfsetospeed(termios*, speed_t); int tcdrain(int); @@ -465,7 +466,7 @@ else version (FreeBSD) int tcflush(int, int); int tcgetattr(int, termios*); int tcsendbreak(int, int); - int tcsetattr(int, int, in termios*); + int tcsetattr(int, int, const scope termios*); } else version (DragonFlyBSD) { @@ -564,8 +565,8 @@ else version (DragonFlyBSD) enum TCOOFF = 1; enum TCOON = 2; - speed_t cfgetispeed(in termios*); - speed_t cfgetospeed(in termios*); + speed_t cfgetispeed(const scope termios*); + speed_t cfgetospeed(const scope termios*); int cfsetispeed(termios*, speed_t); int cfsetospeed(termios*, speed_t); int tcdrain(int); @@ -573,7 +574,7 @@ else version (DragonFlyBSD) int tcflush(int, int); int tcgetattr(int, termios*); int tcsendbreak(int, int); - int tcsetattr(int, int, in termios*); + int tcsetattr(int, int, const scope termios*); } else version (NetBSD) { @@ -672,8 +673,8 @@ else version (NetBSD) enum TCOOFF = 1; enum TCOON = 2; - speed_t cfgetispeed(in termios*); - speed_t cfgetospeed(in termios*); + speed_t cfgetispeed(const scope termios*); + speed_t cfgetospeed(const scope termios*); int cfsetispeed(termios*, speed_t); int cfsetospeed(termios*, speed_t); int tcdrain(int); @@ -681,7 +682,7 @@ else version (NetBSD) int tcflush(int, int); int tcgetattr(int, termios*); int tcsendbreak(int, int); - int tcsetattr(int, int, in termios*); + int tcsetattr(int, int, const scope termios*); } else version (OpenBSD) { @@ -780,8 +781,8 @@ else version (OpenBSD) enum TCOOFF = 1; enum TCOON = 2; - speed_t cfgetispeed(in termios*); - speed_t cfgetospeed(in termios*); + speed_t cfgetispeed(const scope termios*); + speed_t cfgetospeed(const scope termios*); int cfsetispeed(termios*, speed_t); int cfsetospeed(termios*, speed_t); int tcdrain(int); @@ -789,7 +790,7 @@ else version (OpenBSD) int tcflush(int, int); int tcgetattr(int, termios*); int tcsendbreak(int, int); - int tcsetattr(int, int, in termios*); + int tcsetattr(int, int, const scope termios*); } else version (Solaris) { @@ -913,12 +914,12 @@ else version (Solaris) * POSIX termios functions * These functions get mapped into ioctls. */ - speed_t cfgetospeed(in termios*); + speed_t cfgetospeed(const scope termios*); int cfsetospeed(termios*, speed_t); - speed_t cfgetispeed(in termios*); + speed_t cfgetispeed(const scope termios*); int cfsetispeed(termios*, speed_t); int tcgetattr(int, termios*); - int tcsetattr(int, int, in termios*); + int tcsetattr(int, int, const scope termios*); int tcsendbreak(int, int); int tcdrain(int); int tcflush(int, int); @@ -1028,8 +1029,8 @@ else version (CRuntime_UClibc) enum TCOOFF = 0; enum TCOON = 1; - speed_t cfgetispeed(in termios*); - speed_t cfgetospeed(in termios*); + speed_t cfgetispeed(const scope termios*); + speed_t cfgetospeed(const scope termios*); int cfsetispeed(termios*, speed_t); int cfsetospeed(termios*, speed_t); int tcdrain(int); @@ -1037,7 +1038,7 @@ else version (CRuntime_UClibc) int tcflush(int, int); int tcgetattr(int, termios*); int tcsendbreak(int, int); - int tcsetattr(int, int, in termios*); + int tcsetattr(int, int, const scope termios*); } // diff --git a/libphobos/libdruntime/core/sys/posix/time.d b/libphobos/libdruntime/core/sys/posix/time.d index 82a3f199247..52a6f92be0a 100644 --- a/libphobos/libdruntime/core/sys/posix/time.d +++ b/libphobos/libdruntime/core/sys/posix/time.d @@ -15,7 +15,7 @@ */ module core.sys.posix.time; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.stdc.time; public import core.sys.posix.sys.types; public import core.sys.posix.signal; // for sigevent @@ -33,19 +33,20 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // Required (defined in core.stdc.time) // /* -char* asctime(in tm*); +char* asctime(const scope tm*); clock_t clock(); -char* ctime(in time_t*); +char* ctime(const scope time_t*); double difftime(time_t, time_t); -tm* gmtime(in time_t*); -tm* localtime(in time_t*); +tm* gmtime(const scope time_t*); +tm* localtime(const scope time_t*); time_t mktime(tm*); -size_t strftime(char*, size_t, in char*, in tm*); +size_t strftime(char*, size_t, const scope char*, const scope tm*); time_t time(time_t*); */ @@ -114,7 +115,7 @@ int clock_getcpuclockid(pid_t, clockid_t*); // Clock Selection (CS) // /* -int clock_nanosleep(clockid_t, int, in timespec*, timespec*); +int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*); */ // @@ -189,13 +190,13 @@ timer_t int clock_getres(clockid_t, timespec*); int clock_gettime(clockid_t, timespec*); -int clock_settime(clockid_t, in timespec*); -int nanosleep(in timespec*, timespec*); +int clock_settime(clockid_t, const scope timespec*); +int nanosleep(const scope timespec*, timespec*); int timer_create(clockid_t, sigevent*, timer_t*); int timer_delete(timer_t); int timer_gettime(timer_t, itimerspec*); int timer_getoverrun(timer_t); -int timer_settime(timer_t, int, in itimerspec*, itimerspec*); +int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); */ version (CRuntime_Glibc) @@ -225,17 +226,17 @@ version (CRuntime_Glibc) int clock_getres(clockid_t, timespec*); int clock_gettime(clockid_t, timespec*); - int clock_settime(clockid_t, in timespec*); - int nanosleep(in timespec*, timespec*); + int clock_settime(clockid_t, const scope timespec*); + int nanosleep(const scope timespec*, timespec*); int timer_create(clockid_t, sigevent*, timer_t*); int timer_delete(timer_t); int timer_gettime(timer_t, itimerspec*); int timer_getoverrun(timer_t); - int timer_settime(timer_t, int, in itimerspec*, itimerspec*); + int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); } else version (Darwin) { - int nanosleep(in timespec*, timespec*); + int nanosleep(const scope timespec*, timespec*); } else version (FreeBSD) { @@ -264,13 +265,13 @@ else version (FreeBSD) int clock_getres(clockid_t, timespec*); int clock_gettime(clockid_t, timespec*); - int clock_settime(clockid_t, in timespec*); - int nanosleep(in timespec*, timespec*); + int clock_settime(clockid_t, const scope timespec*); + int nanosleep(const scope timespec*, timespec*); int timer_create(clockid_t, sigevent*, timer_t*); int timer_delete(timer_t); int timer_gettime(timer_t, itimerspec*); int timer_getoverrun(timer_t); - int timer_settime(timer_t, int, in itimerspec*, itimerspec*); + int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); } else version (DragonFlyBSD) { @@ -290,13 +291,13 @@ else version (DragonFlyBSD) int clock_getres(clockid_t, timespec*); int clock_gettime(clockid_t, timespec*); - int clock_settime(clockid_t, in timespec*); - int nanosleep(in timespec*, timespec*); + int clock_settime(clockid_t, const scope timespec*); + int nanosleep(const scope timespec*, timespec*); int timer_create(clockid_t, sigevent*, timer_t*); int timer_delete(timer_t); int timer_gettime(timer_t, itimerspec*); int timer_getoverrun(timer_t); - int timer_settime(timer_t, int, in itimerspec*, itimerspec*); + int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); } else version (NetBSD) { @@ -314,13 +315,13 @@ else version (NetBSD) int clock_getres(clockid_t, timespec*); int clock_gettime(clockid_t, timespec*); - int clock_settime(clockid_t, in timespec*); - int nanosleep(in timespec*, timespec*); + int clock_settime(clockid_t, const scope timespec*); + int nanosleep(const scope timespec*, timespec*); int timer_create(clockid_t, sigevent*, timer_t*); int timer_delete(timer_t); int timer_gettime(timer_t, itimerspec*); int timer_getoverrun(timer_t); - int timer_settime(timer_t, int, in itimerspec*, itimerspec*); + int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); } else version (OpenBSD) { @@ -338,13 +339,13 @@ else version (OpenBSD) int clock_getres(clockid_t, timespec*); int clock_gettime(clockid_t, timespec*); - int clock_settime(clockid_t, in timespec*); - int nanosleep(in timespec*, timespec*); + int clock_settime(clockid_t, const scope timespec*); + int nanosleep(const scope timespec*, timespec*); int timer_create(clockid_t, sigevent*, timer_t*); int timer_delete(timer_t); int timer_gettime(timer_t, itimerspec*); int timer_getoverrun(timer_t); - int timer_settime(timer_t, int, in itimerspec*, itimerspec*); + int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); } else version (Solaris) { @@ -365,16 +366,16 @@ else version (Solaris) int clock_getres(clockid_t, timespec*); int clock_gettime(clockid_t, timespec*); - int clock_settime(clockid_t, in timespec*); - int clock_nanosleep(clockid_t, int, in timespec*, timespec*); + int clock_settime(clockid_t, const scope timespec*); + int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*); - int nanosleep(in timespec*, timespec*); + int nanosleep(const scope timespec*, timespec*); int timer_create(clockid_t, sigevent*, timer_t*); int timer_delete(timer_t); int timer_getoverrun(timer_t); int timer_gettime(timer_t, itimerspec*); - int timer_settime(timer_t, int, in itimerspec*, itimerspec*); + int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); } else version (CRuntime_Bionic) { @@ -396,12 +397,12 @@ else version (CRuntime_Bionic) int clock_getres(int, timespec*); int clock_gettime(int, timespec*); - int nanosleep(in timespec*, timespec*); + int nanosleep(const scope timespec*, timespec*); int timer_create(int, sigevent*, timer_t*); int timer_delete(timer_t); int timer_gettime(timer_t, itimerspec*); int timer_getoverrun(timer_t); - int timer_settime(timer_t, int, in itimerspec*, itimerspec*); + int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); } else version (CRuntime_Musl) { @@ -426,18 +427,18 @@ else version (CRuntime_Musl) enum CLOCK_SGI_CYCLE = 10; enum CLOCK_TAI = 11; - int nanosleep(in timespec*, timespec*); + int nanosleep(const scope timespec*, timespec*); int clock_getres(clockid_t, timespec*); int clock_gettime(clockid_t, timespec*); - int clock_settime(clockid_t, in timespec*); - int clock_nanosleep(clockid_t, int, in timespec*, timespec*); + int clock_settime(clockid_t, const scope timespec*); + int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*); int clock_getcpuclockid(pid_t, clockid_t *); int timer_create(clockid_t, sigevent*, timer_t*); int timer_delete(timer_t); int timer_gettime(timer_t, itimerspec*); - int timer_settime(timer_t, int, in itimerspec*, itimerspec*); + int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); int timer_getoverrun(timer_t); } else version (CRuntime_UClibc) @@ -459,13 +460,13 @@ else version (CRuntime_UClibc) int clock_getres(clockid_t, timespec*); int clock_gettime(clockid_t, timespec*); - int clock_settime(clockid_t, in timespec*); - int nanosleep(in timespec*, timespec*); + int clock_settime(clockid_t, const scope timespec*); + int nanosleep(const scope timespec*, timespec*); int timer_create(clockid_t, sigevent*, timer_t*); int timer_delete(timer_t); int timer_gettime(timer_t, itimerspec*); int timer_getoverrun(timer_t); - int timer_settime(timer_t, int, in itimerspec*, itimerspec*); + int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); } else { @@ -476,81 +477,81 @@ else // Thread-Safe Functions (TSF) // /* -char* asctime_r(in tm*, char*); -char* ctime_r(in time_t*, char*); -tm* gmtime_r(in time_t*, tm*); -tm* localtime_r(in time_t*, tm*); +char* asctime_r(const scope tm*, char*); +char* ctime_r(const scope time_t*, char*); +tm* gmtime_r(const scope time_t*, tm*); +tm* localtime_r(const scope time_t*, tm*); */ version (CRuntime_Glibc) { - char* asctime_r(in tm*, char*); - char* ctime_r(in time_t*, char*); - tm* gmtime_r(in time_t*, tm*); - tm* localtime_r(in time_t*, tm*); + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); } else version (Darwin) { - char* asctime_r(in tm*, char*); - char* ctime_r(in time_t*, char*); - tm* gmtime_r(in time_t*, tm*); - tm* localtime_r(in time_t*, tm*); + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); } else version (FreeBSD) { - char* asctime_r(in tm*, char*); - char* ctime_r(in time_t*, char*); - tm* gmtime_r(in time_t*, tm*); - tm* localtime_r(in time_t*, tm*); + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); } else version (NetBSD) { - char* asctime_r(in tm*, char*); - char* ctime_r(in time_t*, char*); - tm* gmtime_r(in time_t*, tm*); - tm* localtime_r(in time_t*, tm*); + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); } else version (OpenBSD) { - char* asctime_r(in tm*, char*); - char* ctime_r(in time_t*, char*); - tm* gmtime_r(in time_t*, tm*); - tm* localtime_r(in time_t*, tm*); + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); } else version (DragonFlyBSD) { - char* asctime_r(in tm*, char*); - char* ctime_r(in time_t*, char*); - tm* gmtime_r(in time_t*, tm*); - tm* localtime_r(in time_t*, tm*); + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); } else version (Solaris) { - char* asctime_r(in tm*, char*); - char* ctime_r(in time_t*, char*); - tm* gmtime_r(in time_t*, tm*); - tm* localtime_r(in time_t*, tm*); + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); } else version (CRuntime_Bionic) { - char* asctime_r(in tm*, char*); - char* ctime_r(in time_t*, char*); - tm* gmtime_r(in time_t*, tm*); - tm* localtime_r(in time_t*, tm*); + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); } else version (CRuntime_Musl) { - char* asctime_r(in tm*, char*); - char* ctime_r(in time_t*, char*); - tm* gmtime_r(in time_t*, tm*); - tm* localtime_r(in time_t*, tm*); + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); } else version (CRuntime_UClibc) { - char* asctime_r(in tm*, char*); - char* ctime_r(in time_t*, char*); - tm* gmtime_r(in time_t*, tm*); - tm* localtime_r(in time_t*, tm*); + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); } else { @@ -566,8 +567,8 @@ getdate_err int daylight; int timezone; -tm* getdate(in char*); -char* strptime(in char*, in char*, tm*); +tm* getdate(const scope char*); +char* strptime(const scope char*, const scope char*, tm*); */ version (CRuntime_Glibc) @@ -575,44 +576,44 @@ version (CRuntime_Glibc) extern __gshared int daylight; extern __gshared c_long timezone; - tm* getdate(in char*); - char* strptime(in char*, in char*, tm*); + tm* getdate(const scope char*); + char* strptime(const scope char*, const scope char*, tm*); } else version (Darwin) { extern __gshared c_long timezone; extern __gshared int daylight; - tm* getdate(in char*); - char* strptime(in char*, in char*, tm*); + tm* getdate(const scope char*); + char* strptime(const scope char*, const scope char*, tm*); } else version (FreeBSD) { - //tm* getdate(in char*); - char* strptime(in char*, in char*, tm*); + //tm* getdate(const scope char*); + char* strptime(const scope char*, const scope char*, tm*); } else version (NetBSD) { - tm* getdate(in char*); - char* strptime(in char*, in char*, tm*); + tm* getdate(const scope char*); + char* strptime(const scope char*, const scope char*, tm*); } else version (OpenBSD) { - //tm* getdate(in char*); - char* strptime(in char*, in char*, tm*); + //tm* getdate(const scope char*); + char* strptime(const scope char*, const scope char*, tm*); } else version (DragonFlyBSD) { - //tm* getdate(in char*); - char* strptime(in char*, in char*, tm*); + //tm* getdate(const scope char*); + char* strptime(const scope char*, const scope char*, tm*); } else version (Solaris) { extern __gshared c_long timezone, altzone; extern __gshared int daylight; - tm* getdate(in char*); - char* __strptime_dontzero(in char*, in char*, tm*); + tm* getdate(const scope char*); + char* __strptime_dontzero(const scope char*, const scope char*, tm*); alias __strptime_dontzero strptime; } else version (CRuntime_Bionic) @@ -620,23 +621,23 @@ else version (CRuntime_Bionic) extern __gshared int daylight; extern __gshared c_long timezone; - char* strptime(in char*, in char*, tm*); + char* strptime(const scope char*, const scope char*, tm*); } else version (CRuntime_Musl) { extern __gshared int daylight; extern __gshared c_long timezone; - tm* getdate(in char*); - char* strptime(in char*, in char*, tm*); + tm* getdate(const scope char*); + char* strptime(const scope char*, const scope char*, tm*); } else version (CRuntime_UClibc) { extern __gshared int daylight; extern __gshared c_long timezone; - tm* getdate(in char*); - char* strptime(in char*, in char*, tm*); + tm* getdate(const scope char*); + char* strptime(const scope char*, const scope char*, tm*); } else { diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d index 2e518aefa84..e38aa96d8eb 100644 --- a/libphobos/libdruntime/core/sys/posix/ucontext.d +++ b/libphobos/libdruntime/core/sys/posix/ucontext.d @@ -14,15 +14,27 @@ */ module core.sys.posix.ucontext; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.signal; // for sigset_t, stack_t -private import core.stdc.stdint : uintptr_t; +import core.stdc.stdint : uintptr_t; version (Posix): extern (C): nothrow: @nogc: - +@system: + +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + +version (ARM) version = ARM_Any; +version (AArch64) version = ARM_Any; version (MIPS32) version = MIPS_Any; version (MIPS64) version = MIPS_Any; version (PPC) version = PPC_Any; @@ -648,7 +660,7 @@ version (CRuntime_Glibc) mcontext_t uc_mcontext; } } - else version (SPARC64) + else version (SPARC_Any) { enum MC_NGREG = 19; alias mc_greg_t = c_ulong; @@ -909,6 +921,72 @@ else version (CRuntime_Musl) else static assert(0, "unimplemented"); } +else version (Darwin) +{ + private + { + version (X86_64) + { + struct __darwin_mcontext + { + ulong[89] __opaque; + } + static assert(__darwin_mcontext.sizeof == 712); + } + else version (X86) + { + struct __darwin_mcontext + { + uint[150] __opaque; + } + static assert(__darwin_mcontext.sizeof == 600); + } + else version (AArch64) + { + struct __darwin_mcontext + { + align(16) ulong[102] __opaque; + } + static assert(__darwin_mcontext.sizeof == 816); + } + else version (ARM) + { + struct __darwin_mcontext + { + uint[85] __opaque; + } + static assert(__darwin_mcontext.sizeof == 340); + } + else version (PPC_Any) + { + struct __darwin_mcontext + { + version (PPC64) + ulong[129] __opaque; + else + uint[258] __opaque; + } + static assert(__darwin_mcontext.sizeof == 1032); + } + else + static assert(false, "mcontext_t unimplemented for this platform."); + } + + alias mcontext_t = __darwin_mcontext*; + + struct ucontext + { + int uc_onstack; + sigset_t uc_sigmask; + stack_t uc_stack; + ucontext* uc_link; + size_t uc_mcsize; + __darwin_mcontext* uc_mcontext; + __darwin_mcontext __mcontext_data; + } + + alias ucontext_t = ucontext; +} else version (FreeBSD) { // @@ -1278,7 +1356,7 @@ else version (OpenBSD) int sc_trapno; int sc_err; void* sc_fpstate; // union savefpu* - }; + } } else version (PPC) { @@ -1365,7 +1443,7 @@ else version (DragonFlyBSD) uint mc_reserved; uint[8] mc_unused; int[256] mc_fpregs; - }; // __attribute__((aligned(64))); + } // __attribute__((aligned(64))); } else { @@ -1389,7 +1467,7 @@ else version (DragonFlyBSD) } else version (Solaris) { - private import core.stdc.stdint; + import core.stdc.stdint; alias uint[4] upad128_t; @@ -1479,7 +1557,7 @@ else version (Solaris) { uint[32] fpu_regs; double[16] fpu_dregs; - }; + } fq *fpu_q; uint fpu_fsr; ubyte fpu_qcnt; @@ -1831,8 +1909,8 @@ else version (CRuntime_UClibc) /* int getcontext(ucontext_t*); void makecontext(ucontext_t*, void function(), int, ...); -int setcontext(in ucontext_t*); -int swapcontext(ucontext_t*, in ucontext_t*); +int setcontext(const scope ucontext_t*); +int swapcontext(ucontext_t*, const scope ucontext_t*); */ static if ( is( ucontext_t ) ) @@ -1852,13 +1930,13 @@ static if ( is( ucontext_t ) ) else void makecontext(ucontext_t*, void function(), int, ...); - int setcontext(in ucontext_t*); - int swapcontext(ucontext_t*, in ucontext_t*); + int setcontext(const scope ucontext_t*); + int swapcontext(ucontext_t*, const scope ucontext_t*); } version (Solaris) { - int walkcontext(in ucontext_t*, int function(uintptr_t, int, void*), void*); + int walkcontext(const scope ucontext_t*, int function(uintptr_t, int, void*), void*); int addrtosymstr(uintptr_t, char*, int); int printstack(int); } diff --git a/libphobos/libdruntime/core/sys/posix/unistd.d b/libphobos/libdruntime/core/sys/posix/unistd.d index 418d63d439b..a691884cb2e 100644 --- a/libphobos/libdruntime/core/sys/posix/unistd.d +++ b/libphobos/libdruntime/core/sys/posix/unistd.d @@ -14,8 +14,8 @@ */ module core.sys.posix.unistd; -private import core.sys.posix.config; -private import core.stdc.stddef; +import core.sys.posix.config; +import core.stdc.stddef; public import core.sys.posix.inttypes; // for intptr_t public import core.sys.posix.sys.types; // for ssize_t, uid_t, gid_t, off_t, pid_t, useconds_t @@ -32,6 +32,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: enum STDIN_FILENO = 0; enum STDOUT_FILENO = 1; @@ -42,20 +43,20 @@ extern __gshared int optind; extern __gshared int opterr; extern __gshared int optopt; -int access(in char*, int); +int access(const scope char*, int); uint alarm(uint) @trusted; -int chdir(in char*); -int chown(in char*, uid_t, gid_t); +int chdir(const scope char*); +int chown(const scope char*, uid_t, gid_t); int close(int) @trusted; size_t confstr(int, char*, size_t); int dup(int) @trusted; int dup2(int, int) @trusted; -int execl(in char*, in char*, ...); -int execle(in char*, in char*, ...); -int execlp(in char*, in char*, ...); -int execv(in char*, in char**); -int execve(in char*, in char**, in char**); -int execvp(in char*, in char**); +int execl(const scope char*, const scope char*, ...); +int execle(const scope char*, const scope char*, ...); +int execlp(const scope char*, const scope char*, ...); +int execv(const scope char*, const scope char**); +int execve(const scope char*, const scope char**, const scope char**); +int execvp(const scope char*, const scope char**); void _exit(int) @trusted; int fchown(int, uid_t, gid_t) @trusted; pid_t fork() @trusted; @@ -69,36 +70,36 @@ int getgroups(int, gid_t *); int gethostname(char*, size_t); char* getlogin() @trusted; int getlogin_r(char*, size_t); -int getopt(int, in char**, in char*); +int getopt(int, const scope char**, const scope char*); pid_t getpgrp() @trusted; pid_t getpid() @trusted; pid_t getppid() @trusted; uid_t getuid() @trusted; int isatty(int) @trusted; -int link(in char*, in char*); +int link(const scope char*, const scope char*); //off_t lseek(int, off_t, int); -c_long pathconf(in char*, int); +c_long pathconf(const scope char*, int); int pause() @trusted; int pipe(ref int[2]) @trusted; ssize_t read(int, void*, size_t); -ssize_t readlink(in char*, char*, size_t); -int rmdir(in char*); +ssize_t readlink(const scope char*, char*, size_t); +int rmdir(const scope char*); int setegid(gid_t) @trusted; int seteuid(uid_t) @trusted; int setgid(gid_t) @trusted; -int setgroups(size_t, in gid_t*) @trusted; +int setgroups(size_t, const scope gid_t*) @trusted; int setpgid(pid_t, pid_t) @trusted; pid_t setsid() @trusted; int setuid(uid_t) @trusted; uint sleep(uint) @trusted; -int symlink(in char*, in char*); +int symlink(const scope char*, const scope char*); c_long sysconf(int) @trusted; pid_t tcgetpgrp(int) @trusted; int tcsetpgrp(int, pid_t) @trusted; char* ttyname(int) @trusted; int ttyname_r(int, char*, size_t); -int unlink(in char*); -ssize_t write(int, in void*, size_t); +int unlink(const scope char*); +ssize_t write(int, const scope void*, size_t); version (CRuntime_Glibc) { @@ -2400,7 +2401,7 @@ else version (CRuntime_UClibc) // XOpen (XSI) // /* -char* crypt(in char*, in char*); +char* crypt(const scope char*, const scope char*); char* ctermid(char*); void encrypt(ref char[64], int); int fchdir(int); @@ -2408,17 +2409,17 @@ c_long gethostid(); pid_t getpgid(pid_t); pid_t getsid(pid_t); char* getwd(char*); // LEGACY -int lchown(in char*, uid_t, gid_t); +int lchown(const scope char*, uid_t, gid_t); int lockf(int, int, off_t); int nice(int); ssize_t pread(int, void*, size_t, off_t); -ssize_t pwrite(int, in void*, size_t, off_t); +ssize_t pwrite(int, const scope void*, size_t, off_t); pid_t setpgrp(); int setregid(gid_t, gid_t); int setreuid(uid_t, uid_t); -void swab(in void*, void*, ssize_t); +void swab(const scope void*, void*, ssize_t); void sync(); -int truncate(in char*, off_t); +int truncate(const scope char*, off_t); useconds_t ualarm(useconds_t, useconds_t); int usleep(useconds_t); pid_t vfork(); @@ -2426,7 +2427,7 @@ pid_t vfork(); version (CRuntime_Glibc) { - char* crypt(in char*, in char*); + char* crypt(const scope char*, const scope char*); char* ctermid(char*); void encrypt(ref char[64], int) @trusted; int fchdir(int) @trusted; @@ -2434,17 +2435,17 @@ version (CRuntime_Glibc) pid_t getpgid(pid_t) @trusted; pid_t getsid(pid_t) @trusted; char* getwd(char*); // LEGACY - int lchown(in char*, uid_t, gid_t); + int lchown(const scope char*, uid_t, gid_t); //int lockf(int, int, off_t); int nice(int) @trusted; //ssize_t pread(int, void*, size_t, off_t); - //ssize_t pwrite(int, in void*, size_t, off_t); + //ssize_t pwrite(int, const scope void*, size_t, off_t); pid_t setpgrp() @trusted; int setregid(gid_t, gid_t) @trusted; int setreuid(uid_t, uid_t) @trusted; - void swab(in void*, void*, ssize_t); + void swab(const scope void*, void*, ssize_t); void sync() @trusted; - //int truncate(in char*, off_t); + //int truncate(const scope char*, off_t); useconds_t ualarm(useconds_t, useconds_t) @trusted; int usleep(useconds_t) @trusted; pid_t vfork(); @@ -2457,18 +2458,18 @@ version (CRuntime_Glibc) ssize_t pread64(int, void*, size_t, off_t); alias pread64 pread; - ssize_t pwrite64(int, in void*, size_t, off_t); + ssize_t pwrite64(int, const scope void*, size_t, off_t); alias pwrite64 pwrite; - int truncate64(in char*, off_t); + int truncate64(const scope char*, off_t); alias truncate64 truncate; } else { int lockf(int, int, off_t) @trusted; ssize_t pread(int, void*, size_t, off_t); - ssize_t pwrite(int, in void*, size_t, off_t); - int truncate(in char*, off_t); + ssize_t pwrite(int, const scope void*, size_t, off_t); + int truncate(const scope char*, off_t); } } else version (CRuntime_Musl) @@ -2479,7 +2480,7 @@ else version (CRuntime_Musl) } else version (Darwin) { - char* crypt(in char*, in char*); + char* crypt(const scope char*, const scope char*); char* ctermid(char*); void encrypt(ref char[64], int) @trusted; int fchdir(int) @trusted; @@ -2487,24 +2488,24 @@ else version (Darwin) pid_t getpgid(pid_t) @trusted; pid_t getsid(pid_t) @trusted; char* getwd(char*); // LEGACY - int lchown(in char*, uid_t, gid_t); + int lchown(const scope char*, uid_t, gid_t); int lockf(int, int, off_t) @trusted; int nice(int) @trusted; ssize_t pread(int, void*, size_t, off_t); - ssize_t pwrite(int, in void*, size_t, off_t); + ssize_t pwrite(int, const scope void*, size_t, off_t); pid_t setpgrp() @trusted; int setregid(gid_t, gid_t) @trusted; int setreuid(uid_t, uid_t) @trusted; - void swab(in void*, void*, ssize_t); + void swab(const scope void*, void*, ssize_t); void sync() @trusted; - int truncate(in char*, off_t); + int truncate(const scope char*, off_t); useconds_t ualarm(useconds_t, useconds_t) @trusted; int usleep(useconds_t) @trusted; pid_t vfork(); } else version (FreeBSD) { - char* crypt(in char*, in char*); + char* crypt(const scope char*, const scope char*); //char* ctermid(char*); void encrypt(ref char[64], int) @trusted; int fchdir(int) @trusted; @@ -2512,24 +2513,24 @@ else version (FreeBSD) int getpgid(pid_t) @trusted; int getsid(pid_t) @trusted; char* getwd(char*); // LEGACY - int lchown(in char*, uid_t, gid_t); + int lchown(const scope char*, uid_t, gid_t); int lockf(int, int, off_t) @trusted; int nice(int) @trusted; ssize_t pread(int, void*, size_t, off_t); - ssize_t pwrite(int, in void*, size_t, off_t); + ssize_t pwrite(int, const scope void*, size_t, off_t); int setpgrp(pid_t, pid_t) @trusted; int setregid(gid_t, gid_t) @trusted; int setreuid(uid_t, uid_t) @trusted; - void swab(in void*, void*, ssize_t); + void swab(const scope void*, void*, ssize_t); void sync() @trusted; - int truncate(in char*, off_t); + int truncate(const scope char*, off_t); useconds_t ualarm(useconds_t, useconds_t) @trusted; int usleep(useconds_t) @trusted; pid_t vfork(); } else version (NetBSD) { - char* crypt(in char*, in char*); + char* crypt(const scope char*, const scope char*); //char* ctermid(char*); void encrypt(ref char[64], int) @trusted; int fchdir(int) @trusted; @@ -2537,24 +2538,24 @@ else version (NetBSD) int getpgid(pid_t) @trusted; int getsid(pid_t) @trusted; char* getwd(char*); // LEGACY - int lchown(in char*, uid_t, gid_t); + int lchown(const scope char*, uid_t, gid_t); int lockf(int, int, off_t) @trusted; int nice(int) @trusted; ssize_t pread(int, void*, size_t, off_t); - ssize_t pwrite(int, in void*, size_t, off_t); + ssize_t pwrite(int, const scope void*, size_t, off_t); int setpgrp(pid_t, pid_t) @trusted; int setregid(gid_t, gid_t) @trusted; int setreuid(uid_t, uid_t) @trusted; - void swab(in void*, void*, ssize_t); + void swab(const scope void*, void*, ssize_t); void sync() @trusted; - int truncate(in char*, off_t); + int truncate(const scope char*, off_t); useconds_t ualarm(useconds_t, useconds_t) @trusted; int usleep(useconds_t) @trusted; pid_t vfork(); } else version (OpenBSD) { - char* crypt(in char*, in char*); + char* crypt(const scope char*, const scope char*); //char* ctermid(char*); //void encrypt(ref char[64], int) @trusted; int fchdir(int) @trusted; @@ -2562,24 +2563,24 @@ else version (OpenBSD) pid_t getpgid(pid_t) @trusted; pid_t getsid(pid_t) @trusted; char* getwd(char*); - int lchown(in char*, uid_t, gid_t); + int lchown(const scope char*, uid_t, gid_t); int lockf(int, int, off_t) @trusted; int nice(int) @trusted; ssize_t pread(int, void*, size_t, off_t); - ssize_t pwrite(int, in void*, size_t, off_t); + ssize_t pwrite(int, const scope void*, size_t, off_t); int setpgrp(pid_t, pid_t) @trusted; int setregid(gid_t, gid_t) @trusted; int setreuid(uid_t, uid_t) @trusted; - void swab(in void*, void*, ssize_t); + void swab(const scope void*, void*, ssize_t); void sync() @trusted; - int truncate(in char*, off_t); + int truncate(const scope char*, off_t); useconds_t ualarm(useconds_t, useconds_t) @trusted; int usleep(useconds_t) @trusted; pid_t vfork(); } else version (DragonFlyBSD) { - char* crypt(in char*, in char*); + char* crypt(const scope char*, const scope char*); //char* ctermid(char*); void encrypt(ref char[64], int) @trusted; int fchdir(int) @trusted; @@ -2587,17 +2588,17 @@ else version (DragonFlyBSD) int getpgid(pid_t) @trusted; int getsid(pid_t) @trusted; char* getwd(char*); // LEGACY - int lchown(in char*, uid_t, gid_t); + int lchown(const scope char*, uid_t, gid_t); int lockf(int, int, off_t) @trusted; int nice(int) @trusted; ssize_t pread(int, void*, size_t, off_t); - ssize_t pwrite(int, in void*, size_t, off_t); + ssize_t pwrite(int, const scope void*, size_t, off_t); int setpgrp(pid_t, pid_t) @trusted; int setregid(gid_t, gid_t) @trusted; int setreuid(uid_t, uid_t) @trusted; - void swab(in void*, void*, ssize_t); + void swab(const scope void*, void*, ssize_t); void sync() @trusted; - int truncate(in char*, off_t); + int truncate(const scope char*, off_t); useconds_t ualarm(useconds_t, useconds_t) @trusted; int usleep(useconds_t) @trusted; pid_t vfork(); @@ -2606,21 +2607,21 @@ else version (CRuntime_Bionic) { int fchdir(int) @trusted; pid_t getpgid(pid_t) @trusted; - int lchown(in char*, uid_t, gid_t); + int lchown(const scope char*, uid_t, gid_t); int nice(int) @trusted; ssize_t pread(int, void*, size_t, off_t); - ssize_t pwrite(int, in void*, size_t, off_t); + ssize_t pwrite(int, const scope void*, size_t, off_t); int setpgrp() @trusted; int setregid(gid_t, gid_t) @trusted; int setreuid(uid_t, uid_t) @trusted; int sync() @trusted; - int truncate(in char*, off_t); + int truncate(const scope char*, off_t); int usleep(c_ulong) @trusted; pid_t vfork(); } else version (Solaris) { - char* crypt(in char*, in char*); + char* crypt(const scope char*, const scope char*); char* ctermid(char*); void encrypt(ref char[64], int); int fchdir(int); @@ -2628,12 +2629,12 @@ else version (Solaris) pid_t getpgid(pid_t); pid_t getsid(pid_t); char* getwd(char*); // LEGACY - int lchown(in char*, uid_t, gid_t); + int lchown(const scope char*, uid_t, gid_t); int nice(int); pid_t setpgrp(); int setregid(gid_t, gid_t); int setreuid(uid_t, uid_t); - void swab(in void*, void*, ssize_t); + void swab(const scope void*, void*, ssize_t); void sync(); useconds_t ualarm(useconds_t, useconds_t); int usleep(useconds_t); @@ -2647,10 +2648,10 @@ else version (Solaris) ssize_t pread(int, void*, size_t, off_t); alias pread pread64; - ssize_t pwrite(int, in void*, size_t, off_t); + ssize_t pwrite(int, const scope void*, size_t, off_t); alias pwrite pwrite64; - int truncate(in char*, off_t); + int truncate(const scope char*, off_t); alias truncate truncate64; } else @@ -2663,24 +2664,24 @@ else version (Solaris) ssize_t pread64(int, void*, size_t, off64_t); alias pread64 pread; - ssize_t pwrite64(int, in void*, size_t, off_t); + ssize_t pwrite64(int, const scope void*, size_t, off_t); alias pwrite64 pwrite; - int truncate64(in char*, off_t); + int truncate64(const scope char*, off_t); alias truncate64 truncate; } else { int lockf(int, int, off_t); ssize_t pread(int, void*, size_t, off_t); - ssize_t pwrite(int, in void*, size_t, off_t); - int truncate(in char*, off_t); + ssize_t pwrite(int, const scope void*, size_t, off_t); + int truncate(const scope char*, off_t); } } } else version (CRuntime_UClibc) { - char* crypt(in char*, in char*); + char* crypt(const scope char*, const scope char*); char* ctermid(char*); void encrypt(ref char[64], int) @trusted; int fchdir(int) @trusted; @@ -2688,12 +2689,12 @@ else version (CRuntime_UClibc) pid_t getpgid(pid_t) @trusted; pid_t getsid(pid_t) @trusted; char* getwd(char*); // LEGACY - int lchown(in char*, uid_t, gid_t); + int lchown(const scope char*, uid_t, gid_t); int nice(int) @trusted; pid_t setpgrp() @trusted; int setregid(gid_t, gid_t) @trusted; int setreuid(uid_t, uid_t) @trusted; - void swab(in void*, void*, ssize_t); + void swab(const scope void*, void*, ssize_t); void sync() @trusted; useconds_t ualarm(useconds_t, useconds_t) @trusted; int usleep(useconds_t) @trusted; @@ -2707,17 +2708,17 @@ else version (CRuntime_UClibc) ssize_t pread64(int, void*, size_t, off_t); alias pread64 pread; - ssize_t pwrite64(int, in void*, size_t, off_t); + ssize_t pwrite64(int, const scope void*, size_t, off_t); alias pwrite64 pwrite; - int truncate64(in char*, off_t); + int truncate64(const scope char*, off_t); alias truncate64 truncate; } else { int lockf(int, int, off_t) @trusted; ssize_t pread(int, void*, size_t, off_t); - ssize_t pwrite(int, in void*, size_t, off_t); - int truncate(in char*, off_t); + ssize_t pwrite(int, const scope void*, size_t, off_t); + int truncate(const scope char*, off_t); } } diff --git a/libphobos/libdruntime/core/sys/posix/utime.d b/libphobos/libdruntime/core/sys/posix/utime.d index ae54c20b2fc..66aea58d78f 100644 --- a/libphobos/libdruntime/core/sys/posix/utime.d +++ b/libphobos/libdruntime/core/sys/posix/utime.d @@ -14,7 +14,7 @@ */ module core.sys.posix.utime; -private import core.sys.posix.config; +import core.sys.posix.config; public import core.sys.posix.sys.types; // for time_t version (OSX) @@ -30,6 +30,7 @@ version (Posix): extern (C): nothrow: @nogc: +@system: // // Required @@ -41,7 +42,7 @@ struct utimbuf time_t modtime; } -int utime(in char*, in utimbuf*); +int utime(const scope char*, const scope utimbuf*); */ version (CRuntime_Glibc) @@ -52,7 +53,7 @@ version (CRuntime_Glibc) time_t modtime; } - int utime(in char*, in utimbuf*); + int utime(const scope char*, const scope utimbuf*); } else version (CRuntime_Musl) { @@ -62,7 +63,7 @@ else version (CRuntime_Musl) time_t modtime; } - int utime(in char*, in utimbuf*); + int utime(const scope char*, const scope utimbuf*); } else version (Darwin) { @@ -72,7 +73,7 @@ else version (Darwin) time_t modtime; } - int utime(in char*, in utimbuf*); + int utime(const scope char*, const scope utimbuf*); } else version (FreeBSD) { @@ -82,7 +83,7 @@ else version (FreeBSD) time_t modtime; } - int utime(in char*, in utimbuf*); + int utime(const scope char*, const scope utimbuf*); } else version (NetBSD) { @@ -92,7 +93,7 @@ else version (NetBSD) time_t modtime; } - int utime(in char*, in utimbuf*); + int utime(const scope char*, const scope utimbuf*); } else version (OpenBSD) { @@ -102,7 +103,7 @@ else version (OpenBSD) time_t modtime; } - int utime(in char*, in utimbuf*); + int utime(const scope char*, const scope utimbuf*); } else version (DragonFlyBSD) { @@ -112,7 +113,7 @@ else version (DragonFlyBSD) time_t modtime; } - int utime(in char*, in utimbuf*); + int utime(const scope char*, const scope utimbuf*); } else version (Solaris) { @@ -122,7 +123,7 @@ else version (Solaris) time_t modtime; } - int utime(in char*, in utimbuf*); + int utime(const scope char*, const scope utimbuf*); } else version (CRuntime_Bionic) { @@ -132,7 +133,7 @@ else version (CRuntime_Bionic) time_t modtime; } - int utime(in char*, in utimbuf*); + int utime(const scope char*, const scope utimbuf*); } else version (CRuntime_UClibc) { @@ -142,5 +143,5 @@ else version (CRuntime_UClibc) time_t modtime; } - int utime(in char*, in utimbuf*); + int utime(const scope char*, const scope utimbuf*); } diff --git a/libphobos/libdruntime/core/sys/solaris/dlfcn.d b/libphobos/libdruntime/core/sys/solaris/dlfcn.d index d23bdaa0b8d..4f69bfdbcec 100644 --- a/libphobos/libdruntime/core/sys/solaris/dlfcn.d +++ b/libphobos/libdruntime/core/sys/solaris/dlfcn.d @@ -39,7 +39,7 @@ enum alias c_ulong Lmid_t; -void* dlmopen(Lmid_t, in char*, int); +void* dlmopen(Lmid_t, const scope char*, int); enum { @@ -56,7 +56,7 @@ enum RTLD_CONFSET = 0x10000, } -int dldump(in char*, in char*, int); +int dldump(const scope char*, const scope char*, int); struct Dl_info { diff --git a/libphobos/libdruntime/core/sys/solaris/err.d b/libphobos/libdruntime/core/sys/solaris/err.d new file mode 100644 index 00000000000..f7876430150 --- /dev/null +++ b/libphobos/libdruntime/core/sys/solaris/err.d @@ -0,0 +1,23 @@ +/** + * D header file for Solaris err.h. + * + * Copyright: Copyright © 2019, The D Language Foundation + * License: Boost License 1.0. + * Authors: Ernesto Castellotti + */ +module core.sys.solaris.err; +import core.stdc.stdarg : va_list; + +version (Solaris): +extern (C): +nothrow: +@nogc: + +void err(int eval, scope const char* fmt, ...); +void errx(int eval, scope const char* fmt, ...); +void warn(scope const char* fmt, ...); +void warnx(scope const char* fmt, ...); +void verr(int eval, scope const char* fmt, va_list args); +void verrx(int eval, scope const char* fmt, va_list args); +void vwarn(scope const char* fmt, va_list args); +void vwarnx(scope const char* fmt, va_list args); diff --git a/libphobos/libdruntime/core/sys/solaris/libelf.d b/libphobos/libdruntime/core/sys/solaris/libelf.d index d0e6aa7b82a..a8d3c1f514f 100644 --- a/libphobos/libdruntime/core/sys/solaris/libelf.d +++ b/libphobos/libdruntime/core/sys/solaris/libelf.d @@ -131,7 +131,7 @@ int elf_getshnum(Elf*, size_t*); int elf_getshdrnum(Elf*, size_t*); int elf_getshstrndx(Elf*, size_t*); int elf_getshdrstrndx(Elf*, size_t*); -c_ulong elf_hash(in char*); +c_ulong elf_hash(const scope char*); uint elf_sys_encoding(); long elf32_checksum(Elf*); Elf_Kind elf_kind(Elf*); @@ -149,8 +149,8 @@ char* elf_rawfile(Elf*, size_t*); char* elf_strptr(Elf*, size_t, size_t); off_t elf_update(Elf*, Elf_Cmd); uint elf_version(uint); -Elf_Data* elf32_xlatetof(Elf_Data*, in Elf_Data*, uint); -Elf_Data* elf32_xlatetom(Elf_Data*, in Elf_Data*, uint); +Elf_Data* elf32_xlatetof(Elf_Data*, const scope Elf_Data*, uint); +Elf_Data* elf32_xlatetom(Elf_Data*, const scope Elf_Data*, uint); version (D_LP64) { @@ -161,6 +161,6 @@ Elf64_Shdr* elf64_getshdr(Elf_Scn*); long elf64_checksum(Elf*); Elf64_Ehdr* elf64_newehdr(Elf*); Elf64_Phdr* elf64_newphdr(Elf*, size_t); -Elf_Data* elf64_xlatetof(Elf_Data*, in Elf_Data*, uint); -Elf_Data* elf64_xlatetom(Elf_Data*, in Elf_Data*, uint); -} \ No newline at end of file +Elf_Data* elf64_xlatetof(Elf_Data*, const scope Elf_Data*, uint); +Elf_Data* elf64_xlatetom(Elf_Data*, const scope Elf_Data*, uint); +} diff --git a/libphobos/libdruntime/core/sys/solaris/link.d b/libphobos/libdruntime/core/sys/solaris/link.d index 2d908b12184..1459783b4a8 100644 --- a/libphobos/libdruntime/core/sys/solaris/link.d +++ b/libphobos/libdruntime/core/sys/solaris/link.d @@ -18,21 +18,21 @@ import core.sys.solaris.sys.link; uint ld_version(uint); void ld_input_done(uint*); -void ld_start(in char*, in Elf32_Half, in char*); +void ld_start(const scope char*, const Elf32_Half, const scope char*); void ld_atexit(int); -void ld_open(in char**, in char**, int*, int, Elf**, Elf*, size_t, in Elf_Kind); -void ld_file(in char*, in Elf_Kind, int, Elf*); -void ld_input_section(in char*, Elf32_Shdr**, Elf32_Word, Elf_Data*, Elf*, uint*); -void ld_section(in char*, Elf32_Shdr*, Elf32_Word, Elf_Data*, Elf*); +void ld_open(const scope char**, const scope char**, int*, int, Elf**, Elf*, size_t, const Elf_Kind); +void ld_file(const scope char*, const Elf_Kind, int, Elf*); +void ld_input_section(const scope char*, Elf32_Shdr**, Elf32_Word, Elf_Data*, Elf*, uint*); +void ld_section(const scope char*, Elf32_Shdr*, Elf32_Word, Elf_Data*, Elf*); version (D_LP64) { - void ld_start64(in char*, in Elf64_Half, in char*); + void ld_start64(const scope char*, const Elf64_Half, const scope char*); void ld_atexit64(int); - void ld_open64(in char**, in char**, int*, int, Elf**, Elf*, size_t, in Elf_Kind); - void ld_file64(in char*, in Elf_Kind, int, Elf*); - void ld_input_section64(in char*, Elf64_Shdr**, Elf64_Word, Elf_Data*, Elf*, uint*); - void ld_section64(in char*, Elf64_Shdr*, Elf64_Word, Elf_Data*, Elf*); + void ld_open64(const scope char**, const scope char**, int*, int, Elf**, Elf*, size_t, const Elf_Kind); + void ld_file64(const scope char*, const Elf_Kind, int, Elf*); + void ld_input_section64(const scope char*, Elf64_Shdr**, Elf64_Word, Elf_Data*, Elf*, uint*); + void ld_section64(const scope char*, Elf64_Shdr*, Elf64_Word, Elf_Data*, Elf*); } enum LD_SUP_VNONE = 0; @@ -130,19 +130,19 @@ else uint la_version(uint); void la_activity(uintptr_t*, uint); void la_preinit(uintptr_t*); -char* la_objsearch(in char*, uintptr_t*, uint); +char* la_objsearch(const scope char*, uintptr_t*, uint); uint la_objopen(Link_map*, Lmid_t, uintptr_t*); uint la_objclose(uintptr_t*); -int la_objfilter(uintptr_t*, in char*, uintptr_t*, uint); +int la_objfilter(uintptr_t*, const scope char*, uintptr_t*, uint); version (D_LP64) { uintptr_t la_amd64_pltenter(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, - La_amd64_regs*, uint*, in char*); - uintptr_t la_symbind64(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, uint*, in char*); + La_amd64_regs*, uint*, const scope char*); + uintptr_t la_symbind64(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, uint*, const scope char*); uintptr_t la_sparcv9_pltenter(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, - La_sparcv9_regs*, uint*, in char*); - uintptr_t la_pltexit64(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, uintptr_t, in char*); + La_sparcv9_regs*, uint*, const scope char*); + uintptr_t la_pltexit64(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, uintptr_t, const scope char*); } else { @@ -172,7 +172,7 @@ struct dl_phdr_info uint64_t dlpi_subs; size_t dlpi_tls_modid; // since Solaris 11.5 void* dlpi_tls_data; // since Solaris 11.5 -}; +} private alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb; private alias extern(C) int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_cb_ngc; diff --git a/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d b/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d index 2d6fda0dcf0..81d02347598 100644 --- a/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d +++ b/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d @@ -178,4 +178,4 @@ else enum M_PLT_RESERVSZ = M32_PLT_RESERVSZ; enum M_GOT_ENTSIZE = M32_GOT_ENTSIZE; enum M_GOT_MAXSMALL = M32_GOT_MAXSMALL; -} \ No newline at end of file +} diff --git a/libphobos/libdruntime/core/sys/windows/accctrl.d b/libphobos/libdruntime/core/sys/windows/accctrl.d index e28f5df73aa..77bc184710f 100644 --- a/libphobos/libdruntime/core/sys/windows/accctrl.d +++ b/libphobos/libdruntime/core/sys/windows/accctrl.d @@ -12,7 +12,7 @@ version (Windows): version (ANSI) {} else version = Unicode; -private import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef; +import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef; // FIXME: check types and grouping of constants // FIXME: check Windows version support diff --git a/libphobos/libdruntime/core/sys/windows/aclapi.d b/libphobos/libdruntime/core/sys/windows/aclapi.d index 762a4dbed0c..1e75d3f52ee 100644 --- a/libphobos/libdruntime/core/sys/windows/aclapi.d +++ b/libphobos/libdruntime/core/sys/windows/aclapi.d @@ -9,6 +9,7 @@ */ module core.sys.windows.aclapi; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "advapi32"); diff --git a/libphobos/libdruntime/core/sys/windows/aclui.d b/libphobos/libdruntime/core/sys/windows/aclui.d index 6000375454c..6ae37c6a686 100644 --- a/libphobos/libdruntime/core/sys/windows/aclui.d +++ b/libphobos/libdruntime/core/sys/windows/aclui.d @@ -9,16 +9,17 @@ */ module core.sys.windows.aclui; version (Windows): +@system: pragma(lib, "aclui"); -private import core.sys.windows.w32api; +import core.sys.windows.w32api; /* static assert (_WIN32_WINNT >= 0x500, "core.sys.windows.aclui is available only if version Windows2000, WindowsXP, Windows2003 " "or WindowsVista is set"); */ import core.sys.windows.accctrl, core.sys.windows.commctrl, core.sys.windows.objbase; -private import core.sys.windows.basetyps, core.sys.windows.prsht, core.sys.windows.unknwn, core.sys.windows.windef, +import core.sys.windows.basetyps, core.sys.windows.prsht, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.winuser; diff --git a/libphobos/libdruntime/core/sys/windows/basetsd.d b/libphobos/libdruntime/core/sys/windows/basetsd.d index 8efacd0da76..97983c6d74a 100644 --- a/libphobos/libdruntime/core/sys/windows/basetsd.d +++ b/libphobos/libdruntime/core/sys/windows/basetsd.d @@ -9,6 +9,7 @@ */ module core.sys.windows.basetsd; version (Windows): +@system: /* This template is used in these modules to declare constant pointer types, * in order to support both D 1.x and 2.x. diff --git a/libphobos/libdruntime/core/sys/windows/basetyps.d b/libphobos/libdruntime/core/sys/windows/basetyps.d index bef43075e20..abe312e4ddc 100644 --- a/libphobos/libdruntime/core/sys/windows/basetyps.d +++ b/libphobos/libdruntime/core/sys/windows/basetyps.d @@ -8,8 +8,9 @@ */ module core.sys.windows.basetyps; version (Windows): +@system: -private import core.sys.windows.windef, core.sys.windows.basetsd; +import core.sys.windows.windef, core.sys.windows.basetsd; align(1) struct GUID { // size is 16 align(1): diff --git a/libphobos/libdruntime/core/sys/windows/cguid.d b/libphobos/libdruntime/core/sys/windows/cguid.d index b6db658be9e..8d67b881ee1 100644 --- a/libphobos/libdruntime/core/sys/windows/cguid.d +++ b/libphobos/libdruntime/core/sys/windows/cguid.d @@ -9,5 +9,5 @@ module core.sys.windows.cguid; version (Windows): -private import core.sys.windows.basetyps; +import core.sys.windows.basetyps; diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d index 34aeccc946b..90a294343fc 100644 --- a/libphobos/libdruntime/core/sys/windows/com.d +++ b/libphobos/libdruntime/core/sys/windows/com.d @@ -1,5 +1,6 @@ module core.sys.windows.com; version (Windows): +@system: pragma(lib,"uuid"); diff --git a/libphobos/libdruntime/core/sys/windows/comcat.d b/libphobos/libdruntime/core/sys/windows/comcat.d index e6ef421a548..cb45ff5762c 100644 --- a/libphobos/libdruntime/core/sys/windows/comcat.d +++ b/libphobos/libdruntime/core/sys/windows/comcat.d @@ -9,9 +9,10 @@ */ module core.sys.windows.comcat; version (Windows): +@system: import core.sys.windows.ole2; -private import core.sys.windows.basetyps, core.sys.windows.cguid, core.sys.windows.objbase, core.sys.windows.unknwn, +import core.sys.windows.basetyps, core.sys.windows.cguid, core.sys.windows.objbase, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; alias IEnumGUID LPENUMGUID; diff --git a/libphobos/libdruntime/core/sys/windows/commctrl.d b/libphobos/libdruntime/core/sys/windows/commctrl.d index bedf36567e1..f008e75ddee 100644 --- a/libphobos/libdruntime/core/sys/windows/commctrl.d +++ b/libphobos/libdruntime/core/sys/windows/commctrl.d @@ -8,13 +8,14 @@ */ module core.sys.windows.commctrl; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "comctl32"); -private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winuser; -private import core.sys.windows.winbase; // for SYSTEMTIME -private import core.sys.windows.objfwd; // for LPSTREAM +import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winuser; +import core.sys.windows.winbase; // for SYSTEMTIME +import core.sys.windows.objfwd; // for LPSTREAM import core.sys.windows.prsht; @@ -3898,7 +3899,7 @@ static if (_WIN32_WINNT >= 0x600) { { int iItem; int iGroup; - }; + } alias LVITEMINDEX* PLVITEMINDEX; struct LVFOOTERINFO diff --git a/libphobos/libdruntime/core/sys/windows/commdlg.d b/libphobos/libdruntime/core/sys/windows/commdlg.d index c113f9efd52..1e8057c5f06 100644 --- a/libphobos/libdruntime/core/sys/windows/commdlg.d +++ b/libphobos/libdruntime/core/sys/windows/commdlg.d @@ -8,11 +8,12 @@ */ module core.sys.windows.commdlg; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "comdlg32"); -private import core.sys.windows.w32api; +import core.sys.windows.w32api; import core.sys.windows.windef, core.sys.windows.winuser; import core.sys.windows.wingdi; // for LPLOGFONTA diff --git a/libphobos/libdruntime/core/sys/windows/cpl.d b/libphobos/libdruntime/core/sys/windows/cpl.d index 823a76bd386..b040aad3eb5 100644 --- a/libphobos/libdruntime/core/sys/windows/cpl.d +++ b/libphobos/libdruntime/core/sys/windows/cpl.d @@ -9,10 +9,11 @@ */ module core.sys.windows.cpl; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.windef, core.sys.windows.winuser; +import core.sys.windows.windef, core.sys.windows.winuser; enum : uint { WM_CPL_LAUNCH = WM_USER + 1000, diff --git a/libphobos/libdruntime/core/sys/windows/cplext.d b/libphobos/libdruntime/core/sys/windows/cplext.d index 89d892e2956..c9452fad77c 100644 --- a/libphobos/libdruntime/core/sys/windows/cplext.d +++ b/libphobos/libdruntime/core/sys/windows/cplext.d @@ -9,6 +9,7 @@ */ module core.sys.windows.cplext; version (Windows): +@system: enum : uint { CPLPAGE_MOUSE_BUTTONS = 1, diff --git a/libphobos/libdruntime/core/sys/windows/custcntl.d b/libphobos/libdruntime/core/sys/windows/custcntl.d index 3f5284f8854..ccfc7ca4ffc 100644 --- a/libphobos/libdruntime/core/sys/windows/custcntl.d +++ b/libphobos/libdruntime/core/sys/windows/custcntl.d @@ -9,10 +9,11 @@ */ module core.sys.windows.custcntl; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.windef; +import core.sys.windows.windef; // FIXME: check type enum CCF_NOTEXT = 1; diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d index 44c19571437..8c9827034e9 100644 --- a/libphobos/libdruntime/core/sys/windows/dbghelp.d +++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d @@ -11,6 +11,7 @@ module core.sys.windows.dbghelp; version (Windows): +@system: import core.sys.windows.winbase /+: FreeLibrary, GetProcAddress, LoadLibraryA+/; import core.sys.windows.windef; @@ -36,7 +37,7 @@ extern(System) alias DWORD64 function(HANDLE hProcess, DWORD64 dwAddr) SymGetModuleBase64Func; alias BOOL function(HANDLE hProcess, DWORD64 dwAddr, IMAGEHLP_MODULEA64 *ModuleInfo) SymGetModuleInfo64Func; alias BOOL function(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, IMAGEHLP_SYMBOLA64 *Symbol) SymGetSymFromAddr64Func; - alias DWORD function(PCTSTR DecoratedName, PTSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc; + alias DWORD function(PCSTR DecoratedName, PSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc; alias DWORD64 function(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) SymLoadModule64Func; alias BOOL function(HANDLE HProcess, PTSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc; alias BOOL function(HANDLE hProcess, DWORD64 Address) SymUnloadModule64Func; @@ -80,6 +81,7 @@ struct DbgHelp sm_inst.SymGetModuleBase64 = cast(SymGetModuleBase64Func) GetProcAddress(sm_hndl,"SymGetModuleBase64"); sm_inst.SymGetModuleInfo64 = cast(SymGetModuleInfo64Func) GetProcAddress(sm_hndl,"SymGetModuleInfo64"); sm_inst.SymGetSymFromAddr64 = cast(SymGetSymFromAddr64Func) GetProcAddress(sm_hndl,"SymGetSymFromAddr64"); + sm_inst.UnDecorateSymbolName = cast(UnDecorateSymbolNameFunc) GetProcAddress(sm_hndl,"UnDecorateSymbolName"); sm_inst.SymLoadModule64 = cast(SymLoadModule64Func) GetProcAddress(sm_hndl,"SymLoadModule64"); sm_inst.SymGetSearchPath = cast(SymGetSearchPathFunc) GetProcAddress(sm_hndl,"SymGetSearchPath"); sm_inst.SymUnloadModule64 = cast(SymUnloadModule64Func) GetProcAddress(sm_hndl,"SymUnloadModule64"); @@ -88,8 +90,8 @@ struct DbgHelp assert( sm_inst.SymInitialize && sm_inst.SymCleanup && sm_inst.StackWalk64 && sm_inst.SymGetOptions && sm_inst.SymSetOptions && sm_inst.SymFunctionTableAccess64 && sm_inst.SymGetLineFromAddr64 && sm_inst.SymGetModuleBase64 && sm_inst.SymGetModuleInfo64 && sm_inst.SymGetSymFromAddr64 && - sm_inst.SymLoadModule64 && sm_inst.SymGetSearchPath && sm_inst.SymUnloadModule64 && - sm_inst.SymRegisterCallback64 && sm_inst.ImagehlpApiVersion); + sm_inst.UnDecorateSymbolName && sm_inst.SymLoadModule64 && sm_inst.SymGetSearchPath && + sm_inst.SymUnloadModule64 && sm_inst.SymRegisterCallback64 && sm_inst.ImagehlpApiVersion); return &sm_inst; } diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp_types.d b/libphobos/libdruntime/core/sys/windows/dbghelp_types.d index f75f98bc882..64477df96ff 100644 --- a/libphobos/libdruntime/core/sys/windows/dbghelp_types.d +++ b/libphobos/libdruntime/core/sys/windows/dbghelp_types.d @@ -11,6 +11,7 @@ module core.sys.windows.dbghelp_types; version (Windows): +@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/dbt.d b/libphobos/libdruntime/core/sys/windows/dbt.d index c43f789a333..a591152cf88 100644 --- a/libphobos/libdruntime/core/sys/windows/dbt.d +++ b/libphobos/libdruntime/core/sys/windows/dbt.d @@ -9,6 +9,7 @@ */ module core.sys.windows.dbt; version (Windows): +@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/dde.d b/libphobos/libdruntime/core/sys/windows/dde.d index 168cbd185a1..0e062274ccf 100644 --- a/libphobos/libdruntime/core/sys/windows/dde.d +++ b/libphobos/libdruntime/core/sys/windows/dde.d @@ -9,9 +9,10 @@ */ module core.sys.windows.dde; version (Windows): +@system: pragma(lib, "user32"); -private import core.sys.windows.windef; +import core.sys.windows.windef; enum : uint { WM_DDE_FIRST = 0x03E0, diff --git a/libphobos/libdruntime/core/sys/windows/ddeml.d b/libphobos/libdruntime/core/sys/windows/ddeml.d index a0cce304d95..209772f6af9 100644 --- a/libphobos/libdruntime/core/sys/windows/ddeml.d +++ b/libphobos/libdruntime/core/sys/windows/ddeml.d @@ -9,11 +9,12 @@ */ module core.sys.windows.ddeml; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "user32"); -private import core.sys.windows.basetsd, core.sys.windows.windef, core.sys.windows.winnt; +import core.sys.windows.basetsd, core.sys.windows.windef, core.sys.windows.winnt; enum : int { CP_WINANSI = 1004, diff --git a/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d b/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d index 4c0db442d6f..7b412c1e761 100644 --- a/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d +++ b/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d @@ -9,8 +9,9 @@ */ module core.sys.windows.dhcpcsdk; version (Windows): +@system: -private import core.sys.windows.w32api, core.sys.windows.windef; +import core.sys.windows.w32api, core.sys.windows.windef; /*static assert (_WIN32_WINNT >= 0x500, "core.sys.windows.dhcpcsdk is available only if version Windows2000, WindowsXP, Windows2003 diff --git a/libphobos/libdruntime/core/sys/windows/dlgs.d b/libphobos/libdruntime/core/sys/windows/dlgs.d index f9306d6e620..796f02720ca 100644 --- a/libphobos/libdruntime/core/sys/windows/dlgs.d +++ b/libphobos/libdruntime/core/sys/windows/dlgs.d @@ -9,8 +9,9 @@ */ module core.sys.windows.dlgs; version (Windows): +@system: -private import core.sys.windows.windef; +import core.sys.windows.windef; enum : ushort { FILEOPENORD = 1536, diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d index c3c4db37c42..9f36ac389a6 100644 --- a/libphobos/libdruntime/core/sys/windows/dll.d +++ b/libphobos/libdruntime/core/sys/windows/dll.d @@ -14,6 +14,7 @@ */ module core.sys.windows.dll; version (Windows): +@system: import core.sys.windows.winbase; import core.sys.windows.winnt; @@ -68,11 +69,11 @@ extern (C) // rt.minfo } private: -version (Win32) -{ struct dll_aux { // don't let symbols leak into other modules +version (Win32) +{ struct LdrpTlsListEntry { LdrpTlsListEntry* next; @@ -238,6 +239,7 @@ struct dll_aux // let the old array leak, in case a oncurrent thread is still relying on it return true; } +} // Win32 alias bool BOOLEAN; @@ -254,7 +256,8 @@ struct dll_aux LIST_ENTRY* prev; } - // the following structures can be found here: http://undocumented.ntinternals.net/ + // the following structures can be found here: + // https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/ldr_data_table_entry.htm // perhaps this should be same as LDR_DATA_TABLE_ENTRY, which is introduced with PEB_LDR_DATA struct LDR_MODULE { @@ -267,10 +270,22 @@ struct dll_aux UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; - SHORT LoadCount; + SHORT LoadCount; // obsolete after Version 6.1 SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp; + PVOID EntryPointActivationContext; + PVOID PatchInformation; + LDR_DDAG_NODE *DdagNode; // starting with Version 6.2 + } + + struct LDR_DDAG_NODE + { + LIST_ENTRY Modules; + void* ServiceTagList; // LDR_SERVICE_TAG_RECORD + ULONG LoadCount; + ULONG ReferenceCount; // Version 10: ULONG LoadWhileUnloadingCount; + ULONG DependencyCount; // Version 10: ULONG LowestLink; } struct PEB_LDR_DATA @@ -283,7 +298,7 @@ struct dll_aux LIST_ENTRY InInitializationOrderModuleList; } - static LDR_MODULE* findLdrModule( HINSTANCE hInstance, void** peb ) nothrow + static LDR_MODULE* findLdrModule( HINSTANCE hInstance, void** peb ) nothrow @nogc { PEB_LDR_DATA* ldrData = cast(PEB_LDR_DATA*) peb[3]; LIST_ENTRY* root = &ldrData.InLoadOrderModuleList; @@ -307,7 +322,6 @@ struct dll_aux return true; } } -} public: /* ***************************************************** @@ -374,6 +388,78 @@ bool dll_fixTLS( HINSTANCE hInstance, void* tlsstart, void* tlsend, void* tls_ca } } +private extern (Windows) ULONGLONG VerSetConditionMask(ULONGLONG, DWORD, BYTE) nothrow @nogc; + +private bool isWindows8OrLater() nothrow @nogc +{ + OSVERSIONINFOEXW osvi; + osvi.dwOSVersionInfoSize = osvi.sizeof; + DWORDLONG dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + + osvi.dwMajorVersion = 6; + osvi.dwMinorVersion = 2; + osvi.wServicePackMajor = 0; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} + +/* ***************************************************** + * Get the process reference count for the given DLL handle + * Params: + * hInstance = DLL instance handle + * Returns: + * the reference count for the DLL in the current process, + * -1 if the DLL is implicitely loaded with the process + * or -2 if the DLL handle is invalid + */ +int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc +{ + void** peb; + version (Win64) + { + version (GNU_InlineAsm) + { + asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" peb; } + } + else + { + asm pure nothrow @nogc + { + mov RAX, 0x60; + mov RAX,GS:[RAX]; + mov peb, RAX; + } + } + + } + else version (Win32) + { + version (GNU_InlineAsm) + { + asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" peb; } + } + else + { + asm pure nothrow @nogc + { + mov EAX,FS:[0x30]; + mov peb, EAX; + } + } + } + dll_aux.LDR_MODULE *ldrMod = dll_aux.findLdrModule( hInstance, peb ); + if ( !ldrMod ) + return -2; // not in module list, bail out + if (isWindows8OrLater()) + return ldrMod.DdagNode.LoadCount; + return ldrMod.LoadCount; +} + // fixup TLS storage, initialize runtime and attach to threads // to be called from DllMain with reason DLL_PROCESS_ATTACH bool dll_process_attach( HINSTANCE hInstance, bool attach_threads, @@ -393,7 +479,7 @@ bool dll_process_attach( HINSTANCE hInstance, bool attach_threads, // attach to all other threads return enumProcessThreads( function (uint id, void* context) { - if ( !thread_findByAddr( id ) ) + if ( !thread_findByAddr( id ) && !findLowLevelThread( id ) ) { // if the OS has not prepared TLS for us, don't attach to the thread if ( GetTlsDataAddress( id ) ) @@ -424,14 +510,22 @@ bool dll_process_attach( HINSTANCE hInstance, bool attach_threads = true ) // to be called from DllMain with reason DLL_PROCESS_DETACH void dll_process_detach( HINSTANCE hInstance, bool detach_threads = true ) { + // notify core.thread.joinLowLevelThread that the DLL is about to be unloaded + thread_DLLProcessDetaching = true; + // detach from all other threads if ( detach_threads ) enumProcessThreads( - function (uint id, void* context) { - if ( id != GetCurrentThreadId() && thread_findByAddr( id ) ) + function (uint id, void* context) + { + if ( id != GetCurrentThreadId() ) { - thread_moduleTlsDtor( id ); - thread_detachByAddr( id ); + if ( auto t = thread_findByAddr( id ) ) + { + thread_moduleTlsDtor( id ); + if ( !t.isMainThread() ) + thread_detachByAddr( id ); + } } return true; }, null ); @@ -450,9 +544,10 @@ bool dll_thread_attach( bool attach_thread = true, bool initTls = true ) { // if the OS has not prepared TLS for us, don't attach to the thread // (happened when running under x64 OS) - if ( !GetTlsDataAddress( GetCurrentThreadId() ) ) + auto tid = GetCurrentThreadId(); + if ( !GetTlsDataAddress( tid ) ) return false; - if ( !thread_findByAddr( GetCurrentThreadId() ) ) + if ( !thread_findByAddr( tid ) && !findLowLevelThread( tid ) ) { // only attach to thread and initalize it if it is not in the thread list (so it's not created by "new Thread") if ( attach_thread ) diff --git a/libphobos/libdruntime/core/sys/windows/docobj.d b/libphobos/libdruntime/core/sys/windows/docobj.d index 0be79d75558..89d5936f581 100644 --- a/libphobos/libdruntime/core/sys/windows/docobj.d +++ b/libphobos/libdruntime/core/sys/windows/docobj.d @@ -8,8 +8,9 @@ */ module core.sys.windows.docobj; version (Windows): +@system: -private import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.objidl, core.sys.windows.oleidl, +import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.objidl, core.sys.windows.oleidl, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; // FIXME: remove inherited methods from interface definitions diff --git a/libphobos/libdruntime/core/sys/windows/errorrep.d b/libphobos/libdruntime/core/sys/windows/errorrep.d index b44d7034b3b..2b22e370ce5 100644 --- a/libphobos/libdruntime/core/sys/windows/errorrep.d +++ b/libphobos/libdruntime/core/sys/windows/errorrep.d @@ -9,10 +9,11 @@ */ module core.sys.windows.errorrep; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.w32api, core.sys.windows.windef; +import core.sys.windows.w32api, core.sys.windows.windef; static assert (_WIN32_WINNT >= 0x501, "core.sys.windows.errorrep is available only if version WindowsXP, Windows2003 " diff --git a/libphobos/libdruntime/core/sys/windows/exdisp.d b/libphobos/libdruntime/core/sys/windows/exdisp.d index 6b953bf2d69..1153112b5d0 100644 --- a/libphobos/libdruntime/core/sys/windows/exdisp.d +++ b/libphobos/libdruntime/core/sys/windows/exdisp.d @@ -8,9 +8,10 @@ */ module core.sys.windows.exdisp; version (Windows): +@system: import core.sys.windows.docobj, core.sys.windows.oaidl, core.sys.windows.ocidl; -private import core.sys.windows.basetyps, core.sys.windows.windef, core.sys.windows.wtypes; +import core.sys.windows.basetyps, core.sys.windows.windef, core.sys.windows.wtypes; enum BrowserNavConstants { diff --git a/libphobos/libdruntime/core/sys/windows/httpext.d b/libphobos/libdruntime/core/sys/windows/httpext.d index 546523407f2..781d7cea74c 100644 --- a/libphobos/libdruntime/core/sys/windows/httpext.d +++ b/libphobos/libdruntime/core/sys/windows/httpext.d @@ -8,6 +8,7 @@ */ module core.sys.windows.httpext; version (Windows): +@system: /* Comment from MinGW httpext.h - Header for ISAPI extensions. @@ -19,9 +20,9 @@ version (Windows): MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ -private import core.sys.windows.basetsd /+: DECLARE_HANDLE, HANDLE+/; -private import core.sys.windows.windef /+: BOOL, CHAR, DWORD, LPBYTE, LPDWORD+/; -private import core.sys.windows.winnt /+: LPCSTR, LPSTR, LPVOID, PVOID, VOID+/; +import core.sys.windows.basetsd /+: DECLARE_HANDLE, HANDLE+/; +import core.sys.windows.windef /+: BOOL, CHAR, DWORD, LPBYTE, LPDWORD+/; +import core.sys.windows.winnt /+: LPCSTR, LPSTR, LPVOID, PVOID, VOID+/; enum { HSE_VERSION_MAJOR = 2, diff --git a/libphobos/libdruntime/core/sys/windows/imagehlp.d b/libphobos/libdruntime/core/sys/windows/imagehlp.d index b77ef761047..f9edba1425f 100644 --- a/libphobos/libdruntime/core/sys/windows/imagehlp.d +++ b/libphobos/libdruntime/core/sys/windows/imagehlp.d @@ -9,6 +9,7 @@ */ module core.sys.windows.imagehlp; version (Windows): +@system: version (ANSI) {} else version = Unicode; @@ -18,7 +19,7 @@ version (ANSI) {} else version = Unicode; as well provide it here. */ -private import core.sys.windows.winbase, core.sys.windows.windef; +import core.sys.windows.winbase, core.sys.windows.windef; // FIXME: check types of constants diff --git a/libphobos/libdruntime/core/sys/windows/imm.d b/libphobos/libdruntime/core/sys/windows/imm.d index 5a55d04b38a..3ebab30037f 100644 --- a/libphobos/libdruntime/core/sys/windows/imm.d +++ b/libphobos/libdruntime/core/sys/windows/imm.d @@ -8,13 +8,14 @@ */ module core.sys.windows.imm; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "imm32"); import core.sys.windows.windef, core.sys.windows.wingdi; import core.sys.windows.winuser; // for the MFS_xxx enums. -private import core.sys.windows.w32api; +import core.sys.windows.w32api; enum WM_CONVERTREQUESTEX = 0x108; enum WM_IME_STARTCOMPOSITION = 0x10D; diff --git a/libphobos/libdruntime/core/sys/windows/intshcut.d b/libphobos/libdruntime/core/sys/windows/intshcut.d index 4070577514f..f2f44e1497d 100644 --- a/libphobos/libdruntime/core/sys/windows/intshcut.d +++ b/libphobos/libdruntime/core/sys/windows/intshcut.d @@ -9,10 +9,11 @@ */ module core.sys.windows.intshcut; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.unknwn, core.sys.windows.windef; +import core.sys.windows.unknwn, core.sys.windows.windef; enum : SCODE { E_FLAGS = 0x80041000, diff --git a/libphobos/libdruntime/core/sys/windows/ipexport.d b/libphobos/libdruntime/core/sys/windows/ipexport.d index c9fcbd33a9c..b66aa26e091 100644 --- a/libphobos/libdruntime/core/sys/windows/ipexport.d +++ b/libphobos/libdruntime/core/sys/windows/ipexport.d @@ -9,8 +9,9 @@ */ module core.sys.windows.ipexport; version (Windows): +@system: -private import core.sys.windows.windef; +import core.sys.windows.windef; enum size_t MAX_ADAPTER_NAME = 128; diff --git a/libphobos/libdruntime/core/sys/windows/iphlpapi.d b/libphobos/libdruntime/core/sys/windows/iphlpapi.d index 6dabd0bc7d2..313e40b92c7 100644 --- a/libphobos/libdruntime/core/sys/windows/iphlpapi.d +++ b/libphobos/libdruntime/core/sys/windows/iphlpapi.d @@ -9,9 +9,10 @@ */ module core.sys.windows.iphlpapi; version (Windows): +@system: import core.sys.windows.ipexport, core.sys.windows.iprtrmib, core.sys.windows.iptypes; -private import core.sys.windows.winbase, core.sys.windows.windef; +import core.sys.windows.winbase, core.sys.windows.windef; extern (Windows) { DWORD AddIPAddress(IPAddr, IPMask, DWORD, PULONG, PULONG); diff --git a/libphobos/libdruntime/core/sys/windows/iprtrmib.d b/libphobos/libdruntime/core/sys/windows/iprtrmib.d index 4365723a50e..1d23bc12cd9 100644 --- a/libphobos/libdruntime/core/sys/windows/iprtrmib.d +++ b/libphobos/libdruntime/core/sys/windows/iprtrmib.d @@ -9,9 +9,10 @@ */ module core.sys.windows.iprtrmib; version (Windows): +@system: import core.sys.windows.ipifcons; -private import core.sys.windows.windef; +import core.sys.windows.windef; // FIXME: check types of constants diff --git a/libphobos/libdruntime/core/sys/windows/iptypes.d b/libphobos/libdruntime/core/sys/windows/iptypes.d index ada3e9cca58..f4f9fe80ad1 100644 --- a/libphobos/libdruntime/core/sys/windows/iptypes.d +++ b/libphobos/libdruntime/core/sys/windows/iptypes.d @@ -9,6 +9,7 @@ */ module core.sys.windows.iptypes; version (Windows): +@system: import core.sys.windows.windef; import core.stdc.time; diff --git a/libphobos/libdruntime/core/sys/windows/isguids.d b/libphobos/libdruntime/core/sys/windows/isguids.d index b78d3521290..61e1d1ea143 100644 --- a/libphobos/libdruntime/core/sys/windows/isguids.d +++ b/libphobos/libdruntime/core/sys/windows/isguids.d @@ -10,7 +10,7 @@ module core.sys.windows.isguids; version (Windows): -private import core.sys.windows.basetyps; +import core.sys.windows.basetyps; extern (C) extern const GUID CLSID_InternetShortcut, diff --git a/libphobos/libdruntime/core/sys/windows/lm.d b/libphobos/libdruntime/core/sys/windows/lm.d index 48a6f55c850..e12f629dcee 100644 --- a/libphobos/libdruntime/core/sys/windows/lm.d +++ b/libphobos/libdruntime/core/sys/windows/lm.d @@ -8,6 +8,8 @@ */ module core.sys.windows.lm; version (Windows): +@system: + /* removed - now supporting only Win2k up version (WindowsVista) { version = WIN32_WINNT_ONLY; diff --git a/libphobos/libdruntime/core/sys/windows/lmaccess.d b/libphobos/libdruntime/core/sys/windows/lmaccess.d index 5846fa193ba..3e1370d596b 100644 --- a/libphobos/libdruntime/core/sys/windows/lmaccess.d +++ b/libphobos/libdruntime/core/sys/windows/lmaccess.d @@ -8,6 +8,7 @@ */ module core.sys.windows.lmaccess; version (Windows): +@system: pragma(lib, "netapi32"); /** @@ -16,7 +17,7 @@ pragma(lib, "netapi32"); the Platform SDK docs, so they have been dropped from this file. */ -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; const wchar[] GROUP_SPECIALGRP_USERS = "USERS", diff --git a/libphobos/libdruntime/core/sys/windows/lmalert.d b/libphobos/libdruntime/core/sys/windows/lmalert.d index 53acff035b5..675dc896a4a 100644 --- a/libphobos/libdruntime/core/sys/windows/lmalert.d +++ b/libphobos/libdruntime/core/sys/windows/lmalert.d @@ -8,9 +8,10 @@ */ module core.sys.windows.lmalert; version (Windows): +@system: pragma(lib, "netapi32"); -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; const TCHAR[] ALERTER_MAILSLOT = `\\.\MAILSLOT\Alerter`, diff --git a/libphobos/libdruntime/core/sys/windows/lmapibuf.d b/libphobos/libdruntime/core/sys/windows/lmapibuf.d index 6c2df771055..f78271a2062 100644 --- a/libphobos/libdruntime/core/sys/windows/lmapibuf.d +++ b/libphobos/libdruntime/core/sys/windows/lmapibuf.d @@ -10,7 +10,7 @@ module core.sys.windows.lmapibuf; version (Windows): pragma(lib, "netapi32"); -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; extern (Windows) { NET_API_STATUS NetApiBufferAllocate(DWORD, PVOID*); diff --git a/libphobos/libdruntime/core/sys/windows/lmat.d b/libphobos/libdruntime/core/sys/windows/lmat.d index 64272af8572..1862adf3642 100644 --- a/libphobos/libdruntime/core/sys/windows/lmat.d +++ b/libphobos/libdruntime/core/sys/windows/lmat.d @@ -8,9 +8,10 @@ */ module core.sys.windows.lmat; version (Windows): +@system: pragma(lib, "netapi32"); -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; enum JOB_RUN_PERIODICALLY = 1; enum JOB_EXEC_ERROR = 2; diff --git a/libphobos/libdruntime/core/sys/windows/lmaudit.d b/libphobos/libdruntime/core/sys/windows/lmaudit.d index 476ab5b709b..524332af5e0 100644 --- a/libphobos/libdruntime/core/sys/windows/lmaudit.d +++ b/libphobos/libdruntime/core/sys/windows/lmaudit.d @@ -9,8 +9,9 @@ // COMMENT: This file may be deprecated. module core.sys.windows.lmaudit; version (Windows): +@system: -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; enum LOGFLAGS_FORWARD = 0; enum LOGFLAGS_BACKWARD = 1; diff --git a/libphobos/libdruntime/core/sys/windows/lmbrowsr.d b/libphobos/libdruntime/core/sys/windows/lmbrowsr.d index 2bd303f91b0..971d8cdd416 100644 --- a/libphobos/libdruntime/core/sys/windows/lmbrowsr.d +++ b/libphobos/libdruntime/core/sys/windows/lmbrowsr.d @@ -8,8 +8,9 @@ */ module core.sys.windows.lmbrowsr; version (Windows): +@system: -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; enum BROWSER_ROLE_PDC = 1; enum BROWSER_ROLE_BDC = 2; diff --git a/libphobos/libdruntime/core/sys/windows/lmchdev.d b/libphobos/libdruntime/core/sys/windows/lmchdev.d index 2dcf9e314cc..39d9e788ef1 100644 --- a/libphobos/libdruntime/core/sys/windows/lmchdev.d +++ b/libphobos/libdruntime/core/sys/windows/lmchdev.d @@ -8,10 +8,11 @@ */ module core.sys.windows.lmchdev; version (Windows): +@system: // COMMENT: This file might be deprecated. -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; enum CHARDEVQ_NO_REQUESTS = -1; enum CHARDEV_CLOSE = 0; diff --git a/libphobos/libdruntime/core/sys/windows/lmconfig.d b/libphobos/libdruntime/core/sys/windows/lmconfig.d index 64e943ac04a..6bb2472cdde 100644 --- a/libphobos/libdruntime/core/sys/windows/lmconfig.d +++ b/libphobos/libdruntime/core/sys/windows/lmconfig.d @@ -8,10 +8,11 @@ */ module core.sys.windows.lmconfig; version (Windows): +@system: // All functions in this file are deprecated! -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; deprecated { struct CONFIG_INFO_0 { diff --git a/libphobos/libdruntime/core/sys/windows/lmcons.d b/libphobos/libdruntime/core/sys/windows/lmcons.d index c0fcb8f802e..b115cce4da3 100644 --- a/libphobos/libdruntime/core/sys/windows/lmcons.d +++ b/libphobos/libdruntime/core/sys/windows/lmcons.d @@ -8,11 +8,12 @@ */ module core.sys.windows.lmcons; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.windef; -private import core.sys.windows.lmerr; // for NERR_BASE +import core.sys.windows.windef; +import core.sys.windows.lmerr; // for NERR_BASE const TCHAR[] MESSAGE_FILENAME = "NETMSG", diff --git a/libphobos/libdruntime/core/sys/windows/lmerr.d b/libphobos/libdruntime/core/sys/windows/lmerr.d index 5af41325352..77e2378de7a 100644 --- a/libphobos/libdruntime/core/sys/windows/lmerr.d +++ b/libphobos/libdruntime/core/sys/windows/lmerr.d @@ -8,6 +8,7 @@ */ module core.sys.windows.lmerr; version (Windows): +@system: import core.sys.windows.winerror; diff --git a/libphobos/libdruntime/core/sys/windows/lmerrlog.d b/libphobos/libdruntime/core/sys/windows/lmerrlog.d index 8bc627e4b76..8e15b4df22c 100644 --- a/libphobos/libdruntime/core/sys/windows/lmerrlog.d +++ b/libphobos/libdruntime/core/sys/windows/lmerrlog.d @@ -8,11 +8,12 @@ */ module core.sys.windows.lmerrlog; version (Windows): +@system: // COMMENT: This appears to be only for Win16. All functions are deprecated. -private import core.sys.windows.lmcons, core.sys.windows.windef; -private import core.sys.windows.lmaudit; // for LPHLOG +import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmaudit; // for LPHLOG enum ERRLOG_BASE=3100; enum ERRLOG2_BASE=5700; diff --git a/libphobos/libdruntime/core/sys/windows/lmmsg.d b/libphobos/libdruntime/core/sys/windows/lmmsg.d index e636df7e855..2a2d60ade06 100644 --- a/libphobos/libdruntime/core/sys/windows/lmmsg.d +++ b/libphobos/libdruntime/core/sys/windows/lmmsg.d @@ -8,9 +8,10 @@ */ module core.sys.windows.lmmsg; version (Windows): +@system: pragma(lib, "netapi32"); -private import core.sys.windows.lmcons, core.sys.windows.windef, core.sys.windows.w32api; +import core.sys.windows.lmcons, core.sys.windows.windef, core.sys.windows.w32api; static assert (_WIN32_WINNT >= 0x501, "core.sys.windows.lmmsg is available only if version WindowsXP, Windows2003 " diff --git a/libphobos/libdruntime/core/sys/windows/lmremutl.d b/libphobos/libdruntime/core/sys/windows/lmremutl.d index 0d1229e44b7..ce7d45aa349 100644 --- a/libphobos/libdruntime/core/sys/windows/lmremutl.d +++ b/libphobos/libdruntime/core/sys/windows/lmremutl.d @@ -8,11 +8,12 @@ */ module core.sys.windows.lmremutl; version (Windows): +@system: pragma(lib, "netapi32"); // D Conversion Note: DESC_CHAR is defined as TCHAR. -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; enum SUPPORTS_REMOTE_ADMIN_PROTOCOL = 2; enum SUPPORTS_RPC = 4; diff --git a/libphobos/libdruntime/core/sys/windows/lmrepl.d b/libphobos/libdruntime/core/sys/windows/lmrepl.d index 7796728be08..02345f81105 100644 --- a/libphobos/libdruntime/core/sys/windows/lmrepl.d +++ b/libphobos/libdruntime/core/sys/windows/lmrepl.d @@ -8,9 +8,10 @@ */ module core.sys.windows.lmrepl; version (Windows): +@system: pragma(lib, "netapi32"); -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; enum REPL_ROLE_EXPORT=1; enum REPL_ROLE_IMPORT=2; diff --git a/libphobos/libdruntime/core/sys/windows/lmserver.d b/libphobos/libdruntime/core/sys/windows/lmserver.d index f27c7efdba9..83a9a84adda 100644 --- a/libphobos/libdruntime/core/sys/windows/lmserver.d +++ b/libphobos/libdruntime/core/sys/windows/lmserver.d @@ -8,9 +8,10 @@ */ module core.sys.windows.lmserver; version (Windows): +@system: import core.sys.windows.winsvc; -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; struct SERVER_INFO_100 { DWORD sv100_platform_id; diff --git a/libphobos/libdruntime/core/sys/windows/lmshare.d b/libphobos/libdruntime/core/sys/windows/lmshare.d index 2aacc7e126c..215fb781e66 100644 --- a/libphobos/libdruntime/core/sys/windows/lmshare.d +++ b/libphobos/libdruntime/core/sys/windows/lmshare.d @@ -8,10 +8,11 @@ */ module core.sys.windows.lmshare; version (Windows): +@system: pragma(lib, "netapi32"); import core.sys.windows.lmcons; -private import core.sys.windows.w32api, core.sys.windows.windef; +import core.sys.windows.w32api, core.sys.windows.windef; enum SHARE_NETNAME_PARMNUM = 1; diff --git a/libphobos/libdruntime/core/sys/windows/lmsname.d b/libphobos/libdruntime/core/sys/windows/lmsname.d index 01dfe030ddf..bdb1a6d3dcc 100644 --- a/libphobos/libdruntime/core/sys/windows/lmsname.d +++ b/libphobos/libdruntime/core/sys/windows/lmsname.d @@ -8,8 +8,9 @@ */ module core.sys.windows.lmsname; version (Windows): +@system: -private import core.sys.windows.windef; +import core.sys.windows.windef; const TCHAR[] SERVICE_WORKSTATION = "LanmanWorkstation", diff --git a/libphobos/libdruntime/core/sys/windows/lmstats.d b/libphobos/libdruntime/core/sys/windows/lmstats.d index 084c3307bbc..0c6e622aab4 100644 --- a/libphobos/libdruntime/core/sys/windows/lmstats.d +++ b/libphobos/libdruntime/core/sys/windows/lmstats.d @@ -8,9 +8,10 @@ */ module core.sys.windows.lmstats; version (Windows): +@system: pragma(lib, "netapi32"); -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; enum ULONG STATSOPT_CLR = 1, diff --git a/libphobos/libdruntime/core/sys/windows/lmsvc.d b/libphobos/libdruntime/core/sys/windows/lmsvc.d index 68a15920e22..1743458007d 100644 --- a/libphobos/libdruntime/core/sys/windows/lmsvc.d +++ b/libphobos/libdruntime/core/sys/windows/lmsvc.d @@ -8,6 +8,7 @@ */ module core.sys.windows.lmsvc; version (Windows): +@system: // FIXME: Is this file deprecated? All of the functions are only for Win16. /** @@ -16,7 +17,7 @@ version (Windows): */ // TODO: 5 macros -private import core.sys.windows.lmcons, core.sys.windows.lmsname, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.lmsname, core.sys.windows.windef; const TCHAR[] SERVICE_DOS_ENCRYPTION = "ENCRYPT"; diff --git a/libphobos/libdruntime/core/sys/windows/lmuse.d b/libphobos/libdruntime/core/sys/windows/lmuse.d index 8ceab4771ec..a9dbcd40b63 100644 --- a/libphobos/libdruntime/core/sys/windows/lmuse.d +++ b/libphobos/libdruntime/core/sys/windows/lmuse.d @@ -8,10 +8,11 @@ */ module core.sys.windows.lmuse; version (Windows): +@system: pragma(lib, "netapi32"); import core.sys.windows.lmuseflg; -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; enum { USE_LOCAL_PARMNUM = 1, diff --git a/libphobos/libdruntime/core/sys/windows/lmwksta.d b/libphobos/libdruntime/core/sys/windows/lmwksta.d index 33b57e50472..f4d85fef47b 100644 --- a/libphobos/libdruntime/core/sys/windows/lmwksta.d +++ b/libphobos/libdruntime/core/sys/windows/lmwksta.d @@ -8,10 +8,11 @@ */ module core.sys.windows.lmwksta; version (Windows): +@system: pragma(lib, "netapi32"); import core.sys.windows.lmuseflg; -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; pragma(lib, "Netapi32"); diff --git a/libphobos/libdruntime/core/sys/windows/lzexpand.d b/libphobos/libdruntime/core/sys/windows/lzexpand.d index 0ed0855c7d4..32ab1410b38 100644 --- a/libphobos/libdruntime/core/sys/windows/lzexpand.d +++ b/libphobos/libdruntime/core/sys/windows/lzexpand.d @@ -8,11 +8,12 @@ */ module core.sys.windows.lzexpand; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "lz32"); -private import core.sys.windows.winbase, core.sys.windows.windef; +import core.sys.windows.winbase, core.sys.windows.windef; enum : LONG { LZERROR_BADINHANDLE = -1, diff --git a/libphobos/libdruntime/core/sys/windows/mapi.d b/libphobos/libdruntime/core/sys/windows/mapi.d index 2f8f03b8ab0..194f63bcc74 100644 --- a/libphobos/libdruntime/core/sys/windows/mapi.d +++ b/libphobos/libdruntime/core/sys/windows/mapi.d @@ -9,8 +9,9 @@ */ module core.sys.windows.mapi; version (Windows): +@system: -private import core.sys.windows.windef; +import core.sys.windows.windef; // FIXME: check types and grouping of constants diff --git a/libphobos/libdruntime/core/sys/windows/mciavi.d b/libphobos/libdruntime/core/sys/windows/mciavi.d index 537bd4829c6..f7367e3caa3 100644 --- a/libphobos/libdruntime/core/sys/windows/mciavi.d +++ b/libphobos/libdruntime/core/sys/windows/mciavi.d @@ -9,8 +9,9 @@ */ module core.sys.windows.mciavi; version (Windows): +@system: -private import core.sys.windows.mmsystem; +import core.sys.windows.mmsystem; // FIXME: check types and grouping of constants diff --git a/libphobos/libdruntime/core/sys/windows/mcx.d b/libphobos/libdruntime/core/sys/windows/mcx.d index 11f6a452d81..01b28ad3855 100644 --- a/libphobos/libdruntime/core/sys/windows/mcx.d +++ b/libphobos/libdruntime/core/sys/windows/mcx.d @@ -9,8 +9,9 @@ */ module core.sys.windows.mcx; version (Windows): +@system: -private import core.sys.windows.windef; +import core.sys.windows.windef; enum DWORD DIALOPTION_BILLING = 64, diff --git a/libphobos/libdruntime/core/sys/windows/mgmtapi.d b/libphobos/libdruntime/core/sys/windows/mgmtapi.d index 3a11e81bfca..673fba8c37e 100644 --- a/libphobos/libdruntime/core/sys/windows/mgmtapi.d +++ b/libphobos/libdruntime/core/sys/windows/mgmtapi.d @@ -9,9 +9,10 @@ */ module core.sys.windows.mgmtapi; version (Windows): +@system: import core.sys.windows.snmp; -private import core.sys.windows.windef; +import core.sys.windows.windef; enum { SNMP_MGMTAPI_TIMEOUT = 40, diff --git a/libphobos/libdruntime/core/sys/windows/mmsystem.d b/libphobos/libdruntime/core/sys/windows/mmsystem.d index ceb4c3d513a..9359afd0e03 100644 --- a/libphobos/libdruntime/core/sys/windows/mmsystem.d +++ b/libphobos/libdruntime/core/sys/windows/mmsystem.d @@ -8,6 +8,7 @@ */ module core.sys.windows.mmsystem; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "winmm"); @@ -16,7 +17,7 @@ pragma(lib, "winmm"); * compile-time constants, so they are implemented as templates. */ -private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver; +import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver; align(1): @@ -1039,7 +1040,7 @@ struct MMTIME { BYTE fps; BYTE dummy; BYTE[2] pad; - }; + } _smpte smpte; struct _midi { DWORD songptrpos; diff --git a/libphobos/libdruntime/core/sys/windows/msacm.d b/libphobos/libdruntime/core/sys/windows/msacm.d index c6bf8af248e..b5d3052d7c6 100644 --- a/libphobos/libdruntime/core/sys/windows/msacm.d +++ b/libphobos/libdruntime/core/sys/windows/msacm.d @@ -9,10 +9,11 @@ */ module core.sys.windows.msacm; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.basetsd, core.sys.windows.mmsystem, core.sys.windows.windef; +import core.sys.windows.basetsd, core.sys.windows.mmsystem, core.sys.windows.windef; mixin DECLARE_HANDLE!("HACMDRIVERID"); mixin DECLARE_HANDLE!("HACMDRIVER"); diff --git a/libphobos/libdruntime/core/sys/windows/mshtml.d b/libphobos/libdruntime/core/sys/windows/mshtml.d index 796f1d3083f..2c4410d6bf3 100644 --- a/libphobos/libdruntime/core/sys/windows/mshtml.d +++ b/libphobos/libdruntime/core/sys/windows/mshtml.d @@ -8,39 +8,40 @@ */ module core.sys.windows.mshtml; version (Windows): +@system: -private import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn, +import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; // These are used in this file, but not defined in MinGW. -interface IHTMLStyleSheet {}; +interface IHTMLStyleSheet {} alias IHTMLStyle LPHTMLSTYLE; alias IHTMLStyleSheet LPHTMLSTYLESHEET; -interface IHTMLLocation {}; +interface IHTMLLocation {} alias IHTMLLocation LPHTMLLOCATION; -interface IHTMLFramesCollection {}; +interface IHTMLFramesCollection {} alias IHTMLFramesCollection LPHTMLFRAMESCOLLECTION; -interface IHTMLStyleSheetsCollection {}; +interface IHTMLStyleSheetsCollection {} alias IHTMLStyleSheetsCollection LPHTMLSTYLESHEETSCOLLECTION; -interface IHTMLStyle {}; -interface IHTMLFiltersCollection {}; +interface IHTMLStyle {} +interface IHTMLFiltersCollection {} alias IHTMLFiltersCollection LPHTMLFILTERSCOLLECTION; interface IOmHistory : IDispatch { HRESULT get_length(short* p); HRESULT back(VARIANT*); HRESULT forward(VARIANT*); HRESULT go(VARIANT*); -}; +} alias IOmHistory LPOMHISTORY; -interface IOmNavigator {}; +interface IOmNavigator {} alias IOmNavigator LPOMNAVIGATOR; -interface IHTMLImageElementFactory {}; +interface IHTMLImageElementFactory {} alias IHTMLImageElementFactory LPHTMLIMAGEELEMENTFACTORY; -interface IHTMLEventObj {}; +interface IHTMLEventObj {} alias IHTMLEventObj LPHTMLEVENTOBJ; -interface IHTMLScreen {}; +interface IHTMLScreen {} alias IHTMLScreen LPHTMLSCREEN; -interface IHTMLOptionElementFactory {}; +interface IHTMLOptionElementFactory {} alias IHTMLOptionElementFactory LPHTMLOPTIONELEMENTFACTORY; interface IHTMLLinkElement : IDispatch { diff --git a/libphobos/libdruntime/core/sys/windows/mswsock.d b/libphobos/libdruntime/core/sys/windows/mswsock.d index f7088ee1d03..cd6b63c197c 100644 --- a/libphobos/libdruntime/core/sys/windows/mswsock.d +++ b/libphobos/libdruntime/core/sys/windows/mswsock.d @@ -9,9 +9,10 @@ */ module core.sys.windows.mswsock; version (Windows): +@system: import core.sys.windows.winbase, core.sys.windows.windef; -private import core.sys.windows.basetyps, core.sys.windows.w32api; +import core.sys.windows.basetyps, core.sys.windows.w32api; import core.sys.windows.winsock2; diff --git a/libphobos/libdruntime/core/sys/windows/nb30.d b/libphobos/libdruntime/core/sys/windows/nb30.d index d587a9f723f..0d250cc40af 100644 --- a/libphobos/libdruntime/core/sys/windows/nb30.d +++ b/libphobos/libdruntime/core/sys/windows/nb30.d @@ -9,8 +9,9 @@ */ module core.sys.windows.nb30; version (Windows): +@system: -private import core.sys.windows.windef; +import core.sys.windows.windef; enum size_t NCBNAMSZ = 16, diff --git a/libphobos/libdruntime/core/sys/windows/nddeapi.d b/libphobos/libdruntime/core/sys/windows/nddeapi.d index b50e6ccc7e3..d4692c9db8a 100644 --- a/libphobos/libdruntime/core/sys/windows/nddeapi.d +++ b/libphobos/libdruntime/core/sys/windows/nddeapi.d @@ -9,10 +9,11 @@ */ module core.sys.windows.nddeapi; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.windef; +import core.sys.windows.windef; // FIXME: check types and grouping of constants diff --git a/libphobos/libdruntime/core/sys/windows/nspapi.d b/libphobos/libdruntime/core/sys/windows/nspapi.d index 0e03acdf271..a2e7fab02f6 100644 --- a/libphobos/libdruntime/core/sys/windows/nspapi.d +++ b/libphobos/libdruntime/core/sys/windows/nspapi.d @@ -9,10 +9,11 @@ */ module core.sys.windows.nspapi; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.basetyps, core.sys.windows.windef; +import core.sys.windows.basetyps, core.sys.windows.windef; // FIXME: check types of constants diff --git a/libphobos/libdruntime/core/sys/windows/ntdef.d b/libphobos/libdruntime/core/sys/windows/ntdef.d index 3dc875e18c9..83d668c0eeb 100644 --- a/libphobos/libdruntime/core/sys/windows/ntdef.d +++ b/libphobos/libdruntime/core/sys/windows/ntdef.d @@ -9,8 +9,9 @@ */ module core.sys.windows.ntdef; version (Windows): +@system: -private import core.sys.windows.basetsd, core.sys.windows.subauth, core.sys.windows.windef, core.sys.windows.winnt; +import core.sys.windows.basetsd, core.sys.windows.subauth, core.sys.windows.windef, core.sys.windows.winnt; enum uint OBJ_INHERIT = 0x0002, diff --git a/libphobos/libdruntime/core/sys/windows/ntdll.d b/libphobos/libdruntime/core/sys/windows/ntdll.d index 72ad54d466c..e8aa3a7b4ca 100644 --- a/libphobos/libdruntime/core/sys/windows/ntdll.d +++ b/libphobos/libdruntime/core/sys/windows/ntdll.d @@ -9,8 +9,9 @@ */ module core.sys.windows.ntdll; version (Windows): +@system: -private import core.sys.windows.w32api; +import core.sys.windows.w32api; enum SHUTDOWN_ACTION { diff --git a/libphobos/libdruntime/core/sys/windows/ntldap.d b/libphobos/libdruntime/core/sys/windows/ntldap.d index 34376589665..e7a55dd2f76 100644 --- a/libphobos/libdruntime/core/sys/windows/ntldap.d +++ b/libphobos/libdruntime/core/sys/windows/ntldap.d @@ -9,6 +9,7 @@ */ module core.sys.windows.ntldap; version (Windows): +@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/ntsecapi.d b/libphobos/libdruntime/core/sys/windows/ntsecapi.d index b043168994c..df9c10a3bb2 100644 --- a/libphobos/libdruntime/core/sys/windows/ntsecapi.d +++ b/libphobos/libdruntime/core/sys/windows/ntsecapi.d @@ -9,6 +9,7 @@ */ module core.sys.windows.ntsecapi; version (Windows): +@system: pragma(lib, "advapi32"); version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/ntsecpkg.d b/libphobos/libdruntime/core/sys/windows/ntsecpkg.d index 55a31123b3e..8625b7ae039 100644 --- a/libphobos/libdruntime/core/sys/windows/ntsecpkg.d +++ b/libphobos/libdruntime/core/sys/windows/ntsecpkg.d @@ -9,6 +9,7 @@ */ module core.sys.windows.ntsecpkg; version (Windows): +@system: import core.sys.windows.windef, core.sys.windows.ntsecapi, core.sys.windows.security, core.sys.windows.ntdef, core.sys.windows.sspi; import core.sys.windows.basetyps : GUID; diff --git a/libphobos/libdruntime/core/sys/windows/oaidl.d b/libphobos/libdruntime/core/sys/windows/oaidl.d index c8938ffa8e8..51d6be904df 100644 --- a/libphobos/libdruntime/core/sys/windows/oaidl.d +++ b/libphobos/libdruntime/core/sys/windows/oaidl.d @@ -8,8 +8,9 @@ */ module core.sys.windows.oaidl; version (Windows): +@system: -private import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; +import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; enum DISPID_UNKNOWN = -1; enum DISPID_VALUE = 0; diff --git a/libphobos/libdruntime/core/sys/windows/objbase.d b/libphobos/libdruntime/core/sys/windows/objbase.d index ee3f0d5f98d..961ebcc833a 100644 --- a/libphobos/libdruntime/core/sys/windows/objbase.d +++ b/libphobos/libdruntime/core/sys/windows/objbase.d @@ -8,10 +8,11 @@ */ module core.sys.windows.objbase; version (Windows): +@system: pragma(lib, "ole32"); import core.sys.windows.cguid, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.wtypes; -private import core.sys.windows.basetyps, core.sys.windows.objfwd, core.sys.windows.rpcdce, core.sys.windows.winbase, +import core.sys.windows.basetyps, core.sys.windows.objfwd, core.sys.windows.rpcdce, core.sys.windows.winbase, core.sys.windows.windef; // DAC: Not needed for D? diff --git a/libphobos/libdruntime/core/sys/windows/objfwd.d b/libphobos/libdruntime/core/sys/windows/objfwd.d index 70a2a1045f3..76d4f4144c5 100644 --- a/libphobos/libdruntime/core/sys/windows/objfwd.d +++ b/libphobos/libdruntime/core/sys/windows/objfwd.d @@ -8,8 +8,9 @@ */ module core.sys.windows.objfwd; version (Windows): +@system: -private import core.sys.windows.objidl; +import core.sys.windows.objidl; /+ // Forward declararions are not necessary in D. diff --git a/libphobos/libdruntime/core/sys/windows/objidl.d b/libphobos/libdruntime/core/sys/windows/objidl.d index 7b3367705b1..5368c296c37 100644 --- a/libphobos/libdruntime/core/sys/windows/objidl.d +++ b/libphobos/libdruntime/core/sys/windows/objidl.d @@ -12,15 +12,16 @@ // # do we need the proxies that are defined in this file? module core.sys.windows.objidl; version (Windows): +@system: import core.sys.windows.unknwn; import core.sys.windows.objfwd; -private import core.sys.windows.windef; -private import core.sys.windows.basetyps; -private import core.sys.windows.oleidl; -private import core.sys.windows.wtypes; -private import core.sys.windows.winbase; // for FILETIME -private import core.sys.windows.rpcdce; +import core.sys.windows.windef; +import core.sys.windows.basetyps; +import core.sys.windows.oleidl; +import core.sys.windows.wtypes; +import core.sys.windows.winbase; // for FILETIME +import core.sys.windows.rpcdce; struct STATSTG { LPOLESTR pwcsName; diff --git a/libphobos/libdruntime/core/sys/windows/objsafe.d b/libphobos/libdruntime/core/sys/windows/objsafe.d index 25569845e7d..0bfd19a0fd5 100644 --- a/libphobos/libdruntime/core/sys/windows/objsafe.d +++ b/libphobos/libdruntime/core/sys/windows/objsafe.d @@ -9,8 +9,9 @@ */ module core.sys.windows.objsafe; version (Windows): +@system: -private import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef; +import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef; enum { INTERFACESAFE_FOR_UNTRUSTED_CALLER = 1, diff --git a/libphobos/libdruntime/core/sys/windows/ocidl.d b/libphobos/libdruntime/core/sys/windows/ocidl.d index 4244ba1a6c2..4b090b0a005 100644 --- a/libphobos/libdruntime/core/sys/windows/ocidl.d +++ b/libphobos/libdruntime/core/sys/windows/ocidl.d @@ -10,12 +10,13 @@ */ module core.sys.windows.ocidl; version (Windows): +@system: -private import core.sys.windows.ole2, core.sys.windows.oleidl, core.sys.windows.oaidl, core.sys.windows.objfwd, +import core.sys.windows.ole2, core.sys.windows.oleidl, core.sys.windows.oaidl, core.sys.windows.objfwd, core.sys.windows.windef, core.sys.windows.wtypes; -private import core.sys.windows.objidl; // for CLIPFORMAT -private import core.sys.windows.wingdi; // for TEXTMETRICW -private import core.sys.windows.winuser; // for LPMSG +import core.sys.windows.objidl; // for CLIPFORMAT +import core.sys.windows.wingdi; // for TEXTMETRICW +import core.sys.windows.winuser; // for LPMSG interface IBindHost : IUnknown {} @@ -25,8 +26,8 @@ interface IServiceProvider : IUnknown{ /* // TODO: -//private import core.sys.windows.servprov; // for IServiceProvider -// private import core.sys.windows.urlmon; // for IBindHost. This is not included in MinGW. +//import core.sys.windows.servprov; // for IServiceProvider +// import core.sys.windows.urlmon; // for IBindHost. This is not included in MinGW. // core.sys.windows.urlmon should contain: interface IBindHost : IUnknown diff --git a/libphobos/libdruntime/core/sys/windows/odbcinst.d b/libphobos/libdruntime/core/sys/windows/odbcinst.d index 8947b39abd5..ee22bc6a86b 100644 --- a/libphobos/libdruntime/core/sys/windows/odbcinst.d +++ b/libphobos/libdruntime/core/sys/windows/odbcinst.d @@ -8,11 +8,12 @@ */ module core.sys.windows.odbcinst; version (Windows): +@system: version (ANSI) {} else version = Unicode; import core.sys.windows.sql; -private import core.sys.windows.windef; +import core.sys.windows.windef; /* FIXME: The Unicode/Ansi functions situation is a mess. How do the xxxA * versions of these functions fit into the scheme? diff --git a/libphobos/libdruntime/core/sys/windows/ole.d b/libphobos/libdruntime/core/sys/windows/ole.d index cb7dffe4104..1a49ea51cd4 100644 --- a/libphobos/libdruntime/core/sys/windows/ole.d +++ b/libphobos/libdruntime/core/sys/windows/ole.d @@ -9,9 +9,10 @@ */ module core.sys.windows.ole; version (Windows): +@system: pragma(lib, "ole32"); -private import core.sys.windows.windef, core.sys.windows.wingdi, core.sys.windows.uuid; +import core.sys.windows.windef, core.sys.windows.wingdi, core.sys.windows.uuid; alias LPCSTR OLE_LPCSTR; diff --git a/libphobos/libdruntime/core/sys/windows/ole2.d b/libphobos/libdruntime/core/sys/windows/ole2.d index 0f216af547c..575a8eb8d61 100644 --- a/libphobos/libdruntime/core/sys/windows/ole2.d +++ b/libphobos/libdruntime/core/sys/windows/ole2.d @@ -8,12 +8,13 @@ */ module core.sys.windows.ole2; version (Windows): +@system: pragma(lib, "ole32"); public import core.sys.windows.basetyps, core.sys.windows.objbase, core.sys.windows.oleauto, core.sys.windows.olectlid, core.sys.windows.oleidl, core.sys.windows.unknwn, core.sys.windows.winerror, core.sys.windows.uuid; -private import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.windef, core.sys.windows.wtypes; -private import core.sys.windows.winuser; // for LPMSG +import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.windef, core.sys.windows.wtypes; +import core.sys.windows.winuser; // for LPMSG enum E_DRAW = VIEW_E_DRAW; diff --git a/libphobos/libdruntime/core/sys/windows/oleacc.d b/libphobos/libdruntime/core/sys/windows/oleacc.d index fb4f770c3ad..77ced02dc0b 100644 --- a/libphobos/libdruntime/core/sys/windows/oleacc.d +++ b/libphobos/libdruntime/core/sys/windows/oleacc.d @@ -8,11 +8,12 @@ */ module core.sys.windows.oleacc; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "oleacc"); -private import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn, core.sys.windows.wtypes, +import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn, core.sys.windows.wtypes, core.sys.windows.windef; enum { diff --git a/libphobos/libdruntime/core/sys/windows/oleauto.d b/libphobos/libdruntime/core/sys/windows/oleauto.d index 113456c1c81..20f34aff5a7 100644 --- a/libphobos/libdruntime/core/sys/windows/oleauto.d +++ b/libphobos/libdruntime/core/sys/windows/oleauto.d @@ -8,11 +8,12 @@ */ module core.sys.windows.oleauto; version (Windows): +@system: pragma(lib, "oleaut32"); import core.sys.windows.oaidl; -private import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; -private import core.sys.windows.winbase; // for SYSTEMTIME +import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; +import core.sys.windows.winbase; // for SYSTEMTIME align(8): enum STDOLE_MAJORVERNUM = 1; @@ -215,10 +216,10 @@ struct NUMPARSE { deprecated { // not actually deprecated, but they aren't converted yet. // (will need to reinstate CreateTypeLib as well) - interface ICreateTypeInfo {}; - interface ICreateTypeInfo2 {}; - interface ICreateTypeLib {}; - interface ICreateTypeLib2 {}; + interface ICreateTypeInfo {} + interface ICreateTypeInfo2 {} + interface ICreateTypeLib {} + interface ICreateTypeLib2 {} alias ICreateTypeInfo LPCREATETYPEINFO; alias ICreateTypeInfo2 LPCREATETYPEINFO2; diff --git a/libphobos/libdruntime/core/sys/windows/olectl.d b/libphobos/libdruntime/core/sys/windows/olectl.d index 3909c484833..e0bc679f929 100644 --- a/libphobos/libdruntime/core/sys/windows/olectl.d +++ b/libphobos/libdruntime/core/sys/windows/olectl.d @@ -8,16 +8,17 @@ */ module core.sys.windows.olectl; version (Windows): +@system: // In conversion from MinGW, the following was deleted: //#define FONTSIZE(n) {n##0000, 0} import core.sys.windows.ocidl, core.sys.windows.olectlid; -private import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.oleauto, core.sys.windows.unknwn, +import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.oleauto, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wingdi, core.sys.windows.winuser, core.sys.windows.wtypes; -private import core.sys.windows.ntdef; // for NTSTATUS -private import core.sys.windows.objfwd; // for LPSTREAM -private import core.sys.windows.winerror; // for SCODE +import core.sys.windows.ntdef; // for NTSTATUS +import core.sys.windows.objfwd; // for LPSTREAM +import core.sys.windows.winerror; // for SCODE private { diff --git a/libphobos/libdruntime/core/sys/windows/olectlid.d b/libphobos/libdruntime/core/sys/windows/olectlid.d index 72156a1062b..fd3ea899a2a 100644 --- a/libphobos/libdruntime/core/sys/windows/olectlid.d +++ b/libphobos/libdruntime/core/sys/windows/olectlid.d @@ -9,5 +9,5 @@ module core.sys.windows.olectlid; version (Windows): -private import core.sys.windows.basetyps; +import core.sys.windows.basetyps; diff --git a/libphobos/libdruntime/core/sys/windows/oledlg.d b/libphobos/libdruntime/core/sys/windows/oledlg.d index 732d302ac02..e44c0290162 100644 --- a/libphobos/libdruntime/core/sys/windows/oledlg.d +++ b/libphobos/libdruntime/core/sys/windows/oledlg.d @@ -7,12 +7,13 @@ * Source: $(DRUNTIMESRC src/core/sys/windows/_oledlg.d) */ module core.sys.windows.oledlg; +@system: version (Windows): version (ANSI) {} else version = Unicode; import core.sys.windows.commdlg, core.sys.windows.dlgs, core.sys.windows.ole2, core.sys.windows.prsht, core.sys.windows.shellapi; -private import core.sys.windows.winbase, core.sys.windows.objidl, core.sys.windows.objfwd, core.sys.windows.winnt; +import core.sys.windows.winbase, core.sys.windows.objidl, core.sys.windows.objfwd, core.sys.windows.winnt; // FIXME: remove inherited methods from interface definitions diff --git a/libphobos/libdruntime/core/sys/windows/oleidl.d b/libphobos/libdruntime/core/sys/windows/oleidl.d index 2c686023d7a..dc0cae85de3 100644 --- a/libphobos/libdruntime/core/sys/windows/oleidl.d +++ b/libphobos/libdruntime/core/sys/windows/oleidl.d @@ -8,15 +8,16 @@ */ module core.sys.windows.oleidl; version (Windows): +@system: // DAC: This is defined in ocidl !! // what is it doing in here? //alias IEnumOleUndoUnits LPENUMOLEUNDOUNITS; -private import core.sys.windows.basetyps, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.windef, +import core.sys.windows.basetyps, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.winuser, core.sys.windows.wtypes; -private import core.sys.windows.objfwd; // for LPMONIKER -private import core.sys.windows.wingdi; // for LPLOGPALETTE +import core.sys.windows.objfwd; // for LPMONIKER +import core.sys.windows.wingdi; // for LPLOGPALETTE enum MK_ALT = 32; diff --git a/libphobos/libdruntime/core/sys/windows/pbt.d b/libphobos/libdruntime/core/sys/windows/pbt.d index e6b7814eee2..aec938e9b82 100644 --- a/libphobos/libdruntime/core/sys/windows/pbt.d +++ b/libphobos/libdruntime/core/sys/windows/pbt.d @@ -9,8 +9,9 @@ */ module core.sys.windows.pbt; version (Windows): +@system: -private import core.sys.windows.windef; +import core.sys.windows.windef; enum : WPARAM { PBT_APMQUERYSUSPEND, diff --git a/libphobos/libdruntime/core/sys/windows/powrprof.d b/libphobos/libdruntime/core/sys/windows/powrprof.d index 59a90c55a5d..75ec73e8efe 100644 --- a/libphobos/libdruntime/core/sys/windows/powrprof.d +++ b/libphobos/libdruntime/core/sys/windows/powrprof.d @@ -9,10 +9,11 @@ */ module core.sys.windows.powrprof; version (Windows): +@system: pragma(lib, "powrprof"); -private import core.sys.windows.windef; -private import core.sys.windows.ntdef; +import core.sys.windows.windef; +import core.sys.windows.ntdef; // FIXME: look up Windows version support diff --git a/libphobos/libdruntime/core/sys/windows/prsht.d b/libphobos/libdruntime/core/sys/windows/prsht.d index 3dbb3146ea4..efea4f254c4 100644 --- a/libphobos/libdruntime/core/sys/windows/prsht.d +++ b/libphobos/libdruntime/core/sys/windows/prsht.d @@ -9,11 +9,12 @@ */ module core.sys.windows.prsht; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "comctl32"); -private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winuser; +import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winuser; enum MAXPROPPAGES = 100; diff --git a/libphobos/libdruntime/core/sys/windows/psapi.d b/libphobos/libdruntime/core/sys/windows/psapi.d index 708878442d0..7e62d9fc1bd 100644 --- a/libphobos/libdruntime/core/sys/windows/psapi.d +++ b/libphobos/libdruntime/core/sys/windows/psapi.d @@ -13,12 +13,13 @@ module core.sys.windows.psapi; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.w32api; -private import core.sys.windows.winbase; -private import core.sys.windows.windef; +import core.sys.windows.w32api; +import core.sys.windows.winbase; +import core.sys.windows.windef; struct MODULEINFO { LPVOID lpBaseOfDll; @@ -83,13 +84,11 @@ alias ENUM_PAGE_FILE_INFORMATION* PENUM_PAGE_FILE_INFORMATION; /* application-defined callback function used with the EnumPageFiles() * http://windowssdk.msdn.microsoft.com/library/ms682627.aspx */ -version (Unicode) { - alias BOOL function(LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCWSTR) - PENUM_PAGE_FILE_CALLBACK; -} else { - alias BOOL function(LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCSTR) - PENUM_PAGE_FILE_CALLBACK; -} +alias BOOL function(LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCWSTR) + PENUM_PAGE_FILE_CALLBACKW; +alias BOOL function(LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCSTR) + PENUM_PAGE_FILE_CALLBACKA; + // Grouped by application, not in alphabetical order. extern (Windows) { @@ -137,11 +136,12 @@ extern (Windows) { /* Resources Information */ BOOL GetPerformanceInfo(PPERFORMANCE_INFORMATION, DWORD); /* XP/Server2003/Vista/Longhorn */ - BOOL EnumPageFilesW(PENUM_PAGE_FILE_CALLBACK, LPVOID); /* 2000/XP/Server2003/Vista/Longhorn */ - BOOL EnumPageFilesA(PENUM_PAGE_FILE_CALLBACK, LPVOID); /* 2000/XP/Server2003/Vista/Longhorn */ + BOOL EnumPageFilesW(PENUM_PAGE_FILE_CALLBACKW, LPVOID); /* 2000/XP/Server2003/Vista/Longhorn */ + BOOL EnumPageFilesA(PENUM_PAGE_FILE_CALLBACKA, LPVOID); /* 2000/XP/Server2003/Vista/Longhorn */ } version (Unicode) { + alias PENUM_PAGE_FILE_CALLBACKW PENUM_PAGE_FILE_CALLBACK; alias GetModuleBaseNameW GetModuleBaseName; alias GetModuleFileNameExW GetModuleFileNameEx; alias GetMappedFileNameW GetMappedFileName; @@ -150,6 +150,7 @@ version (Unicode) { alias EnumPageFilesW EnumPageFiles; alias GetProcessImageFileNameW GetProcessImageFileName; } else { + alias PENUM_PAGE_FILE_CALLBACKA PENUM_PAGE_FILE_CALLBACK; alias GetModuleBaseNameA GetModuleBaseName; alias GetModuleFileNameExA GetModuleFileNameEx; alias GetMappedFileNameA GetMappedFileName; diff --git a/libphobos/libdruntime/core/sys/windows/rapi.d b/libphobos/libdruntime/core/sys/windows/rapi.d index b60a14b7e46..6c48f6bff26 100644 --- a/libphobos/libdruntime/core/sys/windows/rapi.d +++ b/libphobos/libdruntime/core/sys/windows/rapi.d @@ -9,13 +9,14 @@ */ module core.sys.windows.rapi; version (Windows): +@system: /* Comment from MinGW NOTE: This strictly does not belong in the Win32 API since it's really part of Platform SDK. */ -private import core.sys.windows.winbase, core.sys.windows.windef; +import core.sys.windows.winbase, core.sys.windows.windef; extern (Windows): diff --git a/libphobos/libdruntime/core/sys/windows/ras.d b/libphobos/libdruntime/core/sys/windows/ras.d index 479aa3ba0bf..1004c6b63f8 100644 --- a/libphobos/libdruntime/core/sys/windows/ras.d +++ b/libphobos/libdruntime/core/sys/windows/ras.d @@ -8,11 +8,12 @@ */ module core.sys.windows.ras; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "rasapi32"); -private import core.sys.windows.basetyps, core.sys.windows.lmcons, core.sys.windows.w32api, core.sys.windows.windef; +import core.sys.windows.basetyps, core.sys.windows.lmcons, core.sys.windows.w32api, core.sys.windows.windef; align(4): diff --git a/libphobos/libdruntime/core/sys/windows/rasdlg.d b/libphobos/libdruntime/core/sys/windows/rasdlg.d index 77346cb3318..8304a014129 100644 --- a/libphobos/libdruntime/core/sys/windows/rasdlg.d +++ b/libphobos/libdruntime/core/sys/windows/rasdlg.d @@ -9,11 +9,12 @@ */ module core.sys.windows.rasdlg; version (Windows): +@system: version (ANSI) {} else version = Unicode; import core.sys.windows.ras; -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; enum { RASPBDEVENT_AddEntry = 1, diff --git a/libphobos/libdruntime/core/sys/windows/raserror.d b/libphobos/libdruntime/core/sys/windows/raserror.d index 9004444e9ec..43bebacd34e 100644 --- a/libphobos/libdruntime/core/sys/windows/raserror.d +++ b/libphobos/libdruntime/core/sys/windows/raserror.d @@ -8,6 +8,7 @@ */ module core.sys.windows.raserror; version (Windows): +@system: enum { SUCCESS = 0, diff --git a/libphobos/libdruntime/core/sys/windows/rassapi.d b/libphobos/libdruntime/core/sys/windows/rassapi.d index b70dc07d146..0eaa5b28f5b 100644 --- a/libphobos/libdruntime/core/sys/windows/rassapi.d +++ b/libphobos/libdruntime/core/sys/windows/rassapi.d @@ -9,8 +9,9 @@ */ module core.sys.windows.rassapi; version (Windows): +@system: -private import core.sys.windows.lmcons, core.sys.windows.windef; +import core.sys.windows.lmcons, core.sys.windows.windef; // FIXME: check types of constants diff --git a/libphobos/libdruntime/core/sys/windows/reason.d b/libphobos/libdruntime/core/sys/windows/reason.d index 752f28e5c2d..b0c49693e18 100644 --- a/libphobos/libdruntime/core/sys/windows/reason.d +++ b/libphobos/libdruntime/core/sys/windows/reason.d @@ -9,8 +9,9 @@ */ module core.sys.windows.reason; version (Windows): +@system: -private import core.sys.windows.w32api, core.sys.windows.windef; +import core.sys.windows.w32api, core.sys.windows.windef; static assert (_WIN32_WINNT >= 0x501, "core.sys.windows.reason is only available on WindowsXP and later"); diff --git a/libphobos/libdruntime/core/sys/windows/regstr.d b/libphobos/libdruntime/core/sys/windows/regstr.d index 23029647ce2..1fa1c7e0d7f 100644 --- a/libphobos/libdruntime/core/sys/windows/regstr.d +++ b/libphobos/libdruntime/core/sys/windows/regstr.d @@ -8,10 +8,11 @@ */ module core.sys.windows.regstr; version (Windows): +@system: // TODO: fix possible conflict with shloj. Sort out NEC_98 issue. -private import core.sys.windows.windef; +import core.sys.windows.windef; enum REGSTR_MAX_VALUE_LENGTH = 256; diff --git a/libphobos/libdruntime/core/sys/windows/richedit.d b/libphobos/libdruntime/core/sys/windows/richedit.d index a05c3b8deaf..1abc8f3fd2a 100644 --- a/libphobos/libdruntime/core/sys/windows/richedit.d +++ b/libphobos/libdruntime/core/sys/windows/richedit.d @@ -8,11 +8,12 @@ */ module core.sys.windows.richedit; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.windef, core.sys.windows.winuser; -private import core.sys.windows.wingdi; // for LF_FACESIZE +import core.sys.windows.windef, core.sys.windows.winuser; +import core.sys.windows.wingdi; // for LF_FACESIZE align(4): diff --git a/libphobos/libdruntime/core/sys/windows/richole.d b/libphobos/libdruntime/core/sys/windows/richole.d index 56a0fd8ed87..a4e64e83b75 100644 --- a/libphobos/libdruntime/core/sys/windows/richole.d +++ b/libphobos/libdruntime/core/sys/windows/richole.d @@ -8,10 +8,11 @@ */ module core.sys.windows.richole; version (Windows): +@system: -private import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.ole2, core.sys.windows.unknwn, +import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.ole2, core.sys.windows.unknwn, core.sys.windows.windef; -private import core.sys.windows.richedit; // for CHARRANGE +import core.sys.windows.richedit; // for CHARRANGE //align(4): @@ -83,7 +84,7 @@ interface IRichEditOle : IUnknown { HRESULT ContextSensitiveHelp(BOOL); HRESULT GetClipboardData(CHARRANGE*, DWORD, LPDATAOBJECT*); HRESULT ImportDataObject(LPDATAOBJECT, CLIPFORMAT, HGLOBAL); -}; +} alias IRichEditOle LPRICHEDITOLE; interface IRichEditOleCallback : IUnknown { @@ -97,5 +98,5 @@ interface IRichEditOleCallback : IUnknown { HRESULT GetClipboardData(CHARRANGE*, DWORD, LPDATAOBJECT*); HRESULT GetDragDropEffect(BOOL, DWORD, PDWORD); HRESULT GetContextMenu(WORD, LPOLEOBJECT, CHARRANGE*, HMENU*); -}; +} alias IRichEditOleCallback LPRICHEDITOLECALLBACK; diff --git a/libphobos/libdruntime/core/sys/windows/rpc.d b/libphobos/libdruntime/core/sys/windows/rpc.d index 6097184e2dd..59221234392 100644 --- a/libphobos/libdruntime/core/sys/windows/rpc.d +++ b/libphobos/libdruntime/core/sys/windows/rpc.d @@ -8,6 +8,7 @@ */ module core.sys.windows.rpc; version (Windows): +@system: /* Moved to rpcdecp (duplicate definition). typedef void *I_RPC_HANDLE; diff --git a/libphobos/libdruntime/core/sys/windows/rpcdce.d b/libphobos/libdruntime/core/sys/windows/rpcdce.d index d29bd9d7f02..cdffbcf0e5c 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcdce.d +++ b/libphobos/libdruntime/core/sys/windows/rpcdce.d @@ -8,6 +8,7 @@ */ module core.sys.windows.rpcdce; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "Rpcrt4"); @@ -16,7 +17,7 @@ pragma(lib, "Rpcrt4"); // replaced aliases for version (Unicode) public import core.sys.windows.rpcdcep; -private import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.windef; +import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.windef; // FIXME: clean up Windows version support diff --git a/libphobos/libdruntime/core/sys/windows/rpcdce2.d b/libphobos/libdruntime/core/sys/windows/rpcdce2.d index 7993459fc2d..10ec910faae 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcdce2.d +++ b/libphobos/libdruntime/core/sys/windows/rpcdce2.d @@ -8,11 +8,12 @@ */ module core.sys.windows.rpcdce2; version (Windows): +@system: version (ANSI) {} else version = Unicode; import core.sys.windows.rpcdce; -private import core.sys.windows.basetyps; +import core.sys.windows.basetyps; // FIXME: deal with RPC_UNICODE_SUPPORTED // FIXME: check types of constants diff --git a/libphobos/libdruntime/core/sys/windows/rpcdcep.d b/libphobos/libdruntime/core/sys/windows/rpcdcep.d index 2d2927665a1..fe22bf8c724 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcdcep.d +++ b/libphobos/libdruntime/core/sys/windows/rpcdcep.d @@ -8,12 +8,13 @@ */ module core.sys.windows.rpcdcep; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.basetyps; -private import core.sys.windows.w32api; -private import core.sys.windows.windef; +import core.sys.windows.basetyps; +import core.sys.windows.w32api; +import core.sys.windows.windef; mixin DECLARE_HANDLE!("I_RPC_HANDLE"); alias long RPC_STATUS; diff --git a/libphobos/libdruntime/core/sys/windows/rpcndr.d b/libphobos/libdruntime/core/sys/windows/rpcndr.d index d75f1003bc3..6720b94aa9d 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcndr.d +++ b/libphobos/libdruntime/core/sys/windows/rpcndr.d @@ -8,6 +8,7 @@ */ module core.sys.windows.rpcndr; version (Windows): +@system: pragma(lib, "rpcrt4"); /* Translation notes: @@ -19,9 +20,9 @@ pragma(lib, "rpcrt4"); enum __RPCNDR_H_VERSION__= 450; import core.sys.windows.rpcnsip; -private import core.sys.windows.rpc, core.sys.windows.rpcdce, core.sys.windows.unknwn, core.sys.windows.windef; -private import core.sys.windows.objidl; // for IRpcChannelBuffer, IRpcStubBuffer -private import core.sys.windows.basetyps; +import core.sys.windows.rpc, core.sys.windows.rpcdce, core.sys.windows.unknwn, core.sys.windows.windef; +import core.sys.windows.objidl; // for IRpcChannelBuffer, IRpcStubBuffer +import core.sys.windows.basetyps; extern (Windows): diff --git a/libphobos/libdruntime/core/sys/windows/rpcnsi.d b/libphobos/libdruntime/core/sys/windows/rpcnsi.d index f4e85385bf6..2ecae63aefe 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcnsi.d +++ b/libphobos/libdruntime/core/sys/windows/rpcnsi.d @@ -10,13 +10,14 @@ */ module core.sys.windows.rpcnsi; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "rpcns4"); -private import core.sys.windows.basetyps, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi, core.sys.windows.rpcdce, +import core.sys.windows.basetyps, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi, core.sys.windows.rpcdce, core.sys.windows.w32api; -private import core.sys.windows.windef; // for HANDLE +import core.sys.windows.windef; // for HANDLE mixin DECLARE_HANDLE!("RPC_NS_HANDLE"); diff --git a/libphobos/libdruntime/core/sys/windows/rpcnsip.d b/libphobos/libdruntime/core/sys/windows/rpcnsip.d index fcf43898366..1c0f050df75 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcnsip.d +++ b/libphobos/libdruntime/core/sys/windows/rpcnsip.d @@ -8,8 +8,9 @@ */ module core.sys.windows.rpcnsip; version (Windows): +@system: -private import core.sys.windows.rpcdce, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi; +import core.sys.windows.rpcdce, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi; struct RPC_IMPORT_CONTEXT_P { RPC_NS_HANDLE LookupContext; diff --git a/libphobos/libdruntime/core/sys/windows/rpcnterr.d b/libphobos/libdruntime/core/sys/windows/rpcnterr.d index 8b1e5835b01..dcd63ab454f 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcnterr.d +++ b/libphobos/libdruntime/core/sys/windows/rpcnterr.d @@ -8,6 +8,7 @@ */ module core.sys.windows.rpcnterr; version (Windows): +@system: import core.sys.windows.winerror; diff --git a/libphobos/libdruntime/core/sys/windows/schannel.d b/libphobos/libdruntime/core/sys/windows/schannel.d index c7622387a9d..1d2fbda7ddb 100644 --- a/libphobos/libdruntime/core/sys/windows/schannel.d +++ b/libphobos/libdruntime/core/sys/windows/schannel.d @@ -9,9 +9,10 @@ */ module core.sys.windows.schannel; version (Windows): +@system: import core.sys.windows.wincrypt; -private import core.sys.windows.windef; +import core.sys.windows.windef; enum DWORD SCHANNEL_CRED_VERSION = 4; enum SCHANNEL_SHUTDOWN = 1; diff --git a/libphobos/libdruntime/core/sys/windows/sdkddkver.d b/libphobos/libdruntime/core/sys/windows/sdkddkver.d new file mode 100644 index 00000000000..3af3c86d2c0 --- /dev/null +++ b/libphobos/libdruntime/core/sys/windows/sdkddkver.d @@ -0,0 +1,118 @@ +/** + * Windows API header module + * + * Translated from Windows SDK API + * + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC src/core/sys/windows/sdkddkver.d) + */ +module core.sys.windows.sdkddkver; + +version (Windows): +@system: + +enum _WIN32_WINNT_NT4 = 0x0400; +enum _WIN32_WINNT_WIN2K = 0x0500; +enum _WIN32_WINNT_WINXP = 0x0501; +enum _WIN32_WINNT_WS03 = 0x0502; +enum _WIN32_WINNT_WIN6 = 0x0600; +enum _WIN32_WINNT_VISTA = 0x0600; +enum _WIN32_WINNT_WS08 = 0x0600; +enum _WIN32_WINNT_LONGHORN = 0x0600; +enum _WIN32_WINNT_WIN7 = 0x0601; +enum _WIN32_WINNT_WIN8 = 0x0602; +enum _WIN32_WINNT_WINBLUE = 0x0603; +enum _WIN32_WINNT_WIN10 = 0x0A00; + +enum _WIN32_IE_IE20 = 0x0200; +enum _WIN32_IE_IE30 = 0x0300; +enum _WIN32_IE_IE302 = 0x0302; +enum _WIN32_IE_IE40 = 0x0400; +enum _WIN32_IE_IE401 = 0x0401; +enum _WIN32_IE_IE50 = 0x0500; +enum _WIN32_IE_IE501 = 0x0501; +enum _WIN32_IE_IE55 = 0x0550; +enum _WIN32_IE_IE60 = 0x0600; +enum _WIN32_IE_IE60SP1 = 0x0601; +enum _WIN32_IE_IE60SP2 = 0x0603; +enum _WIN32_IE_IE70 = 0x0700; +enum _WIN32_IE_IE80 = 0x0800; +enum _WIN32_IE_IE90 = 0x0900; +enum _WIN32_IE_IE100 = 0x0A00; + +enum _WIN32_IE_NT4 = _WIN32_IE_IE20; +enum _WIN32_IE_NT4SP1 = _WIN32_IE_IE20; +enum _WIN32_IE_NT4SP2 = _WIN32_IE_IE20; +enum _WIN32_IE_NT4SP3 = _WIN32_IE_IE302; +enum _WIN32_IE_NT4SP4 = _WIN32_IE_IE401; +enum _WIN32_IE_NT4SP5 = _WIN32_IE_IE401; +enum _WIN32_IE_NT4SP6 = _WIN32_IE_IE50; +enum _WIN32_IE_WIN98 = _WIN32_IE_IE401; +enum _WIN32_IE_WIN98SE = _WIN32_IE_IE50; +enum _WIN32_IE_WINME = _WIN32_IE_IE55; +enum _WIN32_IE_WIN2K = _WIN32_IE_IE501; +enum _WIN32_IE_WIN2KSP1 = _WIN32_IE_IE501; +enum _WIN32_IE_WIN2KSP2 = _WIN32_IE_IE501; +enum _WIN32_IE_WIN2KSP3 = _WIN32_IE_IE501; +enum _WIN32_IE_WIN2KSP4 = _WIN32_IE_IE501; +enum _WIN32_IE_XP = _WIN32_IE_IE60; +enum _WIN32_IE_XPSP1 = _WIN32_IE_IE60SP1; +enum _WIN32_IE_XPSP2 = _WIN32_IE_IE60SP2; +enum _WIN32_IE_WS03 = 0x0602; +enum _WIN32_IE_WS03SP1 = _WIN32_IE_IE60SP2; +enum _WIN32_IE_WIN6 = _WIN32_IE_IE70; +enum _WIN32_IE_LONGHORN = _WIN32_IE_IE70; +enum _WIN32_IE_WIN7 = _WIN32_IE_IE80; +enum _WIN32_IE_WIN8 = _WIN32_IE_IE100; +enum _WIN32_IE_WINBLUE = _WIN32_IE_IE100; + + +enum NTDDI_WIN2K = 0x05000000; +enum NTDDI_WIN2KSP1 = 0x05000100; +enum NTDDI_WIN2KSP2 = 0x05000200; +enum NTDDI_WIN2KSP3 = 0x05000300; +enum NTDDI_WIN2KSP4 = 0x05000400; + +enum NTDDI_WINXP = 0x05010000; +enum NTDDI_WINXPSP1 = 0x05010100; +enum NTDDI_WINXPSP2 = 0x05010200; +enum NTDDI_WINXPSP3 = 0x05010300; +enum NTDDI_WINXPSP4 = 0x05010400; + +enum NTDDI_WS03 = 0x05020000; +enum NTDDI_WS03SP1 = 0x05020100; +enum NTDDI_WS03SP2 = 0x05020200; +enum NTDDI_WS03SP3 = 0x05020300; +enum NTDDI_WS03SP4 = 0x05020400; + +enum NTDDI_WIN6 = 0x06000000; +enum NTDDI_WIN6SP1 = 0x06000100; +enum NTDDI_WIN6SP2 = 0x06000200; +enum NTDDI_WIN6SP3 = 0x06000300; +enum NTDDI_WIN6SP4 = 0x06000400; + +enum NTDDI_VISTA = NTDDI_WIN6; +enum NTDDI_VISTASP1 = NTDDI_WIN6SP1; +enum NTDDI_VISTASP2 = NTDDI_WIN6SP2; +enum NTDDI_VISTASP3 = NTDDI_WIN6SP3; +enum NTDDI_VISTASP4 = NTDDI_WIN6SP4; + +enum NTDDI_LONGHORN = NTDDI_VISTA; + +enum NTDDI_WS08 = NTDDI_WIN6SP1; +enum NTDDI_WS08SP2 = NTDDI_WIN6SP2; +enum NTDDI_WS08SP3 = NTDDI_WIN6SP3; +enum NTDDI_WS08SP4 = NTDDI_WIN6SP4; + +enum NTDDI_WIN7 = 0x06010000; +enum NTDDI_WIN8 = 0x06020000; +enum NTDDI_WINBLUE = 0x06030000; + +enum OSVERSION_MASK = 0xFFFF0000; +enum SPVERSION_MASK = 0x0000FF00; +enum SUBVERSION_MASK = 0x000000FF; + +enum _WIN32_WINNT = 0x0603; + +enum NTDDI_VERSION = 0x06030000; +enum WINVER = _WIN32_WINNT; diff --git a/libphobos/libdruntime/core/sys/windows/secext.d b/libphobos/libdruntime/core/sys/windows/secext.d index 486025d05ca..dd4ec8589a6 100644 --- a/libphobos/libdruntime/core/sys/windows/secext.d +++ b/libphobos/libdruntime/core/sys/windows/secext.d @@ -9,11 +9,12 @@ // Don't include this file directly, use core.sys.windows.security instead. module core.sys.windows.secext; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "secur32"); -private import core.sys.windows.w32api, core.sys.windows.windef; +import core.sys.windows.w32api, core.sys.windows.windef; static assert (_WIN32_WINNT >= 0x501, "SecExt is only available on WindowsXP and later"); diff --git a/libphobos/libdruntime/core/sys/windows/security.d b/libphobos/libdruntime/core/sys/windows/security.d index a5f57851ccb..2dc7c194975 100644 --- a/libphobos/libdruntime/core/sys/windows/security.d +++ b/libphobos/libdruntime/core/sys/windows/security.d @@ -3,44 +3,118 @@ * * Translated from MinGW Windows headers * - * Authors: Ellery Newcomer + * Authors: Ellery Newcomer, John Colvin * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(DRUNTIMESRC src/core/sys/windows/_security.d) */ module core.sys.windows.security; version (Windows): +@system: -enum :SECURITY_STATUS{ - SEC_E_OK = 0, - SEC_E_CERT_EXPIRED = (-2146893016), - SEC_E_INCOMPLETE_MESSAGE = (-2146893032), - SEC_E_INSUFFICIENT_MEMORY = (-2146893056), - SEC_E_INTERNAL_ERROR = (-2146893052), - SEC_E_INVALID_HANDLE = (-2146893055), - SEC_E_INVALID_TOKEN = (-2146893048), - SEC_E_LOGON_DENIED = (-2146893044), - SEC_E_NO_AUTHENTICATING_AUTHORITY = (-2146893039), - SEC_E_NO_CREDENTIALS = (-2146893042), - SEC_E_TARGET_UNKNOWN = (-2146893053), - SEC_E_UNSUPPORTED_FUNCTION = (-2146893054), - SEC_E_UNTRUSTED_ROOT = (-2146893019), - SEC_E_WRONG_PRINCIPAL = (-2146893022), - SEC_E_SECPKG_NOT_FOUND = (-2146893051), - SEC_E_QOP_NOT_SUPPORTED = (-2146893046), - SEC_E_UNKNOWN_CREDENTIALS = (-2146893043), - SEC_E_NOT_OWNER = (-2146893050), +enum : SECURITY_STATUS +{ + SEC_E_OK = 0x00000000, + SEC_E_INSUFFICIENT_MEMORY = 0x80090300, + SEC_E_INVALID_HANDLE = 0x80090301, + SEC_E_UNSUPPORTED_FUNCTION = 0x80090302, + SEC_E_TARGET_UNKNOWN = 0x80090303, + SEC_E_INTERNAL_ERROR = 0x80090304, + SEC_E_SECPKG_NOT_FOUND = 0x80090305, + SEC_E_NOT_OWNER = 0x80090306, + SEC_E_CANNOT_INSTALL = 0x80090307, + SEC_E_INVALID_TOKEN = 0x80090308, + SEC_E_CANNOT_PACK = 0x80090309, + SEC_E_QOP_NOT_SUPPORTED = 0x8009030A, + SEC_E_NO_IMPERSONATION = 0x8009030B, + SEC_E_LOGON_DENIED = 0x8009030C, + SEC_E_UNKNOWN_CREDENTIALS = 0x8009030D, + SEC_E_NO_CREDENTIALS = 0x8009030E, + SEC_E_MESSAGE_ALTERED = 0x8009030F, + SEC_E_OUT_OF_SEQUENCE = 0x80090310, + SEC_E_NO_AUTHENTICATING_AUTHORITY = 0x80090311, + SEC_E_BAD_PKGID = 0x80090316, + SEC_E_CONTEXT_EXPIRED = 0x80090317, + SEC_E_INCOMPLETE_MESSAGE = 0x80090318, + SEC_E_INCOMPLETE_CREDENTIALS = 0x80090320, + SEC_E_BUFFER_TOO_SMALL = 0x80090321, + SEC_E_WRONG_PRINCIPAL = 0x80090322, + SEC_E_TIME_SKEW = 0x80090324, + SEC_E_UNTRUSTED_ROOT = 0x80090325, + SEC_E_ILLEGAL_MESSAGE = 0x80090326, + SEC_E_CERT_UNKNOWN = 0x80090327, + SEC_E_CERT_EXPIRED = 0x80090328, + SEC_E_ENCRYPT_FAILURE = 0x80090329, + SEC_E_DECRYPT_FAILURE = 0x80090330, + SEC_E_ALGORITHM_MISMATCH = 0x80090331, + SEC_E_SECURITY_QOS_FAILED = 0x80090332, + SEC_E_UNFINISHED_CONTEXT_DELETED = 0x80090333, + SEC_E_NO_TGT_REPLY = 0x80090334, + SEC_E_NO_IP_ADDRESSES = 0x80090335, + SEC_E_WRONG_CREDENTIAL_HANDLE = 0x80090336, + SEC_E_CRYPTO_SYSTEM_INVALID = 0x80090337, + SEC_E_MAX_REFERRALS_EXCEEDED = 0x80090338, + SEC_E_MUST_BE_KDC = 0x80090339, + SEC_E_STRONG_CRYPTO_NOT_SUPPORTED = 0x8009033A, + SEC_E_TOO_MANY_PRINCIPALS = 0x8009033B, + SEC_E_NO_PA_DATA = 0x8009033C, + SEC_E_PKINIT_NAME_MISMATCH = 0x8009033D, + SEC_E_SMARTCARD_LOGON_REQUIRED = 0x8009033E, + SEC_E_SHUTDOWN_IN_PROGRESS = 0x8009033F, + SEC_E_KDC_INVALID_REQUEST = 0x80090340, + SEC_E_KDC_UNABLE_TO_REFER = 0x80090341, + SEC_E_KDC_UNKNOWN_ETYPE = 0x80090342, + SEC_E_UNSUPPORTED_PREAUTH = 0x80090343, + SEC_E_DELEGATION_REQUIRED = 0x80090345, + SEC_E_BAD_BINDINGS = 0x80090346, + SEC_E_MULTIPLE_ACCOUNTS = 0x80090347, + SEC_E_NO_KERB_KEY = 0x80090348, + SEC_E_CERT_WRONG_USAGE = 0x80090349, + SEC_E_DOWNGRADE_DETECTED = 0x80090350, + SEC_E_SMARTCARD_CERT_REVOKED = 0x80090351, + SEC_E_ISSUING_CA_UNTRUSTED = 0x80090352, + SEC_E_REVOCATION_OFFLINE_C = 0x80090353, + SEC_E_PKINIT_CLIENT_FAILURE = 0x80090354, + SEC_E_SMARTCARD_CERT_EXPIRED = 0x80090355, + SEC_E_NO_S4U_PROT_SUPPORT = 0x80090356, + SEC_E_CROSSREALM_DELEGATION_FAILURE = 0x80090357, + SEC_E_REVOCATION_OFFLINE_KDC = 0x80090358, + SEC_E_ISSUING_CA_UNTRUSTED_KDC = 0x80090359, + SEC_E_KDC_CERT_EXPIRED = 0x8009035A, + SEC_E_KDC_CERT_REVOKED = 0x8009035B, + SEC_E_INVALID_PARAMETER = 0x8009035D, + SEC_E_DELEGATION_POLICY = 0x8009035E, + SEC_E_POLICY_NLTM_ONLY = 0x8009035F, + SEC_E_NO_CONTEXT = 0x80090361, + SEC_E_PKU2U_CERT_FAILURE = 0x80090362, + SEC_E_MUTUAL_AUTH_FAILED = 0x80090363, + SEC_E_ONLY_HTTPS_ALLOWED = 0x80090365, + SEC_E_APPLICATION_PROTOCOL_MISMATCH = 0x80090367, + SEC_E_INVALID_UPN_NAME = 0x80090369, + SEC_E_EXT_BUFFER_TOO_SMALL = 0x8009036A, + SEC_E_INSUFFICIENT_BUFFERS = 0x8009036B, + SEC_E_NO_SPM = SEC_E_INTERNAL_ERROR, + SEC_E_NOT_SUPPORTED = SEC_E_UNSUPPORTED_FUNCTION } -enum :SECURITY_STATUS { - SEC_I_RENEGOTIATE = 590625, - SEC_I_COMPLETE_AND_CONTINUE = 590612, - SEC_I_COMPLETE_NEEDED = 590611, - SEC_I_CONTINUE_NEEDED = 590610, - SEC_I_INCOMPLETE_CREDENTIALS = 590624, +enum : SECURITY_STATUS +{ + SEC_I_CONTINUE_NEEDED = 0x00090312, + SEC_I_COMPLETE_NEEDED = 0x00090313, + SEC_I_COMPLETE_AND_CONTINUE = 0x00090314, + SEC_I_LOCAL_LOGON = 0x00090315, + SEC_I_GENERIC_EXTENSION_RECEIVED = 0x00090316, + SEC_I_CONTEXT_EXPIRED = 0x00090317, + SEC_I_INCOMPLETE_CREDENTIALS = 0x00090320, + SEC_I_RENEGOTIATE = 0x00090321, + SEC_I_NO_LSA_CONTEXT = 0x00090323, + SEC_I_SIGNATURE_NEEDED = 0x0009035C, + SEC_I_NO_RENEGOTIATION = 0x00090360, + SEC_I_MESSAGE_FRAGMENT = 0x00090364, + SEC_I_CONTINUE_NEEDED_MESSAGE_OK = 0x00090366, + SEC_I_ASYNC_CALL_PENDING = 0x00090368, } /* always a char */ -alias char SEC_CHAR; -alias wchar SEC_WCHAR; - -alias int SECURITY_STATUS; +alias SEC_CHAR = char; +alias SEC_WCHAR = wchar; +alias SECURITY_STATUS = int; diff --git a/libphobos/libdruntime/core/sys/windows/servprov.d b/libphobos/libdruntime/core/sys/windows/servprov.d index 91a0a118453..1c061dd8746 100644 --- a/libphobos/libdruntime/core/sys/windows/servprov.d +++ b/libphobos/libdruntime/core/sys/windows/servprov.d @@ -8,8 +8,9 @@ */ module core.sys.windows.servprov; version (Windows): +@system: -private import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; +import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; interface IServiceProvider : IUnknown { HRESULT QueryService(REFGUID, REFIID, void**); diff --git a/libphobos/libdruntime/core/sys/windows/setupapi.d b/libphobos/libdruntime/core/sys/windows/setupapi.d index 8df96b16353..432ff354642 100644 --- a/libphobos/libdruntime/core/sys/windows/setupapi.d +++ b/libphobos/libdruntime/core/sys/windows/setupapi.d @@ -9,13 +9,14 @@ */ module core.sys.windows.setupapi; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "setupapi"); -private import core.sys.windows.basetyps, core.sys.windows.commctrl, core.sys.windows.prsht, core.sys.windows.w32api, +import core.sys.windows.basetyps, core.sys.windows.commctrl, core.sys.windows.prsht, core.sys.windows.w32api, core.sys.windows.winreg, core.sys.windows.windef; -private import core.sys.windows.winbase; // for SYSTEMTIME +import core.sys.windows.winbase; // for SYSTEMTIME /*static if (_WIN32_WINNT < _WIN32_WINDOWS) { enum UINT _SETUPAPI_VER = _WIN32_WINNT; // SetupAPI version follows Windows NT version diff --git a/libphobos/libdruntime/core/sys/windows/shellapi.d b/libphobos/libdruntime/core/sys/windows/shellapi.d index 26c6f78c404..2b7f1456d22 100644 --- a/libphobos/libdruntime/core/sys/windows/shellapi.d +++ b/libphobos/libdruntime/core/sys/windows/shellapi.d @@ -9,11 +9,12 @@ */ module core.sys.windows.shellapi; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "shell32"); -private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.basetyps; +import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.basetyps; enum : UINT { ABE_LEFT, diff --git a/libphobos/libdruntime/core/sys/windows/shldisp.d b/libphobos/libdruntime/core/sys/windows/shldisp.d index 876d4d784ef..70cf88428c7 100644 --- a/libphobos/libdruntime/core/sys/windows/shldisp.d +++ b/libphobos/libdruntime/core/sys/windows/shldisp.d @@ -8,8 +8,9 @@ */ module core.sys.windows.shldisp; version (Windows): +@system: -private import core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; +import core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; // options for IAutoComplete2 enum DWORD ACO_AUTOSUGGEST = 0x01; diff --git a/libphobos/libdruntime/core/sys/windows/shlguid.d b/libphobos/libdruntime/core/sys/windows/shlguid.d index e2bbf020af8..15e6138b2f4 100644 --- a/libphobos/libdruntime/core/sys/windows/shlguid.d +++ b/libphobos/libdruntime/core/sys/windows/shlguid.d @@ -8,8 +8,9 @@ */ module core.sys.windows.shlguid; version (Windows): +@system: -private import core.sys.windows.basetyps, core.sys.windows.w32api; +import core.sys.windows.basetyps, core.sys.windows.w32api; // FIXME: clean up Windows version support diff --git a/libphobos/libdruntime/core/sys/windows/shlobj.d b/libphobos/libdruntime/core/sys/windows/shlobj.d index 19b4426edf7..5f921b3ca1a 100644 --- a/libphobos/libdruntime/core/sys/windows/shlobj.d +++ b/libphobos/libdruntime/core/sys/windows/shlobj.d @@ -8,6 +8,7 @@ */ module core.sys.windows.shlobj; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "shell32"); @@ -17,10 +18,10 @@ pragma(lib, "shell32"); // SHGetFolderPath in shfolder.dll on W9x, NT4, also in shell32.dll on W2K import core.sys.windows.commctrl, core.sys.windows.ole2, core.sys.windows.shlguid, core.sys.windows.shellapi; -private import core.sys.windows.prsht, core.sys.windows.unknwn, core.sys.windows.w32api, core.sys.windows.winbase, +import core.sys.windows.prsht, core.sys.windows.unknwn, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.winnt, core.sys.windows.winuser, core.sys.windows.wtypes, core.sys.windows.objfwd, core.sys.windows.objidl; -private import core.sys.windows.winnetwk; // for NETRESOURCE -private import core.sys.windows.oaidl : VARIANT; +import core.sys.windows.winnetwk; // for NETRESOURCE +import core.sys.windows.oaidl : VARIANT; // FIXME: clean up Windows version support @@ -691,7 +692,7 @@ alias IContextMenu LPCONTEXTMENU; interface IContextMenu2 : IContextMenu { HRESULT HandleMenuMsg(UINT, WPARAM, LPARAM); -}; +} alias IContextMenu2 LPCONTEXTMENU2; static if (_WIN32_IE >= 0x500) { @@ -770,7 +771,7 @@ alias IShellPropSheetExt LPSHELLPROPSHEETEXT; interface IExtractIconA : IUnknown { HRESULT GetIconLocation(UINT, LPSTR, UINT, int*, PUINT); HRESULT Extract(LPCSTR, UINT, HICON*, HICON*, UINT); -}; +} alias IExtractIconA LPEXTRACTICONA; interface IExtractIconW : IUnknown { @@ -855,16 +856,6 @@ interface IEnumExtraSearch: IUnknown { alias IEnumExtraSearch LPENUMEXTRASEARCH; interface IShellFolder2 : IShellFolder { - HRESULT ParseDisplayName(HWND, LPBC, LPOLESTR, PULONG, LPITEMIDLIST*, PULONG); - HRESULT EnumObjects(HWND, DWORD, LPENUMIDLIST*); - HRESULT BindToObject(LPCITEMIDLIST, LPBC, REFIID, PVOID*); - HRESULT BindToStorage(LPCITEMIDLIST, LPBC, REFIID, PVOID*); - HRESULT CompareIDs(LPARAM, LPCITEMIDLIST, LPCITEMIDLIST); - HRESULT CreateViewObject(HWND, REFIID, PVOID*); - HRESULT GetAttributesOf(UINT, LPCITEMIDLIST*, PULONG); - HRESULT GetUIObjectOf(HWND, UINT, LPCITEMIDLIST*, REFIID, PUINT, PVOID*); - HRESULT GetDisplayNameOf(LPCITEMIDLIST, DWORD, LPSTRRET); - HRESULT SetNameOf(HWND, LPCITEMIDLIST, LPCOLESTR, DWORD, LPITEMIDLIST*); HRESULT GetDefaultSearchGUID(GUID*); HRESULT EnumSearches(IEnumExtraSearch*); HRESULT GetDefaultColumn(DWORD, ULONG*, ULONG*); diff --git a/libphobos/libdruntime/core/sys/windows/shlwapi.d b/libphobos/libdruntime/core/sys/windows/shlwapi.d index 64e97963c84..8cb21ef4a4a 100644 --- a/libphobos/libdruntime/core/sys/windows/shlwapi.d +++ b/libphobos/libdruntime/core/sys/windows/shlwapi.d @@ -8,6 +8,7 @@ */ module core.sys.windows.shlwapi; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "shlwapi"); @@ -27,7 +28,7 @@ wnsprintf functions are not included. */ import core.sys.windows.objbase, core.sys.windows.shlobj; -private import core.sys.windows.basetyps, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.windef, +import core.sys.windows.basetyps, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.winbase, core.sys.windows.winreg; enum DLLVER_PLATFORM_WINDOWS = 0x00000001; diff --git a/libphobos/libdruntime/core/sys/windows/snmp.d b/libphobos/libdruntime/core/sys/windows/snmp.d index 4f550184d0a..ea64e0d86b5 100644 --- a/libphobos/libdruntime/core/sys/windows/snmp.d +++ b/libphobos/libdruntime/core/sys/windows/snmp.d @@ -9,10 +9,11 @@ */ module core.sys.windows.snmp; version (Windows): +@system: -private import core.sys.windows.basetsd /+: HANDLE+/; -private import core.sys.windows.windef /+: BOOL, BYTE, DWORD, INT, LONG, UINT, ULONG+/; -private import core.sys.windows.winnt /+: LPSTR, LPVOID, ULARGE_INTEGER, VOID+/; +import core.sys.windows.basetsd /+: HANDLE+/; +import core.sys.windows.windef /+: BOOL, BYTE, DWORD, INT, LONG, UINT, ULONG+/; +import core.sys.windows.winnt /+: LPSTR, LPVOID, ULARGE_INTEGER, VOID+/; // These are not documented on MSDN enum { diff --git a/libphobos/libdruntime/core/sys/windows/sql.d b/libphobos/libdruntime/core/sys/windows/sql.d index 4eb2cfb514e..177a48dc0c3 100644 --- a/libphobos/libdruntime/core/sys/windows/sql.d +++ b/libphobos/libdruntime/core/sys/windows/sql.d @@ -8,9 +8,10 @@ */ module core.sys.windows.sql; version (Windows): +@system: public import core.sys.windows.sqltypes; -private import core.sys.windows.windef; +import core.sys.windows.windef; enum ODBCVER = 0x0351; diff --git a/libphobos/libdruntime/core/sys/windows/sqlext.d b/libphobos/libdruntime/core/sys/windows/sqlext.d index 842f721205b..3acfc5aa70c 100644 --- a/libphobos/libdruntime/core/sys/windows/sqlext.d +++ b/libphobos/libdruntime/core/sys/windows/sqlext.d @@ -8,6 +8,7 @@ */ module core.sys.windows.sqlext; version (Windows): +@system: /* Conversion notes: The MinGW file was a horrible mess. All of the #defines were sorted alphabetically, @@ -17,7 +18,7 @@ version (Windows): */ public import core.sys.windows.sql; -private import core.sys.windows.windef; +import core.sys.windows.windef; enum SQL_SPEC_MAJOR = 3; enum SQL_SPEC_MINOR = 51; diff --git a/libphobos/libdruntime/core/sys/windows/sqltypes.d b/libphobos/libdruntime/core/sys/windows/sqltypes.d index 288b20eeede..aaffeb22585 100644 --- a/libphobos/libdruntime/core/sys/windows/sqltypes.d +++ b/libphobos/libdruntime/core/sys/windows/sqltypes.d @@ -8,6 +8,7 @@ */ module core.sys.windows.sqltypes; version (Windows): +@system: version (ANSI) {} else version = Unicode; @@ -15,8 +16,8 @@ version (ANSI) {} else version = Unicode; It's assumed that ODBC >= 0x0300. */ -private import core.sys.windows.windef; -private import core.sys.windows.basetyps; // for GUID +import core.sys.windows.windef; +import core.sys.windows.basetyps; // for GUID alias byte SCHAR, SQLSCHAR; alias int SDWORD, SLONG, SQLINTEGER; diff --git a/libphobos/libdruntime/core/sys/windows/sqlucode.d b/libphobos/libdruntime/core/sys/windows/sqlucode.d index 6a5a48c73db..21f47f6f54e 100644 --- a/libphobos/libdruntime/core/sys/windows/sqlucode.d +++ b/libphobos/libdruntime/core/sys/windows/sqlucode.d @@ -8,10 +8,11 @@ */ module core.sys.windows.sqlucode; version (Windows): +@system: version (ANSI) {} else version = Unicode; -private import core.sys.windows.sqlext; +import core.sys.windows.sqlext; enum SQL_WCHAR = -8; enum SQL_WVARCHAR = -9; diff --git a/libphobos/libdruntime/core/sys/windows/sspi.d b/libphobos/libdruntime/core/sys/windows/sspi.d index 9f72368668a..cf41298a631 100644 --- a/libphobos/libdruntime/core/sys/windows/sspi.d +++ b/libphobos/libdruntime/core/sys/windows/sspi.d @@ -9,6 +9,7 @@ */ module core.sys.windows.sspi; version (Windows): +@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/stacktrace.d b/libphobos/libdruntime/core/sys/windows/stacktrace.d index d354ffecfe3..2922e54ebae 100644 --- a/libphobos/libdruntime/core/sys/windows/stacktrace.d +++ b/libphobos/libdruntime/core/sys/windows/stacktrace.d @@ -11,9 +11,9 @@ module core.sys.windows.stacktrace; version (Windows): +@system: import core.demangle; -import core.runtime; import core.stdc.stdlib; import core.stdc.string; import core.sys.windows.dbghelp; @@ -217,11 +217,6 @@ private: // do ... while so that we don't skip the first stackframe do { - if ( stackframe.AddrPC.Offset == stackframe.AddrReturn.Offset ) - { - debug(PRINTF) printf("Endless callstack\n"); - break; - } if (frameNum >= skip) { result ~= stackframe.AddrPC.Offset; @@ -255,26 +250,23 @@ private: char[][] trace; foreach (pc; addresses) { - if ( pc != 0 ) + char[] res; + if (dbghelp.SymGetSymFromAddr64(hProcess, pc, null, symbol) && + *symbol.Name.ptr) { - char[] res; - if (dbghelp.SymGetSymFromAddr64(hProcess, pc, null, symbol) && - *symbol.Name.ptr) - { - DWORD disp; - IMAGEHLP_LINEA64 line=void; - line.SizeOfStruct = IMAGEHLP_LINEA64.sizeof; - - if (dbghelp.SymGetLineFromAddr64(hProcess, pc, &disp, &line)) - res = formatStackFrame(cast(void*)pc, symbol.Name.ptr, - line.FileName, line.LineNumber); - else - res = formatStackFrame(cast(void*)pc, symbol.Name.ptr); - } + DWORD disp; + IMAGEHLP_LINEA64 line=void; + line.SizeOfStruct = IMAGEHLP_LINEA64.sizeof; + + if (dbghelp.SymGetLineFromAddr64(hProcess, pc, &disp, &line)) + res = formatStackFrame(cast(void*)pc, symbol.Name.ptr, + line.FileName, line.LineNumber); else - res = formatStackFrame(cast(void*)pc); - trace ~= res; + res = formatStackFrame(cast(void*)pc, symbol.Name.ptr); } + else + res = formatStackFrame(cast(void*)pc); + trace ~= res; } return trace; } @@ -307,7 +299,7 @@ private: } static char[] formatStackFrame(void* pc, char* symName, - in char* fileName, uint lineNum) + const scope char* fileName, uint lineNum) { import core.stdc.stdio : snprintf; char[11] buf=void; diff --git a/libphobos/libdruntime/core/sys/windows/stat.d b/libphobos/libdruntime/core/sys/windows/stat.d index 03d219b1100..c9ee6ce5ca8 100644 --- a/libphobos/libdruntime/core/sys/windows/stat.d +++ b/libphobos/libdruntime/core/sys/windows/stat.d @@ -6,6 +6,7 @@ module core.sys.windows.stat; version (Windows): extern (C) nothrow @nogc: +@system: // Posix version is in core.sys.posix.sys.stat diff --git a/libphobos/libdruntime/core/sys/windows/stdc/time.d b/libphobos/libdruntime/core/sys/windows/stdc/time.d new file mode 100644 index 00000000000..97eb4bf1e11 --- /dev/null +++ b/libphobos/libdruntime/core/sys/windows/stdc/time.d @@ -0,0 +1,59 @@ +/** + * D header file for C99. + * + * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_time.h.html, _time.h) + * + * Copyright: Copyright Sean Kelly 2005 - 2009. + * License: Distributed under the + * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). + * (See accompanying file LICENSE) + * Authors: Sean Kelly, + * Alex Rønne Petersen + * Source: $(DRUNTIMESRC core/stdc/_time.d) + * Standards: ISO/IEC 9899:1999 (E) + */ + +module core.sys.windows.stdc.time; + +version (Windows): + +import core.stdc.config; + +extern (C): +@trusted: // There are only a few functions here that use unsafe C strings. +nothrow: +@nogc: + +/// +struct tm +{ + int tm_sec; /// seconds after the minute - [0, 60] + int tm_min; /// minutes after the hour - [0, 59] + int tm_hour; /// hours since midnight - [0, 23] + int tm_mday; /// day of the month - [1, 31] + int tm_mon; /// months since January - [0, 11] + int tm_year; /// years since 1900 + int tm_wday; /// days since Sunday - [0, 6] + int tm_yday; /// days since January 1 - [0, 365] + int tm_isdst; /// Daylight Saving Time flag +} + +/// +alias c_long time_t; +/// +alias c_long clock_t; + +enum clock_t CLOCKS_PER_SEC = 1000; +clock_t clock(); + +/// +void tzset(); // non-standard +/// +void _tzset(); // non-standard +/// +@system char* _strdate(return scope char* s); // non-standard +/// +@system char* _strtime(return scope char* s); // non-standard + +/// +extern __gshared const(char)*[2] tzname; // non-standard diff --git a/libphobos/libdruntime/core/sys/windows/subauth.d b/libphobos/libdruntime/core/sys/windows/subauth.d index 9d39a90619a..42d2fa73cf8 100644 --- a/libphobos/libdruntime/core/sys/windows/subauth.d +++ b/libphobos/libdruntime/core/sys/windows/subauth.d @@ -8,8 +8,9 @@ */ module core.sys.windows.subauth; version (Windows): +@system: -private import core.sys.windows.ntdef, core.sys.windows.windef; +import core.sys.windows.ntdef, core.sys.windows.windef; /+ alias LONG NTSTATUS; diff --git a/libphobos/libdruntime/core/sys/windows/threadaux.d b/libphobos/libdruntime/core/sys/windows/threadaux.d index e3bdd400668..fb4d1ee64ba 100644 --- a/libphobos/libdruntime/core/sys/windows/threadaux.d +++ b/libphobos/libdruntime/core/sys/windows/threadaux.d @@ -14,6 +14,7 @@ */ module core.sys.windows.threadaux; version (Windows): +@system: import core.sys.windows.basetsd/+ : HANDLE+/; import core.sys.windows.winbase/+ : CloseHandle, GetCurrentThreadId, GetCurrentProcessId, diff --git a/libphobos/libdruntime/core/sys/windows/tlhelp32.d b/libphobos/libdruntime/core/sys/windows/tlhelp32.d index 3a3959f8deb..308c5a46cc1 100644 --- a/libphobos/libdruntime/core/sys/windows/tlhelp32.d +++ b/libphobos/libdruntime/core/sys/windows/tlhelp32.d @@ -8,11 +8,12 @@ */ module core.sys.windows.tlhelp32; version (Windows): +@system: pragma(lib, "kernel32"); version (ANSI) {} else version = Unicode; -private import core.sys.windows.windef; +import core.sys.windows.windef; enum : uint { HF32_DEFAULT = 1, diff --git a/libphobos/libdruntime/core/sys/windows/tmschema.d b/libphobos/libdruntime/core/sys/windows/tmschema.d index ad62d0e40b3..ea7863a97b6 100644 --- a/libphobos/libdruntime/core/sys/windows/tmschema.d +++ b/libphobos/libdruntime/core/sys/windows/tmschema.d @@ -8,6 +8,7 @@ */ module core.sys.windows.tmschema; version (Windows): +@system: /* BUTTON parts */ enum { diff --git a/libphobos/libdruntime/core/sys/windows/unknwn.d b/libphobos/libdruntime/core/sys/windows/unknwn.d index 8bcbc3c6074..1c3e4539f01 100644 --- a/libphobos/libdruntime/core/sys/windows/unknwn.d +++ b/libphobos/libdruntime/core/sys/windows/unknwn.d @@ -8,9 +8,10 @@ */ module core.sys.windows.unknwn; version (Windows): +@system: import core.sys.windows.objfwd, core.sys.windows.windef, core.sys.windows.wtypes; -private import core.sys.windows.basetyps; +import core.sys.windows.basetyps; extern (Windows) { void* MIDL_user_allocate(size_t); diff --git a/libphobos/libdruntime/core/sys/windows/uuid.d b/libphobos/libdruntime/core/sys/windows/uuid.d index d3b979dac89..7e8d4b9b7e0 100644 --- a/libphobos/libdruntime/core/sys/windows/uuid.d +++ b/libphobos/libdruntime/core/sys/windows/uuid.d @@ -1,5 +1,6 @@ module core.sys.windows.uuid; version (Windows): +@system: import core.sys.windows.basetyps; diff --git a/libphobos/libdruntime/core/sys/windows/vfw.d b/libphobos/libdruntime/core/sys/windows/vfw.d index 4d168b38a86..3ffff201347 100644 --- a/libphobos/libdruntime/core/sys/windows/vfw.d +++ b/libphobos/libdruntime/core/sys/windows/vfw.d @@ -9,6 +9,7 @@ module core.sys.windows.vfw; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "vfw32"); diff --git a/libphobos/libdruntime/core/sys/windows/w32api.d b/libphobos/libdruntime/core/sys/windows/w32api.d index 33807c9daa7..a392d591a4c 100644 --- a/libphobos/libdruntime/core/sys/windows/w32api.d +++ b/libphobos/libdruntime/core/sys/windows/w32api.d @@ -9,6 +9,7 @@ */ module core.sys.windows.w32api; version (Windows): +@system: version (ANSI) {} else version = Unicode; @@ -24,7 +25,7 @@ enum __W32API_MINOR_VERSION = 17; * removed in order to simplify the bindings. */ version (Windows10) { - enum uint _WIN32_WINNT = 0x604; + enum uint _WIN32_WINNT = 0xA00; } else version (Windows8_1) { // also Windows2012R2 enum uint _WIN32_WINNT = 0x603; } else version (Windows8) { // also Windows2012 @@ -45,7 +46,9 @@ enum __W32API_MINOR_VERSION = 17; enum uint _WIN32_WINNT = 0x501; } -version (IE10) { +version (IE11) { + enum uint _WIN32_IE = 0xA00; +} else version (IE10) { enum uint _WIN32_IE = 0xA00; } else version (IE9) { enum uint _WIN32_IE = 0x900; @@ -61,6 +64,8 @@ version (IE10) { enum uint _WIN32_IE = 0x600; } else version (IE56) { enum uint _WIN32_IE = 0x560; +} else version (IE55) { + enum uint _WIN32_IE = 0x550; } else version (IE501) { enum uint _WIN32_IE = 0x501; } else version (IE5) { @@ -71,6 +76,8 @@ version (IE10) { enum uint _WIN32_IE = 0x400; } else version (IE3) { enum uint _WIN32_IE = 0x300; +} else static if (_WIN32_WINNT >= 0x500) { + enum uint _WIN32_IE = 0x600; } else static if (_WIN32_WINNT >= 0x410) { enum uint _WIN32_IE = 0x400; } else { diff --git a/libphobos/libdruntime/core/sys/windows/winbase.d b/libphobos/libdruntime/core/sys/windows/winbase.d index 280c4684b33..a9844de450b 100644 --- a/libphobos/libdruntime/core/sys/windows/winbase.d +++ b/libphobos/libdruntime/core/sys/windows/winbase.d @@ -8,6 +8,7 @@ */ module core.sys.windows.winbase; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "kernel32"); @@ -33,7 +34,7 @@ int wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); */ import core.sys.windows.windef, core.sys.windows.winver; -private import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winnt; +import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winnt; // FIXME: //alias void va_list; @@ -1285,9 +1286,17 @@ struct WIN32_STREAM_ID { } alias WIN32_STREAM_ID* LPWIN32_STREAM_ID; -enum FINDEX_INFO_LEVELS { - FindExInfoStandard, - FindExInfoMaxInfoLevel +static if (_WIN32_WINNT >= 0x601) { + enum FINDEX_INFO_LEVELS { + FindExInfoStandard, + FindExInfoBasic, + FindExInfoMaxInfoLevel, + } +} else { + enum FINDEX_INFO_LEVELS { + FindExInfoStandard, + FindExInfoMaxInfoLevel, + } } enum FINDEX_SEARCH_OPS { @@ -1581,6 +1590,14 @@ static if (_WIN32_WINNT >= 0x410) { alias DWORD EXECUTION_STATE; } +// CreateSymbolicLink +static if (_WIN32_WINNT >= 0x600) { + enum { + SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1, + SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2 + } +} + // Callbacks extern (Windows) { alias DWORD function(LPVOID) LPTHREAD_START_ROUTINE; @@ -2242,6 +2259,7 @@ WINBASEAPI BOOL WINAPI SetEvent(HANDLE); BOOL IsValidAcl(PACL); BOOL IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR); BOOL IsValidSid(PSID); + BOOL CreateWellKnownSid(WELL_KNOWN_SID_TYPE, PSID, PSID, PDWORD); BOOL LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED); BOOL LogonUserA(LPSTR, LPSTR, LPSTR, DWORD, DWORD, PHANDLE); BOOL LogonUserW(LPWSTR, LPWSTR, LPWSTR, DWORD, DWORD, PHANDLE); @@ -2471,6 +2489,11 @@ WINBASEAPI BOOL WINAPI SetEvent(HANDLE); static if (_WIN32_WINNT >= 0x510) { VOID RestoreLastError(DWORD); } + + static if (_WIN32_WINNT >= 0x600) { + BOOL CreateSymbolicLinkA(LPCSTR, LPCSTR, DWORD); + BOOL CreateSymbolicLinkW(LPCWSTR, LPCWSTR, DWORD); + } } // For compatibility with old core.sys.windows.windows: @@ -2656,6 +2679,10 @@ version (Unicode) { alias GetDllDirectoryW GetDllDirectory; } + static if (_WIN32_WINNT >= 0x600) { + alias CreateSymbolicLinkW CreateSymbolicLink; + } + } else { //alias STARTUPINFOA STARTUPINFO; alias WIN32_FIND_DATAA WIN32_FIND_DATA; @@ -2830,6 +2857,10 @@ version (Unicode) { alias SetDllDirectoryA SetDllDirectory; alias SetFirmwareEnvironmentVariableA SetFirmwareEnvironmentVariable; } + + static if (_WIN32_WINNT >= 0x600) { + alias CreateSymbolicLinkA CreateSymbolicLink; + } } alias STARTUPINFO* LPSTARTUPINFO; diff --git a/libphobos/libdruntime/core/sys/windows/winber.d b/libphobos/libdruntime/core/sys/windows/winber.d index 9ff3231b208..27189038826 100644 --- a/libphobos/libdruntime/core/sys/windows/winber.d +++ b/libphobos/libdruntime/core/sys/windows/winber.d @@ -9,6 +9,7 @@ */ module core.sys.windows.winber; version (Windows): +@system: /* Comment from MinGW winber.h - Header file for the Windows LDAP Basic Encoding Rules API diff --git a/libphobos/libdruntime/core/sys/windows/wincon.d b/libphobos/libdruntime/core/sys/windows/wincon.d index 6b06c14b166..67bd17e7d09 100644 --- a/libphobos/libdruntime/core/sys/windows/wincon.d +++ b/libphobos/libdruntime/core/sys/windows/wincon.d @@ -8,11 +8,12 @@ */ module core.sys.windows.wincon; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "kernel32"); -private import core.sys.windows.w32api, core.sys.windows.windef; +import core.sys.windows.w32api, core.sys.windows.windef; // FIXME: clean up Windows version support diff --git a/libphobos/libdruntime/core/sys/windows/wincrypt.d b/libphobos/libdruntime/core/sys/windows/wincrypt.d index 0651ea803cf..94951057e68 100644 --- a/libphobos/libdruntime/core/sys/windows/wincrypt.d +++ b/libphobos/libdruntime/core/sys/windows/wincrypt.d @@ -9,11 +9,12 @@ */ module core.sys.windows.wincrypt; version (Windows): +@system: pragma(lib, "advapi32"); version (ANSI) {} else version = Unicode; -private import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef; +import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef; /* FIXME: * Types of some constants diff --git a/libphobos/libdruntime/core/sys/windows/windef.d b/libphobos/libdruntime/core/sys/windows/windef.d index 25cf0440657..f79b593c518 100644 --- a/libphobos/libdruntime/core/sys/windows/windef.d +++ b/libphobos/libdruntime/core/sys/windows/windef.d @@ -9,9 +9,10 @@ */ module core.sys.windows.windef; version (Windows): +@system: public import core.sys.windows.winnt; -private import core.sys.windows.w32api; +import core.sys.windows.w32api; enum size_t MAX_PATH = 260; diff --git a/libphobos/libdruntime/core/sys/windows/windows.d b/libphobos/libdruntime/core/sys/windows/windows.d index 85dc5f43e84..8b8c8ab3554 100644 --- a/libphobos/libdruntime/core/sys/windows/windows.d +++ b/libphobos/libdruntime/core/sys/windows/windows.d @@ -8,6 +8,7 @@ */ module core.sys.windows.windows; version (Windows): +@system: /* windows.h - main header file for the Win32 API diff --git a/libphobos/libdruntime/core/sys/windows/winerror.d b/libphobos/libdruntime/core/sys/windows/winerror.d index 71a2f98dacc..ab987a3e81a 100644 --- a/libphobos/libdruntime/core/sys/windows/winerror.d +++ b/libphobos/libdruntime/core/sys/windows/winerror.d @@ -8,12 +8,13 @@ */ module core.sys.windows.winerror; version (Windows): +@system: /* Comments from the Mingw header: * WAIT_TIMEOUT is also defined in winbase.h */ -private import core.sys.windows.windef; +import core.sys.windows.windef; alias int SCODE; // was in core.sys.windows.wtypes. diff --git a/libphobos/libdruntime/core/sys/windows/wingdi.d b/libphobos/libdruntime/core/sys/windows/wingdi.d index e495b2be84f..4fc125c6225 100644 --- a/libphobos/libdruntime/core/sys/windows/wingdi.d +++ b/libphobos/libdruntime/core/sys/windows/wingdi.d @@ -8,13 +8,14 @@ */ module core.sys.windows.wingdi; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "gdi32"); // FIXME: clean up Windows version support -private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver; +import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver; // BITMAPINFOHEADER.biCompression enum : DWORD { @@ -2057,13 +2058,13 @@ struct RGBQUAD { BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; -}; +} alias RGBQUAD* LPRGBQUAD; struct BITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD[1] bmiColors; -}; +} alias BITMAPINFO* PBITMAPINFO, LPBITMAPINFO; alias int FXPT16DOT16; diff --git a/libphobos/libdruntime/core/sys/windows/winhttp.d b/libphobos/libdruntime/core/sys/windows/winhttp.d index a7a343f3890..e919635e4ed 100644 --- a/libphobos/libdruntime/core/sys/windows/winhttp.d +++ b/libphobos/libdruntime/core/sys/windows/winhttp.d @@ -8,6 +8,7 @@ */ module core.sys.windows.winhttp; version (Windows): +@system: pragma(lib, "winhttp"); // FIXME: Grouping of constants. Windows SDK doesn't make this entirely clear // FIXME: Verify WINHTTP_STATUS_CALLBACK function declaration works correctly diff --git a/libphobos/libdruntime/core/sys/windows/wininet.d b/libphobos/libdruntime/core/sys/windows/wininet.d index 231c31a0e06..64b95c4c00e 100644 --- a/libphobos/libdruntime/core/sys/windows/wininet.d +++ b/libphobos/libdruntime/core/sys/windows/wininet.d @@ -9,6 +9,7 @@ */ module core.sys.windows.wininet; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "wininet"); @@ -17,6 +18,11 @@ pragma(lib, "wininet"); import core.sys.windows.winbase, core.sys.windows.windef; +// From Winineti.h +enum { + INTERNET_FLAG_BGUPDATE = 0x00000008, +} + enum { INTERNET_INVALID_PORT_NUMBER = 0, INTERNET_DEFAULT_FTP_PORT = 21, @@ -46,8 +52,18 @@ enum : DWORD { } enum { - INTERNET_REQFLAG_FROM_CACHE = 1, - INTERNET_REQFLAG_ASYNC = 2 + INTERNET_REQFLAG_FROM_CACHE = 0x00000001, + INTERNET_REQFLAG_ASYNC = 0x00000002, + INTERNET_REQFLAG_VIA_PROXY = 0x00000004, + INTERNET_REQFLAG_NO_HEADERS = 0x00000008, + INTERNET_REQFLAG_PASSIVE = 0x00000010, + INTERNET_REQFLAG_CACHE_WRITE_DISABLED = 0x00000040, + INTERNET_REQFLAG_NET_TIMEOUT = 0x00000080, +} + +enum { + INTERNET_FLAG_IDN_DIRECT = 0x00000001, + INTERNET_FLAG_IDN_PROXY = 0x00000002 } enum DWORD @@ -59,13 +75,16 @@ enum DWORD INTERNET_FLAG_NO_CACHE_WRITE = 0x04000000, INTERNET_FLAG_DONT_CACHE = INTERNET_FLAG_NO_CACHE_WRITE, INTERNET_FLAG_MAKE_PERSISTENT = 0x02000000, - INTERNET_FLAG_OFFLINE = 0x01000000, + INTERNET_FLAG_FROM_CACHE = 0x01000000, + INTERNET_FLAG_OFFLINE = INTERNET_FLAG_FROM_CACHE, INTERNET_FLAG_SECURE = 0x00800000, INTERNET_FLAG_KEEP_CONNECTION = 0x00400000, INTERNET_FLAG_NO_AUTO_REDIRECT = 0x00200000, INTERNET_FLAG_READ_PREFETCH = 0x00100000, INTERNET_FLAG_NO_COOKIES = 0x00080000, INTERNET_FLAG_NO_AUTH = 0x00040000, + INTERNET_FLAG_RESTRICTED_ZONE = 0x00020000, + INTERNET_FLAG_CACHE_IF_NET_FAIL = 0x00010000, INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP = 0x00008000, INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS = 0x00004000, INTERNET_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000, @@ -74,14 +93,55 @@ enum DWORD INTERNET_FLAG_HYPERLINK = 0x00000400, INTERNET_FLAG_NO_UI = 0x00000200, INTERNET_FLAG_PRAGMA_NOCACHE = 0x00000100, - INTERNET_FLAG_MUST_CACHE_REQUEST = 0x00000010, + INTERNET_FLAG_CACHE_ASYNC = 0x00000080, + INTERNET_FLAG_FORMS_SUBMIT = 0x00000040, + INTERNET_FLAG_FWD_BACK = 0x00000020, + INTERNET_FLAG_NEED_FILE = 0x00000010, + INTERNET_FLAG_MUST_CACHE_REQUEST = INTERNET_FLAG_NEED_FILE, INTERNET_FLAG_TRANSFER_ASCII = FTP_TRANSFER_TYPE_ASCII, INTERNET_FLAG_TRANSFER_BINARY = FTP_TRANSFER_TYPE_BINARY, - SECURITY_INTERNET_MASK = 0x0000F000, + SECURITY_INTERNET_MASK = INTERNET_FLAG_IGNORE_CERT_CN_INVALID | + INTERNET_FLAG_IGNORE_CERT_DATE_INVALID | + INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | + INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP, + SECURITY_SET_MASK = SECURITY_INTERNET_MASK, - INTERNET_FLAGS_MASK = 0xFFFCFE13, + INTERNET_FLAGS_MASK = INTERNET_FLAG_RELOAD + | INTERNET_FLAG_RAW_DATA + | INTERNET_FLAG_EXISTING_CONNECT + | INTERNET_FLAG_ASYNC + | INTERNET_FLAG_PASSIVE + | INTERNET_FLAG_NO_CACHE_WRITE + | INTERNET_FLAG_MAKE_PERSISTENT + | INTERNET_FLAG_FROM_CACHE + | INTERNET_FLAG_SECURE + | INTERNET_FLAG_KEEP_CONNECTION + | INTERNET_FLAG_NO_AUTO_REDIRECT + | INTERNET_FLAG_READ_PREFETCH + | INTERNET_FLAG_NO_COOKIES + | INTERNET_FLAG_NO_AUTH + | INTERNET_FLAG_CACHE_IF_NET_FAIL + | SECURITY_INTERNET_MASK + | INTERNET_FLAG_RESYNCHRONIZE + | INTERNET_FLAG_HYPERLINK + | INTERNET_FLAG_NO_UI + | INTERNET_FLAG_PRAGMA_NOCACHE + | INTERNET_FLAG_CACHE_ASYNC + | INTERNET_FLAG_FORMS_SUBMIT + | INTERNET_FLAG_NEED_FILE + | INTERNET_FLAG_RESTRICTED_ZONE + | INTERNET_FLAG_TRANSFER_BINARY + | INTERNET_FLAG_TRANSFER_ASCII + | INTERNET_FLAG_FWD_BACK + | INTERNET_FLAG_BGUPDATE, + + INTERNET_ERROR_MASK_INSERT_CDROM = 0x1, + INTERNET_ERROR_MASK_COMBINED_SEC_CERT = 0x2, + INTERNET_ERROR_MASK_NEED_MSN_SSPI_PKG = 0X4, + INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY = 0x8, + INTERNET_OPTIONS_MASK = ~INTERNET_FLAGS_MASK; enum INTERNET_NO_CALLBACK = 0; @@ -122,9 +182,8 @@ enum { INTERNET_OPTION_CONTROL_RECEIVE_TIMEOUT = INTERNET_OPTION_RECEIVE_TIMEOUT, INTERNET_OPTION_DATA_SEND_TIMEOUT, INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, - INTERNET_OPTION_HANDLE_TYPE, - INTERNET_OPTION_CONTEXT_VALUE, - INTERNET_OPTION_LISTEN_TIMEOUT, + INTERNET_OPTION_HANDLE_TYPE = 9, + INTERNET_OPTION_LISTEN_TIMEOUT = 11, INTERNET_OPTION_READ_BUFFER_SIZE, INTERNET_OPTION_WRITE_BUFFER_SIZE, // = 13 INTERNET_OPTION_ASYNC_ID = 15, @@ -152,9 +211,73 @@ enum { INTERNET_OPTION_END_BROWSER_SESSION, INTERNET_OPTION_PROXY_USERNAME, INTERNET_OPTION_PROXY_PASSWORD, // = 44 - INTERNET_FIRST_OPTION = INTERNET_OPTION_CALLBACK, - // why? - INTERNET_LAST_OPTION = INTERNET_OPTION_USER_AGENT + INTERNET_OPTION_CONTEXT_VALUE = 45, + INTERNET_OPTION_CONNECT_LIMIT = 46, + INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT= 47, + INTERNET_OPTION_POLICY = 48, + INTERNET_OPTION_DISCONNECTED_TIMEOUT = 49, + INTERNET_OPTION_CONNECTED_STATE = 50, + INTERNET_OPTION_IDLE_STATE = 51, + INTERNET_OPTION_OFFLINE_SEMANTICS = 52, + INTERNET_OPTION_SECONDARY_CACHE_KEY = 53, + INTERNET_OPTION_CALLBACK_FILTER = 54, + INTERNET_OPTION_CONNECT_TIME = 55, + INTERNET_OPTION_SEND_THROUGHPUT = 56, + INTERNET_OPTION_RECEIVE_THROUGHPUT = 57, + INTERNET_OPTION_REQUEST_PRIORITY = 58, + INTERNET_OPTION_HTTP_VERSION = 59, + INTERNET_OPTION_RESET_URLCACHE_SESSION = 60, + INTERNET_OPTION_ERROR_MASK = 62, + INTERNET_OPTION_FROM_CACHE_TIMEOUT = 63, + INTERNET_OPTION_BYPASS_EDITED_ENTRY = 64, + INTERNET_OPTION_HTTP_DECODING = 65, + INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO = 67, + INTERNET_OPTION_CODEPAGE = 68, + INTERNET_OPTION_CACHE_TIMESTAMPS = 69, + INTERNET_OPTION_DISABLE_AUTODIAL = 70, + INTERNET_OPTION_MAX_CONNS_PER_SERVER = 73, + INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER= 74, + INTERNET_OPTION_PER_CONNECTION_OPTION = 75, + INTERNET_OPTION_DIGEST_AUTH_UNLOAD = 76, + INTERNET_OPTION_IGNORE_OFFLINE = 77, + INTERNET_OPTION_IDENTITY = 78, + INTERNET_OPTION_REMOVE_IDENTITY = 79, + INTERNET_OPTION_ALTER_IDENTITY = 80, + INTERNET_OPTION_SUPPRESS_BEHAVIOR = 81, + INTERNET_OPTION_AUTODIAL_MODE = 82, + INTERNET_OPTION_AUTODIAL_CONNECTION = 83, + INTERNET_OPTION_CLIENT_CERT_CONTEXT = 84, + INTERNET_OPTION_AUTH_FLAGS = 85, + INTERNET_OPTION_COOKIES_3RD_PARTY = 86, + INTERNET_OPTION_DISABLE_PASSPORT_AUTH = 87, + INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY = 88, + INTERNET_OPTION_EXEMPT_CONNECTION_LIMIT = 89, + INTERNET_OPTION_ENABLE_PASSPORT_AUTH = 90, + INTERNET_OPTION_HIBERNATE_INACTIVE_WORKER_THREADS = 91, + INTERNET_OPTION_ACTIVATE_WORKER_THREADS = 92, + INTERNET_OPTION_RESTORE_WORKER_THREAD_DEFAULTS = 93, + INTERNET_OPTION_SOCKET_SEND_BUFFER_LENGTH = 94, + INTERNET_OPTION_PROXY_SETTINGS_CHANGED = 95, + INTERNET_OPTION_DATAFILE_EXT = 96, + INTERNET_OPTION_CODEPAGE_PATH = 100, + INTERNET_OPTION_CODEPAGE_EXTRA = 101, + INTERNET_OPTION_IDN = 102, + INTERNET_OPTION_MAX_CONNS_PER_PROXY = 103, + INTERNET_OPTION_SUPPRESS_SERVER_AUTH = 104, + INTERNET_OPTION_SERVER_CERT_CHAIN_CONTEXT = 105, + INTERNET_OPTION_ENABLE_REDIRECT_CACHE_READ = 122, + INTERNET_OPTION_COMPRESSED_CONTENT_LENGTH = 147, + INTERNET_OPTION_ENABLE_HTTP_PROTOCOL = 148, + INTERNET_OPTION_HTTP_PROTOCOL_USED = 149, + INTERNET_OPTION_ENCODE_EXTRA = 155, + INTERNET_OPTION_HSTS = 157, + INTERNET_OPTION_ENTERPRISE_CONTEXT = 159, + INTERNET_OPTION_CONNECTION_FILTER = 162, + INTERNET_OPTION_REFERER_TOKEN_BINDING_HOSTNAME = 163, + INTERNET_OPTION_TOKEN_BINDING_PUBLIC_KEY = 181, + INTERNET_OPTION_COOKIES_SAME_SITE_LEVEL = 187, + INTERNET_FIRST_OPTION = INTERNET_OPTION_CALLBACK, + INTERNET_LAST_OPTION = INTERNET_OPTION_COOKIES_SAME_SITE_LEVEL, } enum INTERNET_PRIORITY_FOREGROUND = 1000; @@ -641,8 +764,11 @@ enum INTERNET_SCHEME { INTERNET_SCHEME_NEWS, INTERNET_SCHEME_MAILTO, INTERNET_SCHEME_SOCKS, + INTERNET_SCHEME_JAVASCRIPT, + INTERNET_SCHEME_VBSCRIPT, + INTERNET_SCHEME_RES, INTERNET_SCHEME_FIRST = INTERNET_SCHEME_FTP, - INTERNET_SCHEME_LAST = INTERNET_SCHEME_SOCKS + INTERNET_SCHEME_LAST = INTERNET_SCHEME_RES } alias INTERNET_SCHEME* LPINTERNET_SCHEME; @@ -652,6 +778,14 @@ struct INTERNET_ASYNC_RESULT { } alias INTERNET_ASYNC_RESULT* LPINTERNET_ASYNC_RESULT; +struct INTERNET_DIAGNOSTIC_SOCKET_INFO { + DWORD_PTR Socket; + DWORD SourcePort; + DWORD DestPort; + DWORD Flags; +} +alias INTERNET_DIAGNOSTIC_SOCKET_INFO* LPINTERNET_DIAGNOSTIC_SOCKET_INFO; + struct INTERNET_PREFETCH_STATUS { DWORD dwStatus; DWORD dwSize; @@ -665,6 +799,74 @@ struct INTERNET_PROXY_INFO { } alias INTERNET_PROXY_INFO* LPINTERNET_PROXY_INFO; +struct INTERNET_PER_CONN_OPTIONA { + DWORD dwOption; + union { + DWORD dwValue; + LPSTR pszValue; + FILETIME ftValue; + } +} +alias INTERNET_PER_CONN_OPTIONA* LPINTERNET_PER_CONN_OPTIONA; + +struct INTERNET_PER_CONN_OPTIONW { + DWORD dwOption; + union { + DWORD dwValue; + LPWSTR pszValue; + FILETIME ftValue; + } +} +alias INTERNET_PER_CONN_OPTIONW* LPINTERNET_PER_CONN_OPTIONW; + +struct INTERNET_PER_CONN_OPTION_LISTA { + DWORD dwSize; + LPSTR pszConnection; + DWORD dwOptionCount; + DWORD dwOptionError; + LPINTERNET_PER_CONN_OPTIONA pOptions; +} +alias INTERNET_PER_CONN_OPTION_LISTA* LPINTERNET_PER_CONN_OPTION_LISTA; + +struct INTERNET_PER_CONN_OPTION_LISTW { + DWORD dwSize; + LPWSTR pszConnection; + DWORD dwOptionCount; + DWORD dwOptionError; + LPINTERNET_PER_CONN_OPTIONW pOptions; +} +alias INTERNET_PER_CONN_OPTION_LISTW* LPINTERNET_PER_CONN_OPTION_LISTW; + +enum { + INTERNET_PER_CONN_FLAGS = 1, + INTERNET_PER_CONN_PROXY_SERVER = 2, + INTERNET_PER_CONN_PROXY_BYPASS = 3, + INTERNET_PER_CONN_AUTOCONFIG_URL = 4, + INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5, + INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL = 6, + INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS = 7, + INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME = 8, + INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL = 9, + INTERNET_PER_CONN_FLAGS_UI = 10, +} + +enum { + PROXY_TYPE_DIRECT = 0x00000001, + PROXY_TYPE_PROXY = 0x00000002, + PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, + PROXY_TYPE_AUTO_DETECT = 0x00000008, +} + +enum { + AUTO_PROXY_FLAG_USER_SET = 0x00000001, + AUTO_PROXY_FLAG_ALWAYS_DETECT = 0x00000002, + AUTO_PROXY_FLAG_DETECTION_RUN = 0x00000004, + AUTO_PROXY_FLAG_MIGRATED = 0x00000008, + AUTO_PROXY_FLAG_DONT_CACHE_PROXY_RESULT = 0x00000010, + AUTO_PROXY_FLAG_CACHE_INIT_RUN = 0x00000020, + AUTO_PROXY_FLAG_DETECTION_SUSPECT = 0x00000040, +} + struct INTERNET_VERSION_INFO { DWORD dwMajorVersion; DWORD dwMinorVersion; @@ -1129,6 +1331,10 @@ extern (Windows) { } version (Unicode) { + alias INTERNET_PER_CONN_OPTIONW INTERNET_PER_CONN_OPTION; + alias LPINTERNET_PER_CONN_OPTIONW LPINTERNET_PER_CONN_OPTION; + alias INTERNET_PER_CONN_OPTION_LISTW INTERNET_PER_CONN_OPTION_LIST; + alias LPINTERNET_PER_CONN_OPTION_LISTW LPINTERNET_PER_CONN_OPTION_LIST; alias URL_COMPONENTSW URL_COMPONENTS; alias LPURL_COMPONENTSW LPURL_COMPONENTS; alias GOPHER_FIND_DATAW GOPHER_FIND_DATA; @@ -1187,6 +1393,10 @@ version (Unicode) { alias GetUrlCacheGroupAttributeW GetUrlCacheGroupAttribute; alias SetUrlCacheGroupAttributeW SetUrlCacheGroupAttribute; } else { + alias INTERNET_PER_CONN_OPTIONA INTERNET_PER_CONN_OPTION; + alias LPINTERNET_PER_CONN_OPTIONA LPINTERNET_PER_CONN_OPTION; + alias INTERNET_PER_CONN_OPTION_LISTA INTERNET_PER_CONN_OPTION_LIST; + alias LPINTERNET_PER_CONN_OPTION_LISTA LPINTERNET_PER_CONN_OPTION_LIST; alias URL_COMPONENTSA URL_COMPONENTS; alias LPURL_COMPONENTSA LPURL_COMPONENTS; alias GOPHER_FIND_DATAA GOPHER_FIND_DATA; diff --git a/libphobos/libdruntime/core/sys/windows/winioctl.d b/libphobos/libdruntime/core/sys/windows/winioctl.d index cd41a3f70ae..84d498e772f 100644 --- a/libphobos/libdruntime/core/sys/windows/winioctl.d +++ b/libphobos/libdruntime/core/sys/windows/winioctl.d @@ -9,10 +9,11 @@ */ module core.sys.windows.winioctl; version (Windows): +@system: // FIXME: check types of some constants -private import core.sys.windows.basetyps, core.sys.windows.windef; +import core.sys.windows.basetyps, core.sys.windows.windef; enum size_t HIST_NO_OF_BUCKETS = 24, diff --git a/libphobos/libdruntime/core/sys/windows/winldap.d b/libphobos/libdruntime/core/sys/windows/winldap.d index 8a861ae5488..78578dd51dd 100644 --- a/libphobos/libdruntime/core/sys/windows/winldap.d +++ b/libphobos/libdruntime/core/sys/windows/winldap.d @@ -9,6 +9,7 @@ */ module core.sys.windows.winldap; version (Windows): +@system: version (ANSI) {} else version = Unicode; @@ -30,7 +31,7 @@ version (ANSI) {} else version = Unicode; */ import core.sys.windows.schannel, core.sys.windows.winber; -private import core.sys.windows.wincrypt, core.sys.windows.windef; +import core.sys.windows.wincrypt, core.sys.windows.windef; //align(4): @@ -460,7 +461,7 @@ struct LDAPVLVInfo { * Under Microsoft WinLDAP the function ldap_error is only stub. * This macro uses LDAP structure to get error string and pass it to the user. */ -private extern (C) int printf(in char* format, ...); +private extern (C) int printf(const scope char* format, ...); int ldap_perror(LDAP* handle, char* message) { return printf("%s: %s\n", message, handle.ld_error); } @@ -491,111 +492,111 @@ extern (C) { ULONG ldap_controls_freeW(LDAPControlW**); ULONG ldap_free_controlsA(LDAPControlA**); ULONG ldap_free_controlsW(LDAPControlW**); - ULONG ldap_sasl_bindA(LDAP*, PCHAR, PCHAR, BERVAL*, PLDAPControlA*, + ULONG ldap_sasl_bindA(LDAP*, PCSTR, PCSTR, BERVAL*, PLDAPControlA*, PLDAPControlA*, int*); - ULONG ldap_sasl_bindW(LDAP*, PWCHAR, PWCHAR, BERVAL*, PLDAPControlW*, + ULONG ldap_sasl_bindW(LDAP*, PCWSTR, PCWSTR, BERVAL*, PLDAPControlW*, PLDAPControlW*, int*); - ULONG ldap_sasl_bind_sA(LDAP*, PCHAR, PCHAR, BERVAL*, PLDAPControlA*, + ULONG ldap_sasl_bind_sA(LDAP*, PCSTR, PCSTR, BERVAL*, PLDAPControlA*, PLDAPControlA*, PBERVAL*); - ULONG ldap_sasl_bind_sW(LDAP*, PWCHAR, PWCHAR, BERVAL*, PLDAPControlW*, + ULONG ldap_sasl_bind_sW(LDAP*, PCWSTR, PCWSTR, BERVAL*, PLDAPControlW*, PLDAPControlW*, PBERVAL*); - ULONG ldap_simple_bindA(LDAP*, PCHAR, PCHAR); - ULONG ldap_simple_bindW(LDAP*, PWCHAR, PWCHAR); - ULONG ldap_simple_bind_sA(LDAP*, PCHAR, PCHAR); - ULONG ldap_simple_bind_sW(LDAP*, PWCHAR, PWCHAR); + ULONG ldap_simple_bindA(LDAP*, PSTR, PSTR); + ULONG ldap_simple_bindW(LDAP*, PWSTR, PWSTR); + ULONG ldap_simple_bind_sA(LDAP*, PSTR, PSTR); + ULONG ldap_simple_bind_sW(LDAP*, PWSTR, PWSTR); ULONG ldap_unbind(LDAP*); ULONG ldap_unbind_s(LDAP*); - ULONG ldap_search_extA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG, + ULONG ldap_search_extA(LDAP*, PCSTR, ULONG, PCSTR, PZPSTR, ULONG, + PLDAPControlA*, PLDAPControlA*, ULONG, ULONG, ULONG*); + ULONG ldap_search_extW(LDAP*, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG, PLDAPControlW*, PLDAPControlW*, ULONG, ULONG, ULONG*); - ULONG ldap_search_extW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG, - PLDAPControlW*, PLDAPControlW*, ULONG, ULONG, ULONG*); - ULONG ldap_search_ext_sA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG, - PLDAPControlA*, PLDAPControlA*, LDAP_TIMEVAL*, ULONG, LDAPMessage**); - ULONG ldap_search_ext_sW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG, - PLDAPControlW*, PLDAPControlW*, LDAP_TIMEVAL*, ULONG, LDAPMessage**); - ULONG ldap_searchA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG); - ULONG ldap_searchW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG); - ULONG ldap_search_sA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG, - LDAPMessage**); - ULONG ldap_search_sW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG, - LDAPMessage**); - ULONG ldap_search_stA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG, - LDAP_TIMEVAL*, LDAPMessage**); - ULONG ldap_search_stW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG, - LDAP_TIMEVAL*, LDAPMessage**); - ULONG ldap_compare_extA(LDAP*, PCHAR, PCHAR, PCHAR, BerValue*, + ULONG ldap_search_ext_sA(LDAP*, PCSTR, ULONG, PCSTR, PZPSTR, ULONG, + PLDAPControlA*, PLDAPControlA*, LDAP_TIMEVAL*, ULONG, PLDAPMessage*); + ULONG ldap_search_ext_sW(LDAP*, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG, + PLDAPControlW*, PLDAPControlW*, LDAP_TIMEVAL*, ULONG, PLDAPMessage*); + ULONG ldap_searchA(LDAP*, PCSTR, ULONG, PCSTR, PZPSTR, ULONG); + ULONG ldap_searchW(LDAP*, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG); + ULONG ldap_search_sA(LDAP*, PCSTR, ULONG, PCSTR, PZPSTR, ULONG, + PLDAPMessage*); + ULONG ldap_search_sW(LDAP*, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG, + PLDAPMessage*); + ULONG ldap_search_stA(LDAP*, PCSTR, ULONG, PCSTR, PZPSTR, ULONG, + LDAP_TIMEVAL*, PLDAPMessage*); + ULONG ldap_search_stW(LDAP*, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG, + LDAP_TIMEVAL*, PLDAPMessage*); + ULONG ldap_compare_extA(LDAP*, PCSTR, PCSTR, PCSTR, BerValue*, PLDAPControlA*, PLDAPControlA*, ULONG*); - ULONG ldap_compare_extW(LDAP*, PWCHAR, PWCHAR, PWCHAR, BerValue*, + ULONG ldap_compare_extW(LDAP*, PCWSTR, PCWSTR, PCWSTR, BerValue*, PLDAPControlW*, PLDAPControlW*, ULONG*); - ULONG ldap_compare_ext_sA(LDAP*, PCHAR, PCHAR, PCHAR, BerValue*, + ULONG ldap_compare_ext_sA(LDAP*, PCSTR, PCSTR, PCSTR, BerValue*, PLDAPControlA*, PLDAPControlA*); - ULONG ldap_compare_ext_sW(LDAP*, PWCHAR, PWCHAR, PWCHAR, BerValue*, + ULONG ldap_compare_ext_sW(LDAP*, PCWSTR, PCWSTR, PCWSTR, BerValue*, PLDAPControlW*, PLDAPControlW*); - ULONG ldap_compareA(LDAP*, PCHAR, PCHAR, PCHAR); - ULONG ldap_compareW(LDAP*, PWCHAR, PWCHAR, PWCHAR); - ULONG ldap_compare_sA(LDAP*, PCHAR, PCHAR, PCHAR); - ULONG ldap_compare_sW(LDAP*, PWCHAR, PWCHAR, PWCHAR); - ULONG ldap_modify_extA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*, + ULONG ldap_compareA(LDAP*, PCSTR, PCSTR, PCSTR); + ULONG ldap_compareW(LDAP*, PCWSTR, PCWSTR, PCWSTR); + ULONG ldap_compare_sA(LDAP*, PCSTR, PCSTR, PCSTR); + ULONG ldap_compare_sW(LDAP*, PCWSTR, PCWSTR, PCWSTR); + ULONG ldap_modify_extA(LDAP*, PCSTR, LDAPModA**, PLDAPControlA*, PLDAPControlA*, ULONG*); - ULONG ldap_modify_extW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*, + ULONG ldap_modify_extW(LDAP*, PCWSTR, LDAPModW**, PLDAPControlW*, PLDAPControlW*, ULONG*); - ULONG ldap_modify_ext_sA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*, + ULONG ldap_modify_ext_sA(LDAP*, PCSTR, LDAPModA**, PLDAPControlA*, PLDAPControlA*); - ULONG ldap_modify_ext_sW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*, + ULONG ldap_modify_ext_sW(LDAP*, PCWSTR, LDAPModW**, PLDAPControlW*, PLDAPControlW*); - ULONG ldap_modifyA(LDAP*, PCHAR, LDAPModA*[]); - ULONG ldap_modifyW(LDAP*, PWCHAR, LDAPModW*[]); - ULONG ldap_modify_sA(LDAP*, PCHAR, LDAPModA*[]); - ULONG ldap_modify_sW(LDAP*, PWCHAR, LDAPModW*[]); - ULONG ldap_rename_extA(LDAP*, PCHAR, PCHAR, PCHAR, INT, PLDAPControlA*, + ULONG ldap_modifyA(LDAP*, PSTR, LDAPModA**); + ULONG ldap_modifyW(LDAP*, PWSTR, LDAPModW**); + ULONG ldap_modify_sA(LDAP*, PSTR, LDAPModA**); + ULONG ldap_modify_sW(LDAP*, PWSTR, LDAPModW**); + ULONG ldap_rename_extA(LDAP*, PCSTR, PCSTR, PCSTR, INT, PLDAPControlA*, PLDAPControlA*, ULONG*); - ULONG ldap_rename_extW(LDAP*, PWCHAR, PWCHAR, PWCHAR, INT, PLDAPControlW*, + ULONG ldap_rename_extW(LDAP*, PCWSTR, PCWSTR, PCWSTR, INT, PLDAPControlW*, PLDAPControlW*, ULONG*); - ULONG ldap_rename_ext_sA(LDAP*, PCHAR, PCHAR, PCHAR, INT, + ULONG ldap_rename_ext_sA(LDAP*, PCSTR, PCSTR, PCSTR, INT, PLDAPControlA*, PLDAPControlA*); - ULONG ldap_rename_ext_sW(LDAP*, PWCHAR, PWCHAR, PWCHAR, INT, + ULONG ldap_rename_ext_sW(LDAP*, PCWSTR, PCWSTR, PCWSTR, INT, PLDAPControlW*, PLDAPControlW*); - ULONG ldap_add_extA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*, + ULONG ldap_add_extA(LDAP*, PCSTR, LDAPModA**, PLDAPControlA*, PLDAPControlA*, ULONG*); - ULONG ldap_add_extW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*, + ULONG ldap_add_extW(LDAP*, PCWSTR, LDAPModW**, PLDAPControlW*, PLDAPControlW*, ULONG*); - ULONG ldap_add_ext_sA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*, + ULONG ldap_add_ext_sA(LDAP*, PCSTR, LDAPModA**, PLDAPControlA*, PLDAPControlA*); - ULONG ldap_add_ext_sW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*, + ULONG ldap_add_ext_sW(LDAP*, PCWSTR, LDAPModW**, PLDAPControlW*, PLDAPControlW*); - ULONG ldap_addA(LDAP*, PCHAR, LDAPModA*[]); - ULONG ldap_addW(LDAP*, PWCHAR, LDAPModW*[]); - ULONG ldap_add_sA(LDAP*, PCHAR, LDAPModA*[]); - ULONG ldap_add_sW(LDAP*, PWCHAR, LDAPModW*[]); - ULONG ldap_delete_extA(LDAP*, PCHAR, PLDAPControlA*, PLDAPControlA*, + ULONG ldap_addA(LDAP*, PSTR, LDAPModA**); + ULONG ldap_addW(LDAP*, PWSTR, LDAPModW**); + ULONG ldap_add_sA(LDAP*, PSTR, LDAPModA**); + ULONG ldap_add_sW(LDAP*, PWSTR, LDAPModW**); + ULONG ldap_delete_extA(LDAP*, PCSTR, PLDAPControlA*, PLDAPControlA*, ULONG*); - ULONG ldap_delete_extW(LDAP*, PWCHAR, PLDAPControlW*, PLDAPControlW*, + ULONG ldap_delete_extW(LDAP*, PCWSTR, PLDAPControlW*, PLDAPControlW*, ULONG*); - ULONG ldap_delete_ext_sA(LDAP*, PCHAR, PLDAPControlA*, PLDAPControlA*); - ULONG ldap_delete_ext_sW(LDAP*, PWCHAR, PLDAPControlW*, PLDAPControlW*); - ULONG ldap_deleteA(LDAP*, PCHAR); - ULONG ldap_deleteW(LDAP*, PWCHAR); - ULONG ldap_delete_sA(LDAP*, PCHAR); - ULONG ldap_delete_sW(LDAP*, PWCHAR); - ULONG ldap_extended_operationA(LDAP*, PCHAR, BerValue*, PLDAPControlA*, + ULONG ldap_delete_ext_sA(LDAP*, PCSTR, PLDAPControlA*, PLDAPControlA*); + ULONG ldap_delete_ext_sW(LDAP*, PCWSTR, PLDAPControlW*, PLDAPControlW*); + ULONG ldap_deleteA(LDAP*, PCSTR); + ULONG ldap_deleteW(LDAP*, PCWSTR); + ULONG ldap_delete_sA(LDAP*, PCSTR); + ULONG ldap_delete_sW(LDAP*, PCWSTR); + ULONG ldap_extended_operationA(LDAP*, PCSTR, BerValue*, PLDAPControlA*, PLDAPControlA*, ULONG*); - ULONG ldap_extended_operationW(LDAP*, PWCHAR, BerValue*, PLDAPControlW*, + ULONG ldap_extended_operationW(LDAP*, PCWSTR, BerValue*, PLDAPControlW*, PLDAPControlW*, ULONG*); - ULONG ldap_extended_operation_sA(LDAP*, PCHAR, BerValue*, PLDAPControlA*, + ULONG ldap_extended_operation_sA(LDAP*, PSTR, BerValue*, PLDAPControlA*, PLDAPControlA*, PCHAR*, BerValue**); - ULONG ldap_extended_operation_sW(LDAP*, PWCHAR, BerValue*, PLDAPControlW*, + ULONG ldap_extended_operation_sW(LDAP*, PWSTR, BerValue*, PLDAPControlW*, PLDAPControlW*, PWCHAR*, BerValue**); ULONG ldap_close_extended_op(LDAP*, ULONG); ULONG ldap_abandon(LDAP*, ULONG); ULONG ldap_result(LDAP*, ULONG, ULONG, LDAP_TIMEVAL*, LDAPMessage**); ULONG ldap_msgfree(LDAPMessage*); - ULONG ldap_parse_resultA(LDAP*, LDAPMessage*, ULONG*, PCHAR*, PCHAR*, - PCHAR**, PLDAPControlA**, BOOLEAN); - ULONG ldap_parse_resultW(LDAP*, LDAPMessage*, ULONG*, PWCHAR*, PWCHAR*, - PWCHAR**, PLDAPControlW**, BOOLEAN); - ULONG ldap_parse_extended_resultA(LDAP, LDAPMessage*, PCHAR*, BerValue**, + ULONG ldap_parse_resultA(LDAP*, LDAPMessage*, ULONG*, PSTR*, PSTR*, + PZPSTR*, PLDAPControlA**, BOOLEAN); + ULONG ldap_parse_resultW(LDAP*, LDAPMessage*, ULONG*, PWSTR*, PWSTR*, + PZPWSTR*, PLDAPControlW**, BOOLEAN); + ULONG ldap_parse_extended_resultA(LDAP, LDAPMessage*, PSTR*, BerValue**, BOOLEAN); - ULONG ldap_parse_extended_resultW(LDAP, LDAPMessage*, PWCHAR*, BerValue**, + ULONG ldap_parse_extended_resultW(LDAP, LDAPMessage*, PWSTR*, BerValue**, BOOLEAN); PCHAR ldap_err2stringA(ULONG); PWCHAR ldap_err2stringW(ULONG); @@ -614,10 +615,10 @@ extern (C) { PWCHAR ldap_next_attributeW(LDAP*, LDAPMessage*, BerElement*); VOID ldap_memfreeA(PCHAR); VOID ldap_memfreeW(PWCHAR); - PCHAR* ldap_get_valuesA(LDAP*, LDAPMessage*, PCHAR); - PWCHAR* ldap_get_valuesW(LDAP*, LDAPMessage*, PWCHAR); - BerValue** ldap_get_values_lenA(LDAP*, LDAPMessage*, PCHAR); - BerValue** ldap_get_values_lenW(LDAP*, LDAPMessage*, PWCHAR); + PCHAR* ldap_get_valuesA(LDAP*, LDAPMessage*, PCSTR); + PWCHAR* ldap_get_valuesW(LDAP*, LDAPMessage*, PCWSTR); + BerValue** ldap_get_values_lenA(LDAP*, LDAPMessage*, PCSTR); + BerValue** ldap_get_values_lenW(LDAP*, LDAPMessage*, PCWSTR); ULONG ldap_count_valuesA(PCHAR*); ULONG ldap_count_valuesW(PWCHAR*); ULONG ldap_count_values_len(BerValue**); @@ -626,16 +627,16 @@ extern (C) { ULONG ldap_value_free_len(BerValue**); PCHAR ldap_get_dnA(LDAP*, LDAPMessage*); PWCHAR ldap_get_dnW(LDAP*, LDAPMessage*); - PCHAR ldap_explode_dnA(PCHAR, ULONG); - PWCHAR ldap_explode_dnW(PWCHAR, ULONG); - PCHAR ldap_dn2ufnA(PCHAR); - PWCHAR ldap_dn2ufnW(PWCHAR); - ULONG ldap_ufn2dnA(PCHAR, PCHAR*); - ULONG ldap_ufn2dnW(PWCHAR, PWCHAR*); + PCHAR ldap_explode_dnA(PCSTR, ULONG); + PWCHAR ldap_explode_dnW(PCWSTR, ULONG); + PCHAR ldap_dn2ufnA(PCSTR); + PWCHAR ldap_dn2ufnW(PCWSTR); + ULONG ldap_ufn2dnA(PCSTR, PSTR*); + ULONG ldap_ufn2dnW(PCWSTR, PWSTR*); ULONG ldap_parse_referenceA(LDAP*, LDAPMessage*, PCHAR**); ULONG ldap_parse_referenceW(LDAP*, LDAPMessage*, PWCHAR**); - ULONG ldap_check_filterA(LDAP*, PCHAR); - ULONG ldap_check_filterW(LDAP*, PWCHAR); + ULONG ldap_check_filterA(LDAP*, PSTR); + ULONG ldap_check_filterW(LDAP*, PWSTR); ULONG ldap_create_page_controlA(PLDAP, ULONG, BerValue*, UCHAR, PLDAPControlA*); ULONG ldap_create_page_controlW(PLDAP, ULONG, BerValue*, UCHAR, @@ -644,8 +645,8 @@ extern (C) { PLDAPControlA*); ULONG ldap_create_sort_controlW(PLDAP, PLDAPSortKeyW*, UCHAR, PLDAPControlW*); - INT ldap_create_vlv_controlA(LDAP*, LDAPVLVInfo*, UCHAR, LDAPControlA**); - INT ldap_create_vlv_controlW(LDAP*, LDAPVLVInfo*, UCHAR, LDAPControlW**); + INT ldap_create_vlv_controlA(LDAP*, LDAPVLVInfo*, UCHAR, PLDAPControlA*); + INT ldap_create_vlv_controlW(LDAP*, LDAPVLVInfo*, UCHAR, PLDAPControlW*); ULONG ldap_encode_sort_controlA(PLDAP, PLDAPSortKeyA*, PLDAPControlA, BOOLEAN); ULONG ldap_encode_sort_controlW(PLDAP, PLDAPSortKeyW*, PLDAPControlW, @@ -660,31 +661,31 @@ extern (C) { ULONG ldap_parse_page_controlW(PLDAP, PLDAPControlW*, ULONG*, BerValue**); ULONG ldap_parse_sort_controlA(PLDAP, PLDAPControlA*, ULONG*, PCHAR*); ULONG ldap_parse_sort_controlW(PLDAP, PLDAPControlW*, ULONG*, PWCHAR*); - INT ldap_parse_vlv_controlA(LDAP*, LDAPControlA**, uint*, uint*, - BerValue**, int*); - INT ldap_parse_vlv_controlW(LDAP*, LDAPControlW**, uint*, uint*, - BerValue**, int*); - PLDAPSearch ldap_search_init_pageA(PLDAP, PCHAR, ULONG, PCHAR, PCHAR[], + INT ldap_parse_vlv_controlA(PLDAP, PLDAPControlA*, PULONG, PULONG, + BerValue**, PINT); + INT ldap_parse_vlv_controlW(PLDAP, PLDAPControlW*, PULONG, PULONG, + BerValue**, PINT); + PLDAPSearch ldap_search_init_pageA(PLDAP, PCSTR, ULONG, PCSTR, PZPSTR, ULONG, PLDAPControlA*, PLDAPControlA*, ULONG, ULONG, PLDAPSortKeyA*); - PLDAPSearch ldap_search_init_pageW(PLDAP, PWCHAR, ULONG, PWCHAR, PWCHAR[], + PLDAPSearch ldap_search_init_pageW(PLDAP, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG, PLDAPControlW*, PLDAPControlW*, ULONG, ULONG, PLDAPSortKeyW*); ULONG ldap_search_abandon_page(PLDAP, PLDAPSearch); LDAP ldap_conn_from_msg(LDAP*, LDAPMessage*); INT LdapUnicodeToUTF8(LPCWSTR, int, LPSTR, int); INT LdapUTF8ToUnicode(LPCSTR, int, LPWSTR, int); - deprecated { - ULONG ldap_bindA(LDAP*, PCHAR, PCHAR, ULONG); - ULONG ldap_bindW(LDAP*, PWCHAR, PWCHAR, ULONG); - ULONG ldap_bind_sA(LDAP*, PCHAR, PCHAR, ULONG); - ULONG ldap_bind_sW(LDAP*, PWCHAR, PWCHAR, ULONG); - ULONG ldap_modrdnA(LDAP*, PCHAR, PCHAR); - ULONG ldap_modrdnW(LDAP*, PWCHAR, PWCHAR); - ULONG ldap_modrdn_sA(LDAP*, PCHAR, PCHAR); - ULONG ldap_modrdn_sW(LDAP*, PWCHAR, PWCHAR); - ULONG ldap_modrdn2A(LDAP*, PCHAR, PCHAR, INT); - ULONG ldap_modrdn2W(LDAP*, PWCHAR, PWCHAR, INT); - ULONG ldap_modrdn2_sA(LDAP*, PCHAR, PCHAR, INT); - ULONG ldap_modrdn2_sW(LDAP*, PWCHAR, PWCHAR, INT); + ULONG ldap_bindA(LDAP*, PSTR, PCHAR, ULONG); + ULONG ldap_bindW(LDAP*, PWSTR, PWCHAR, ULONG); + ULONG ldap_bind_sA(LDAP*, PSTR, PCHAR, ULONG); + ULONG ldap_bind_sW(LDAP*, PWSTR, PWCHAR, ULONG); + deprecated ("For LDAP 3 or later, use the ldap_rename_ext or ldap_rename_ext_s functions") { + ULONG ldap_modrdnA(LDAP*, PCSTR, PCSTR); + ULONG ldap_modrdnW(LDAP*, PCWSTR, PCWSTR); + ULONG ldap_modrdn_sA(LDAP*, PCSTR, PCSTR); + ULONG ldap_modrdn_sW(LDAP*, PCWSTR, PCWSTR); + ULONG ldap_modrdn2A(LDAP*, PCSTR, PCSTR, INT); + ULONG ldap_modrdn2W(LDAP*, PCWSTR, PCWSTR, INT); + ULONG ldap_modrdn2_sA(LDAP*, PCSTR, PCSTR, INT); + ULONG ldap_modrdn2_sW(LDAP*, PCWSTR, PCWSTR, INT); } } diff --git a/libphobos/libdruntime/core/sys/windows/winnetwk.d b/libphobos/libdruntime/core/sys/windows/winnetwk.d index 1f952b681aa..7601279005f 100644 --- a/libphobos/libdruntime/core/sys/windows/winnetwk.d +++ b/libphobos/libdruntime/core/sys/windows/winnetwk.d @@ -9,11 +9,12 @@ */ module core.sys.windows.winnetwk; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "mpr"); -private import core.sys.windows.winbase, core.sys.windows.winerror, core.sys.windows.winnt; +import core.sys.windows.winbase, core.sys.windows.winerror, core.sys.windows.winnt; enum : DWORD { WNNC_NET_MSNET = 0x00010000, diff --git a/libphobos/libdruntime/core/sys/windows/winnls.d b/libphobos/libdruntime/core/sys/windows/winnls.d index 5f1c15005e1..6483f4bcc02 100644 --- a/libphobos/libdruntime/core/sys/windows/winnls.d +++ b/libphobos/libdruntime/core/sys/windows/winnls.d @@ -9,11 +9,12 @@ */ module core.sys.windows.winnls; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "kernel32"); -private import core.sys.windows.basetsd, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef; +import core.sys.windows.basetsd, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef; alias DWORD LCTYPE, CALTYPE, CALID, LGRPID, GEOID, GEOTYPE, GEOCLASS; diff --git a/libphobos/libdruntime/core/sys/windows/winnt.d b/libphobos/libdruntime/core/sys/windows/winnt.d index f378a17943d..2d9a28121e9 100644 --- a/libphobos/libdruntime/core/sys/windows/winnt.d +++ b/libphobos/libdruntime/core/sys/windows/winnt.d @@ -8,11 +8,12 @@ */ module core.sys.windows.winnt; version (Windows): +@system: version (ANSI) {} else version = Unicode; public import core.sys.windows.basetsd, core.sys.windows.windef, core.sys.windows.winerror; -private import core.sys.windows.w32api; +import core.sys.windows.w32api; /* Translation Notes: The following macros are unneeded for D: @@ -2246,8 +2247,8 @@ enum LEGACY_SAVE_AREA_LENGTH = XMM_SAVE_AREA32.sizeof; M128A Xmm13; M128A Xmm14; M128A Xmm15; - }; - }; + } + } M128A[26] VectorRegister; DWORD64 VectorControl; DWORD64 DebugControl; @@ -2397,6 +2398,7 @@ struct TOKEN_OWNER { PSID Owner; } alias TOKEN_OWNER* PTOKEN_OWNER; +enum SECURITY_MAX_SID_SIZE = 68; struct TOKEN_PRIMARY_GROUP { PSID PrimaryGroup; @@ -2436,6 +2438,10 @@ struct TOKEN_USER { } alias TOKEN_USER* PTOKEN_USER; +struct TOKEN_MANDATORY_LABEL { + SID_AND_ATTRIBUTES Label; +} +alias PTOKEN_MANDATORY_LABEL = TOKEN_MANDATORY_LABEL*; alias DWORD SECURITY_INFORMATION; alias SECURITY_INFORMATION* PSECURITY_INFORMATION; alias WORD SECURITY_DESCRIPTOR_CONTROL; @@ -2451,6 +2457,18 @@ struct SECURITY_DESCRIPTOR { PACL Dacl; } alias SECURITY_DESCRIPTOR* PSECURITY_DESCRIPTOR, PISECURITY_DESCRIPTOR; +enum TOKEN_ELEVATION_TYPE { + TokenElevationTypeDefault = 1, + TokenElevationTypeFull, + TokenElevationTypeLimited +} + +alias PTOKEN_ELEVATION_TYPE = TOKEN_ELEVATION_TYPE*; + +struct TOKEN_ELEVATION { + DWORD TokenIsElevated; +} +alias PTOKEN_ELEVATION = TOKEN_ELEVATION*; enum TOKEN_INFORMATION_CLASS { TokenUser = 1, @@ -2469,7 +2487,32 @@ enum TOKEN_INFORMATION_CLASS { TokenSessionReference, TokenSandBoxInert, TokenAuditPolicy, - TokenOrigin + TokenOrigin, + TokenElevationType, + TokenLinkedToken, + TokenElevation, + TokenHasRestrictions, + TokenAccessInformation, + TokenVirtualizationAllowed, + TokenVirtualizationEnabled, + TokenIntegrityLevel, + TokenUIAccess, + TokenMandatoryPolicy, + TokenLogonSid, + TokenIsAppContainer, + TokenCapabilities, + TokenAppContainerSid, + TokenAppContainerNumber, + TokenUserClaimAttributes, + TokenDeviceClaimAttributes, + TokenRestrictedUserClaimAttributes, + TokenRestrictedDeviceClaimAttributes, + TokenDeviceGroups, + TokenRestrictedDeviceGroups, + TokenSecurityAttributes, + TokenIsRestricted, + TokenProcessTrustLevel, + MaxTokenInfoClass // MaxTokenInfoClass should always be the last enum } enum SID_NAME_USE { @@ -2485,6 +2528,103 @@ enum SID_NAME_USE { } alias SID_NAME_USE* PSID_NAME_USE; +enum WELL_KNOWN_SID_TYPE { + WinNullSid = 0, + WinWorldSid = 1, + WinLocalSid = 2, + WinCreatorOwnerSid = 3, + WinCreatorGroupSid = 4, + WinCreatorOwnerServerSid = 5, + WinCreatorGroupServerSid = 6, + WinNtAuthoritySid = 7, + WinDialupSid = 8, + WinNetworkSid = 9, + WinBatchSid = 10, + WinInteractiveSid = 11, + WinServiceSid = 12, + WinAnonymousSid = 13, + WinProxySid = 14, + WinEnterpriseControllersSid = 15, + WinSelfSid = 16, + WinAuthenticatedUserSid = 17, + WinRestrictedCodeSid = 18, + WinTerminalServerSid = 19, + WinRemoteLogonIdSid = 20, + WinLogonIdsSid = 21, + WinLocalSystemSid = 22, + WinLocalServiceSid = 23, + WinNetworkServiceSid = 24, + WinBuiltinDomainSid = 25, + WinBuiltinAdministratorsSid = 26, + WinBuiltinUsersSid = 27, + WinBuiltinGuestsSid = 28, + WinBuiltinPowerUsersSid = 29, + WinBuiltinAccountOperatorsSid = 30, + WinBuiltinSystemOperatorsSid = 31, + WinBuiltinPrintOperatorsSid = 32, + WinBuiltinBackupOperatorsSid = 33, + WinBuiltinReplicatorSid = 34, + WinBuiltinPreWindows2000CompatibleAccessSid = 35, + WinBuiltinRemoteDesktopUsersSid = 36, + WinBuiltinNetworkConfigurationOperatorsSid = 37, + WinAccountAdministratorSid = 38, + WinAccountGuestSid = 39, + WinAccountKrbtgtSid = 40, + WinAccountDomainAdminsSid = 41, + WinAccountDomainUsersSid = 42, + WinAccountDomainGuestsSid = 43, + WinAccountComputersSid = 44, + WinAccountControllersSid = 45, + WinAccountCertAdminsSid = 46, + WinAccountSchemaAdminsSid = 47, + WinAccountEnterpriseAdminsSid = 48, + WinAccountPolicyAdminsSid = 49, + WinAccountRasAndIasServersSid = 50, + WinNTLMAuthenticationSid = 51, + WinDigestAuthenticationSid = 52, + WinSChannelAuthenticationSid = 53, + WinThisOrganizationSid = 54, + WinOtherOrganizationSid = 55, + WinBuiltinIncomingForestTrustBuildersSid = 56, + WinBuiltinPerfMonitoringUsersSid = 57, + WinBuiltinPerfLoggingUsersSid = 58, + WinBuiltinAuthorizationAccessSid = 59, + WinBuiltinTerminalServerLicenseServersSid = 60, + WinBuiltinDCOMUsersSid = 61, + WinBuiltinIUsersSid = 62, + WinIUserSid = 63, + WinBuiltinCryptoOperatorsSid = 64, + WinUntrustedLabelSid = 65, + WinLowLabelSid = 66, + WinMediumLabelSid = 67, + WinHighLabelSid = 68, + WinSystemLabelSid = 69, + WinWriteRestrictedCodeSid = 70, + WinCreatorOwnerRightsSid = 71, + WinCacheablePrincipalsGroupSid = 72, + WinNonCacheablePrincipalsGroupSid = 73, + WinEnterpriseReadonlyControllersSid = 74, + WinAccountReadonlyControllersSid = 75, + WinBuiltinEventLogReadersGroup = 76, + WinNewEnterpriseReadonlyControllersSid = 77, + WinBuiltinCertSvcDComAccessGroup = 78, + WinMediumPlusLabelSid = 79, + WinLocalLogonSid = 80, + WinConsoleLogonSid = 81, + WinThisOrganizationCertificateSid = 82, + WinApplicationPackageAuthoritySid = 83, + WinBuiltinAnyPackageSid = 84, + WinCapabilityInternetClientSid = 85, + WinCapabilityInternetClientServerSid = 86, + WinCapabilityPrivateNetworkClientServerSid = 87, + WinCapabilityPicturesLibrarySid = 88, + WinCapabilityVideosLibrarySid = 89, + WinCapabilityMusicLibrarySid = 90, + WinCapabilityDocumentsLibrarySid = 91, + WinCapabilitySharedUserCertificatesSid = 92, + WinCapabilityEnterpriseAuthenticationSid = 93, + WinCapabilityRemovableStorageSid = 94 +} struct QUOTA_LIMITS { SIZE_T PagedPoolLimit; SIZE_T NonPagedPoolLimit; @@ -3734,6 +3874,7 @@ enum DWORD ES_SYSTEM_REQUIRED = 0x00000001, ES_DISPLAY_REQUIRED = 0x00000002, ES_USER_PRESENT = 0x00000004, + ES_AWAYMODE_REQUIRED = 0x00000040, ES_CONTINUOUS = 0x80000000; enum LATENCY_TIME { diff --git a/libphobos/libdruntime/core/sys/windows/winperf.d b/libphobos/libdruntime/core/sys/windows/winperf.d index 24a6c2c3810..367c2b09561 100644 --- a/libphobos/libdruntime/core/sys/windows/winperf.d +++ b/libphobos/libdruntime/core/sys/windows/winperf.d @@ -8,6 +8,7 @@ */ module core.sys.windows.winperf; version (Windows): +@system: import core.sys.windows.windef; import core.sys.windows.winbase; // for SYSTEMTIME diff --git a/libphobos/libdruntime/core/sys/windows/winreg.d b/libphobos/libdruntime/core/sys/windows/winreg.d index 2f80e8f767d..078bdf7037e 100644 --- a/libphobos/libdruntime/core/sys/windows/winreg.d +++ b/libphobos/libdruntime/core/sys/windows/winreg.d @@ -9,11 +9,12 @@ */ module core.sys.windows.winreg; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "advapi32"); -private import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef; +import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef; enum : HKEY { // for some reason, DMD errors if I don't give all the values explicitly HKEY_CLASSES_ROOT = cast(HKEY) 0x80000000, @@ -97,58 +98,58 @@ static if (_WIN32_WINNT >= 0x600) { } extern (Windows) nothrow @nogc { - LONG RegCloseKey(in HKEY); + LONG RegCloseKey(const scope HKEY); LONG RegConnectRegistryA(LPCSTR, HKEY, PHKEY); LONG RegConnectRegistryW(LPCWSTR, HKEY, PHKEY); - LONG RegCreateKeyExA(in HKEY, LPCSTR, DWORD, LPSTR, DWORD, REGSAM, + LONG RegCreateKeyExA(const scope HKEY, LPCSTR, DWORD, LPSTR, DWORD, REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, PDWORD); - LONG RegCreateKeyExW(in HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM, + LONG RegCreateKeyExW(const scope HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, PDWORD); - LONG RegDeleteKeyA(in HKEY, LPCSTR); - LONG RegDeleteKeyW(in HKEY, LPCWSTR); - LONG RegDeleteValueA(in HKEY, LPCSTR); - LONG RegDeleteValueW(in HKEY, LPCWSTR); - LONG RegEnumKeyExA(in HKEY, DWORD, LPSTR, PDWORD, PDWORD, LPSTR, PDWORD, + LONG RegDeleteKeyA(const scope HKEY, LPCSTR); + LONG RegDeleteKeyW(const scope HKEY, LPCWSTR); + LONG RegDeleteValueA(const scope HKEY, LPCSTR); + LONG RegDeleteValueW(const scope HKEY, LPCWSTR); + LONG RegEnumKeyExA(const scope HKEY, DWORD, LPSTR, PDWORD, PDWORD, LPSTR, PDWORD, PFILETIME); - LONG RegEnumKeyExW(in HKEY, DWORD, LPWSTR, PDWORD, PDWORD, LPWSTR, PDWORD, + LONG RegEnumKeyExW(const scope HKEY, DWORD, LPWSTR, PDWORD, PDWORD, LPWSTR, PDWORD, PFILETIME); - LONG RegEnumValueA(in HKEY, DWORD, LPSTR, PDWORD, PDWORD, PDWORD, LPBYTE, + LONG RegEnumValueA(const scope HKEY, DWORD, LPSTR, PDWORD, PDWORD, PDWORD, LPBYTE, PDWORD); - LONG RegEnumValueW(in HKEY, DWORD, LPWSTR, PDWORD, PDWORD, PDWORD, LPBYTE, + LONG RegEnumValueW(const scope HKEY, DWORD, LPWSTR, PDWORD, PDWORD, PDWORD, LPBYTE, PDWORD); - LONG RegFlushKey(in HKEY); - LONG RegLoadKeyA(in HKEY, LPCSTR, LPCSTR); - LONG RegLoadKeyW(in HKEY, LPCWSTR, LPCWSTR); - LONG RegOpenKeyExA(in HKEY, LPCSTR, DWORD, REGSAM, PHKEY); - LONG RegOpenKeyExW(in HKEY, LPCWSTR, DWORD, REGSAM, PHKEY); - LONG RegQueryInfoKeyA(in HKEY, LPSTR, PDWORD, PDWORD, PDWORD, PDWORD, + LONG RegFlushKey(const scope HKEY); + LONG RegLoadKeyA(const scope HKEY, LPCSTR, LPCSTR); + LONG RegLoadKeyW(const scope HKEY, LPCWSTR, LPCWSTR); + LONG RegOpenKeyExA(const scope HKEY, LPCSTR, DWORD, REGSAM, PHKEY); + LONG RegOpenKeyExW(const scope HKEY, LPCWSTR, DWORD, REGSAM, PHKEY); + LONG RegQueryInfoKeyA(const scope HKEY, LPSTR, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PFILETIME); - LONG RegQueryInfoKeyW(in HKEY, LPWSTR, PDWORD, PDWORD, PDWORD, PDWORD, + LONG RegQueryInfoKeyW(const scope HKEY, LPWSTR, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PFILETIME); - LONG RegQueryMultipleValuesA(in HKEY, PVALENTA, DWORD, LPSTR, LPDWORD); - LONG RegQueryMultipleValuesW(in HKEY, PVALENTW, DWORD, LPWSTR, LPDWORD); - LONG RegQueryValueExA(in HKEY, LPCSTR, LPDWORD, LPDWORD, /*LPBYTE*/LPVOID, LPDWORD); - LONG RegQueryValueExW(in HKEY, LPCWSTR, LPDWORD, LPDWORD, /*LPBYTE*/LPVOID, LPDWORD); - LONG RegReplaceKeyA(in HKEY, LPCSTR, LPCSTR, LPCSTR); - LONG RegReplaceKeyW(in HKEY, LPCWSTR, LPCWSTR, LPCWSTR); - LONG RegSaveKeyA(in HKEY, LPCSTR, LPSECURITY_ATTRIBUTES); - LONG RegSaveKeyW(in HKEY, LPCWSTR, LPSECURITY_ATTRIBUTES); - LONG RegSetKeySecurity(in HKEY, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR); - LONG RegSetValueExA(in HKEY, LPCSTR, DWORD, DWORD, const(BYTE)*, DWORD); - LONG RegSetValueExW(in HKEY, LPCWSTR, DWORD, DWORD, const(BYTE)*, DWORD); - LONG RegUnLoadKeyA(in HKEY, LPCSTR); - LONG RegUnLoadKeyW(in HKEY, LPCWSTR); - LONG RegNotifyChangeKeyValue(in HKEY, BOOL, DWORD, HANDLE, BOOL); + LONG RegQueryMultipleValuesA(const scope HKEY, PVALENTA, DWORD, LPSTR, LPDWORD); + LONG RegQueryMultipleValuesW(const scope HKEY, PVALENTW, DWORD, LPWSTR, LPDWORD); + LONG RegQueryValueExA(const scope HKEY, LPCSTR, LPDWORD, LPDWORD, /*LPBYTE*/LPVOID, LPDWORD); + LONG RegQueryValueExW(const scope HKEY, LPCWSTR, LPDWORD, LPDWORD, /*LPBYTE*/LPVOID, LPDWORD); + LONG RegReplaceKeyA(const scope HKEY, LPCSTR, LPCSTR, LPCSTR); + LONG RegReplaceKeyW(const scope HKEY, LPCWSTR, LPCWSTR, LPCWSTR); + LONG RegSaveKeyA(const scope HKEY, LPCSTR, LPSECURITY_ATTRIBUTES); + LONG RegSaveKeyW(const scope HKEY, LPCWSTR, LPSECURITY_ATTRIBUTES); + LONG RegSetKeySecurity(const scope HKEY, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR); + LONG RegSetValueExA(const scope HKEY, LPCSTR, DWORD, DWORD, const(BYTE)*, DWORD); + LONG RegSetValueExW(const scope HKEY, LPCWSTR, DWORD, DWORD, const(BYTE)*, DWORD); + LONG RegUnLoadKeyA(const scope HKEY, LPCSTR); + LONG RegUnLoadKeyW(const scope HKEY, LPCWSTR); + LONG RegNotifyChangeKeyValue(const scope HKEY, BOOL, DWORD, HANDLE, BOOL); BOOL AbortSystemShutdownA(LPCSTR); BOOL AbortSystemShutdownW(LPCWSTR); BOOL InitiateSystemShutdownA(LPSTR, LPSTR, DWORD, BOOL, BOOL); BOOL InitiateSystemShutdownW(LPWSTR, LPWSTR, DWORD, BOOL, BOOL); - LONG RegGetKeySecurity(in HKEY, SECURITY_INFORMATION, + LONG RegGetKeySecurity(const scope HKEY, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, PDWORD); - LONG RegRestoreKeyA(in HKEY, LPCSTR, DWORD); - LONG RegRestoreKeyW(in HKEY, LPCWSTR, DWORD); - LONG RegSetKeySecurity(in HKEY, SECURITY_INFORMATION, + LONG RegRestoreKeyA(const scope HKEY, LPCSTR, DWORD); + LONG RegRestoreKeyW(const scope HKEY, LPCWSTR, DWORD); + LONG RegSetKeySecurity(const scope HKEY, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR); static if (_WIN32_WINNT >= 0x500) { @@ -158,28 +159,28 @@ extern (Windows) nothrow @nogc { } static if (_WIN32_WINNT >= 0x501) { - LONG RegSaveKeyExA(in HKEY, LPCSTR, LPSECURITY_ATTRIBUTES, DWORD); - LONG RegSaveKeyExW(in HKEY, LPCWSTR, LPSECURITY_ATTRIBUTES, DWORD); + LONG RegSaveKeyExA(const scope HKEY, LPCSTR, LPSECURITY_ATTRIBUTES, DWORD); + LONG RegSaveKeyExW(const scope HKEY, LPCWSTR, LPSECURITY_ATTRIBUTES, DWORD); } static if (_WIN32_WINNT >= 0x600) { - LONG RegGetValueA(in HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, + LONG RegGetValueA(const scope HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData); - LONG RegGetValueW(in HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, + LONG RegGetValueW(const scope HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData); } //deprecated { - LONG RegCreateKeyA(in HKEY, LPCSTR, PHKEY); - LONG RegCreateKeyW(in HKEY, LPCWSTR, PHKEY); - LONG RegEnumKeyA(in HKEY, DWORD, LPSTR, DWORD); - LONG RegEnumKeyW(in HKEY, DWORD, LPWSTR, DWORD); - LONG RegOpenKeyA(in HKEY, LPCSTR, PHKEY); - LONG RegOpenKeyW(in HKEY, LPCWSTR, PHKEY); - LONG RegQueryValueA(in HKEY, LPCSTR, LPSTR, PLONG); - LONG RegQueryValueW(in HKEY, LPCWSTR, LPWSTR, PLONG); - LONG RegSetValueA(in HKEY, LPCSTR, DWORD, LPCSTR, DWORD); - LONG RegSetValueW(in HKEY, LPCWSTR, DWORD, LPCWSTR, DWORD); + LONG RegCreateKeyA(const scope HKEY, LPCSTR, PHKEY); + LONG RegCreateKeyW(const scope HKEY, LPCWSTR, PHKEY); + LONG RegEnumKeyA(const scope HKEY, DWORD, LPSTR, DWORD); + LONG RegEnumKeyW(const scope HKEY, DWORD, LPWSTR, DWORD); + LONG RegOpenKeyA(const scope HKEY, LPCSTR, PHKEY); + LONG RegOpenKeyW(const scope HKEY, LPCWSTR, PHKEY); + LONG RegQueryValueA(const scope HKEY, LPCSTR, LPSTR, PLONG); + LONG RegQueryValueW(const scope HKEY, LPCWSTR, LPWSTR, PLONG); + LONG RegSetValueA(const scope HKEY, LPCSTR, DWORD, LPCSTR, DWORD); + LONG RegSetValueW(const scope HKEY, LPCWSTR, DWORD, LPCWSTR, DWORD); //} } diff --git a/libphobos/libdruntime/core/sys/windows/winsock2.d b/libphobos/libdruntime/core/sys/windows/winsock2.d index 04e9881d7d9..55a45be85bf 100644 --- a/libphobos/libdruntime/core/sys/windows/winsock2.d +++ b/libphobos/libdruntime/core/sys/windows/winsock2.d @@ -6,6 +6,7 @@ module core.sys.windows.winsock2; version (Windows): +@system: pragma(lib, "ws2_32"); diff --git a/libphobos/libdruntime/core/sys/windows/winspool.d b/libphobos/libdruntime/core/sys/windows/winspool.d index 8cc50ddd165..db5b23f6eb2 100644 --- a/libphobos/libdruntime/core/sys/windows/winspool.d +++ b/libphobos/libdruntime/core/sys/windows/winspool.d @@ -8,12 +8,13 @@ */ module core.sys.windows.winspool; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "winspool"); -private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.wingdi; -private import core.sys.windows.winbase; // for SYSTEMTIME +import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.wingdi; +import core.sys.windows.winbase; // for SYSTEMTIME // FIXME: clean up Windows version support diff --git a/libphobos/libdruntime/core/sys/windows/winsvc.d b/libphobos/libdruntime/core/sys/windows/winsvc.d index 3114807d1ba..44c4563aab6 100644 --- a/libphobos/libdruntime/core/sys/windows/winsvc.d +++ b/libphobos/libdruntime/core/sys/windows/winsvc.d @@ -9,11 +9,12 @@ */ module core.sys.windows.winsvc; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "advapi32"); -private import core.sys.windows.w32api, core.sys.windows.windef; +import core.sys.windows.w32api, core.sys.windows.windef; // FIXME: check Windows version support diff --git a/libphobos/libdruntime/core/sys/windows/winuser.d b/libphobos/libdruntime/core/sys/windows/winuser.d index 11f0a28c42f..07e5efaa33d 100644 --- a/libphobos/libdruntime/core/sys/windows/winuser.d +++ b/libphobos/libdruntime/core/sys/windows/winuser.d @@ -8,6 +8,7 @@ */ module core.sys.windows.winuser; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "user32"); @@ -22,8 +23,8 @@ pragma(lib, "user32"); //#define GetWindowTask(hWnd) ((HANDLE)GetWindowThreadProcessId(hWnd, NULL)) //#define DefHookProc(c, p, lp, h) CallNextHookEx((HHOOK)*h, c, p, lp) -private import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.wingdi; -private import core.sys.windows.windef; // for HMONITOR +import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.wingdi; +import core.sys.windows.windef; // for HMONITOR // FIXME: clean up Windows version support @@ -3545,7 +3546,7 @@ void POINTSTOPOINT()(out POINT p, LONG ps) { p.y = HIWORD(ps); } -POINTS POINTTOPOINTS()(in POINT p) { +POINTS POINTTOPOINTS()(const POINT p) { return MAKELONG(p.x, p.y); } diff --git a/libphobos/libdruntime/core/sys/windows/winver.d b/libphobos/libdruntime/core/sys/windows/winver.d index e33ff4b498f..afe53d8f7cc 100644 --- a/libphobos/libdruntime/core/sys/windows/winver.d +++ b/libphobos/libdruntime/core/sys/windows/winver.d @@ -9,11 +9,15 @@ */ module core.sys.windows.winver; version (Windows): +@system: +import core.sys.windows.w32api; +import core.sys.windows.winbase; +import core.sys.windows.sdkddkver; version (ANSI) {} else version = Unicode; pragma(lib, "version"); -private import core.sys.windows.windef; +import core.sys.windows.windef; // FIXME: type weirdness enum { @@ -172,3 +176,89 @@ version (Unicode) { alias VerLanguageNameA VerLanguageName; alias VerQueryValueA VerQueryValue; } + +alias VERSIONHELPERAPI = BOOL; +VERSIONHELPERAPI IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi; + const DWORDLONG dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, + VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL + ); + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} + +VERSIONHELPERAPI IsWindowsXPOrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0); +} + +VERSIONHELPERAPI IsWindowsXPSP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1); +} + +VERSIONHELPERAPI IsWindowsXPSP2OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2); +} + +VERSIONHELPERAPI IsWindowsXPSP3OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3); +} + +VERSIONHELPERAPI IsWindowsVistaOrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); +} + +VERSIONHELPERAPI IsWindowsVistaSP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1); +} + +VERSIONHELPERAPI IsWindowsVistaSP2OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2); +} + +VERSIONHELPERAPI IsWindows7OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0); +} + +VERSIONHELPERAPI IsWindows7SP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1); +} + +VERSIONHELPERAPI IsWindows8OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0); +} + +VERSIONHELPERAPI IsWindows8Point1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0); +} + +VERSIONHELPERAPI IsWindows10OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN10), LOBYTE(_WIN32_WINNT_WIN10), 0); +} + +VERSIONHELPERAPI IsWindowsServer() +{ + OSVERSIONINFOEXW osvi = { OSVERSIONINFOEXW.sizeof, 0, 0, 0, 0, [0], 0, 0, 0, VER_NT_WORKSTATION }; + const DWORDLONG dwlConditionMask = VerSetConditionMask( 0, VER_PRODUCT_TYPE, VER_EQUAL ); + + return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask); +} diff --git a/libphobos/libdruntime/core/sys/windows/wtsapi32.d b/libphobos/libdruntime/core/sys/windows/wtsapi32.d index 538dc629adb..643c049c25c 100644 --- a/libphobos/libdruntime/core/sys/windows/wtsapi32.d +++ b/libphobos/libdruntime/core/sys/windows/wtsapi32.d @@ -8,10 +8,11 @@ */ module core.sys.windows.wtsapi32; version (Windows): +@system: version (ANSI) {} else version = Unicode; pragma(lib, "wtsapi32"); -private import core.sys.windows.w32api; +import core.sys.windows.w32api; import core.sys.windows.windef; enum { diff --git a/libphobos/libdruntime/core/sys/windows/wtypes.d b/libphobos/libdruntime/core/sys/windows/wtypes.d index b7a83cbce70..8af42cf7179 100644 --- a/libphobos/libdruntime/core/sys/windows/wtypes.d +++ b/libphobos/libdruntime/core/sys/windows/wtypes.d @@ -8,10 +8,11 @@ */ module core.sys.windows.wtypes; version (Windows): +@system: import core.sys.windows.rpc, core.sys.windows.rpcndr; -private import core.sys.windows.windef; -private import core.sys.windows.uuid; // for GUID_NULL +import core.sys.windows.windef; +import core.sys.windows.uuid; // for GUID_NULL alias GUID_NULL IID_NULL, CLSID_NULL; @@ -187,7 +188,7 @@ enum VARENUM { VT_ILLEGAL = 0xffff, VT_ILLEGALMASKED = 0xfff, VT_TYPEMASK = 0xfff -}; +} struct BYTE_SIZEDARR { uint clSize; diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d deleted file mode 100644 index 7506a8b3ee3..00000000000 --- a/libphobos/libdruntime/core/thread.d +++ /dev/null @@ -1,5732 +0,0 @@ -/** - * The thread module provides support for thread creation and management. - * - * Copyright: Copyright Sean Kelly 2005 - 2012. - * License: Distributed under the - * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). - * (See accompanying file LICENSE) - * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak - * Source: $(DRUNTIMESRC core/_thread.d) - */ - -/* NOTE: This file has been patched from the original DMD distribution to - * work with the GDC compiler. - */ -module core.thread; - - -public import core.time; // for Duration -import core.exception : onOutOfMemoryError; - -version (OSX) - version = Darwin; -else version (iOS) - version = Darwin; -else version (TVOS) - version = Darwin; -else version (WatchOS) - version = Darwin; - -private -{ - // interface to rt.tlsgc - import core.internal.traits : externDFunc; - - alias rt_tlsgc_init = externDFunc!("rt.tlsgc.init", void* function() nothrow @nogc); - alias rt_tlsgc_destroy = externDFunc!("rt.tlsgc.destroy", void function(void*) nothrow @nogc); - - alias ScanDg = void delegate(void* pstart, void* pend) nothrow; - alias rt_tlsgc_scan = - externDFunc!("rt.tlsgc.scan", void function(void*, scope ScanDg) nothrow); - - alias rt_tlsgc_processGCMarks = - externDFunc!("rt.tlsgc.processGCMarks", void function(void*, scope IsMarkedDg) nothrow); -} - -version (Solaris) -{ - import core.sys.solaris.sys.priocntl; - import core.sys.solaris.sys.types; -} - -version (GNU) -{ - import gcc.builtins; - import gcc.config; - version (GNU_StackGrowsDown) - version = StackGrowsDown; -} -else -{ - // this should be true for most architectures - version = StackGrowsDown; -} - -/** - * Returns the process ID of the calling process, which is guaranteed to be - * unique on the system. This call is always successful. - * - * Example: - * --- - * writefln("Current process id: %s", getpid()); - * --- - */ -version (Posix) -{ - alias getpid = core.sys.posix.unistd.getpid; -} -else version (Windows) -{ - alias getpid = core.sys.windows.windows.GetCurrentProcessId; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Thread and Fiber Exceptions -/////////////////////////////////////////////////////////////////////////////// - - -/** - * Base class for thread exceptions. - */ -class ThreadException : Exception -{ - @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) - { - super(msg, file, line, next); - } - - @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) - { - super(msg, file, line, next); - } -} - - -/** -* Base class for thread errors to be used for function inside GC when allocations are unavailable. -*/ -class ThreadError : Error -{ - @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) - { - super(msg, file, line, next); - } - - @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) - { - super(msg, file, line, next); - } -} - -private -{ - import core.atomic, core.memory, core.sync.mutex; - - // Handling unaligned mutexes are not supported on all platforms, so we must - // ensure that the address of all shared data are appropriately aligned. - import core.internal.traits : classInstanceAlignment; - - enum mutexAlign = classInstanceAlignment!Mutex; - enum mutexClassInstanceSize = __traits(classInstanceSize, Mutex); - - // - // exposed by compiler runtime - // - extern (C) void rt_moduleTlsCtor(); - extern (C) void rt_moduleTlsDtor(); - - /** - * Hook for whatever EH implementation is used to save/restore some data - * per stack. - * - * Params: - * newContext = The return value of the prior call to this function - * where the stack was last swapped out, or null when a fiber stack - * is switched in for the first time. - */ - extern(C) void* _d_eh_swapContext(void* newContext) nothrow @nogc; - - version (DigitalMars) - { - version (Windows) - alias swapContext = _d_eh_swapContext; - else - { - extern(C) void* _d_eh_swapContextDwarf(void* newContext) nothrow @nogc; - - void* swapContext(void* newContext) nothrow @nogc - { - /* Detect at runtime which scheme is being used. - * Eventually, determine it statically. - */ - static int which = 0; - final switch (which) - { - case 0: - { - assert(newContext == null); - auto p = _d_eh_swapContext(newContext); - auto pdwarf = _d_eh_swapContextDwarf(newContext); - if (p) - { - which = 1; - return p; - } - else if (pdwarf) - { - which = 2; - return pdwarf; - } - return null; - } - case 1: - return _d_eh_swapContext(newContext); - case 2: - return _d_eh_swapContextDwarf(newContext); - } - } - } - } - else - alias swapContext = _d_eh_swapContext; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Thread Entry Point and Signal Handlers -/////////////////////////////////////////////////////////////////////////////// - - -version (Windows) -{ - private - { - import core.stdc.stdint : uintptr_t; // for _beginthreadex decl below - import core.stdc.stdlib; // for malloc, atexit - import core.sys.windows.windows; - import core.sys.windows.threadaux; // for OpenThreadHandle - - extern (Windows) alias btex_fptr = uint function(void*); - extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*) nothrow; - - // - // Entry point for Windows threads - // - extern (Windows) uint thread_entryPoint( void* arg ) nothrow - { - Thread obj = cast(Thread) arg; - assert( obj ); - - assert( obj.m_curr is &obj.m_main ); - obj.m_main.bstack = getStackBottom(); - obj.m_main.tstack = obj.m_main.bstack; - obj.m_tlsgcdata = rt_tlsgc_init(); - - Thread.setThis(obj); - Thread.add(obj); - scope (exit) - { - Thread.remove(obj); - } - Thread.add(&obj.m_main); - - // NOTE: No GC allocations may occur until the stack pointers have - // been set and Thread.getThis returns a valid reference to - // this thread object (this latter condition is not strictly - // necessary on Windows but it should be followed for the - // sake of consistency). - - // TODO: Consider putting an auto exception object here (using - // alloca) forOutOfMemoryError plus something to track - // whether an exception is in-flight? - - void append( Throwable t ) - { - if ( obj.m_unhandled is null ) - obj.m_unhandled = t; - else - { - Throwable last = obj.m_unhandled; - while ( last.next !is null ) - last = last.next; - last.next = t; - } - } - - version (D_InlineAsm_X86) - { - asm nothrow @nogc { fninit; } - } - - try - { - rt_moduleTlsCtor(); - try - { - obj.run(); - } - catch ( Throwable t ) - { - append( t ); - } - rt_moduleTlsDtor(); - } - catch ( Throwable t ) - { - append( t ); - } - return 0; - } - - - HANDLE GetCurrentThreadHandle() nothrow @nogc - { - const uint DUPLICATE_SAME_ACCESS = 0x00000002; - - HANDLE curr = GetCurrentThread(), - proc = GetCurrentProcess(), - hndl; - - DuplicateHandle( proc, curr, proc, &hndl, 0, TRUE, DUPLICATE_SAME_ACCESS ); - return hndl; - } - } -} -else version (Posix) -{ - private - { - import core.stdc.errno; - import core.sys.posix.semaphore; - import core.sys.posix.stdlib; // for malloc, valloc, free, atexit - import core.sys.posix.pthread; - import core.sys.posix.signal; - import core.sys.posix.time; - - version (Darwin) - { - import core.sys.darwin.mach.thread_act; - import core.sys.darwin.pthread : pthread_mach_thread_np; - } - - // - // Entry point for POSIX threads - // - extern (C) void* thread_entryPoint( void* arg ) nothrow - { - version (Shared) - { - import rt.sections; - Thread obj = cast(Thread)(cast(void**)arg)[0]; - auto loadedLibraries = (cast(void**)arg)[1]; - .free(arg); - } - else - { - Thread obj = cast(Thread)arg; - } - assert( obj ); - - // loadedLibraries need to be inherited from parent thread - // before initilizing GC for TLS (rt_tlsgc_init) - version (Shared) inheritLoadedLibraries(loadedLibraries); - - assert( obj.m_curr is &obj.m_main ); - obj.m_main.bstack = getStackBottom(); - obj.m_main.tstack = obj.m_main.bstack; - obj.m_tlsgcdata = rt_tlsgc_init(); - - atomicStore!(MemoryOrder.raw)(obj.m_isRunning, true); - Thread.setThis(obj); // allocates lazy TLS (see Issue 11981) - Thread.add(obj); // can only receive signals from here on - scope (exit) - { - Thread.remove(obj); - atomicStore!(MemoryOrder.raw)(obj.m_isRunning, false); - } - Thread.add(&obj.m_main); - - static extern (C) void thread_cleanupHandler( void* arg ) nothrow @nogc - { - Thread obj = cast(Thread) arg; - assert( obj ); - - // NOTE: If the thread terminated abnormally, just set it as - // not running and let thread_suspendAll remove it from - // the thread list. This is safer and is consistent - // with the Windows thread code. - atomicStore!(MemoryOrder.raw)(obj.m_isRunning,false); - } - - // NOTE: Using void to skip the initialization here relies on - // knowledge of how pthread_cleanup is implemented. It may - // not be appropriate for all platforms. However, it does - // avoid the need to link the pthread module. If any - // implementation actually requires default initialization - // then pthread_cleanup should be restructured to maintain - // the current lack of a link dependency. - static if ( __traits( compiles, pthread_cleanup ) ) - { - pthread_cleanup cleanup = void; - cleanup.push( &thread_cleanupHandler, cast(void*) obj ); - } - else static if ( __traits( compiles, pthread_cleanup_push ) ) - { - pthread_cleanup_push( &thread_cleanupHandler, cast(void*) obj ); - } - else - { - static assert( false, "Platform not supported." ); - } - - // NOTE: No GC allocations may occur until the stack pointers have - // been set and Thread.getThis returns a valid reference to - // this thread object (this latter condition is not strictly - // necessary on Windows but it should be followed for the - // sake of consistency). - - // TODO: Consider putting an auto exception object here (using - // alloca) forOutOfMemoryError plus something to track - // whether an exception is in-flight? - - void append( Throwable t ) - { - if ( obj.m_unhandled is null ) - obj.m_unhandled = t; - else - { - Throwable last = obj.m_unhandled; - while ( last.next !is null ) - last = last.next; - last.next = t; - } - } - - try - { - rt_moduleTlsCtor(); - try - { - obj.run(); - } - catch ( Throwable t ) - { - append( t ); - } - rt_moduleTlsDtor(); - version (Shared) cleanupLoadedLibraries(); - } - catch ( Throwable t ) - { - append( t ); - } - - // NOTE: Normal cleanup is handled by scope(exit). - - static if ( __traits( compiles, pthread_cleanup ) ) - { - cleanup.pop( 0 ); - } - else static if ( __traits( compiles, pthread_cleanup_push ) ) - { - pthread_cleanup_pop( 0 ); - } - - return null; - } - - - // - // Used to track the number of suspended threads - // - __gshared sem_t suspendCount; - - - extern (C) void thread_suspendHandler( int sig ) nothrow - in - { - assert( sig == suspendSignalNumber ); - } - body - { - void op(void* sp) nothrow - { - // NOTE: Since registers are being pushed and popped from the - // stack, any other stack data used by this function should - // be gone before the stack cleanup code is called below. - Thread obj = Thread.getThis(); - assert(obj !is null); - - if ( !obj.m_lock ) - { - obj.m_curr.tstack = getStackTop(); - } - - sigset_t sigres = void; - int status; - - status = sigfillset( &sigres ); - assert( status == 0 ); - - status = sigdelset( &sigres, resumeSignalNumber ); - assert( status == 0 ); - - version (FreeBSD) obj.m_suspendagain = false; - status = sem_post( &suspendCount ); - assert( status == 0 ); - - sigsuspend( &sigres ); - - if ( !obj.m_lock ) - { - obj.m_curr.tstack = obj.m_curr.bstack; - } - } - - // avoid deadlocks on FreeBSD, see Issue 13416 - version (FreeBSD) - { - auto obj = Thread.getThis(); - if (THR_IN_CRITICAL(obj.m_addr)) - { - obj.m_suspendagain = true; - if (sem_post(&suspendCount)) assert(0); - return; - } - } - - callWithStackShell(&op); - } - - - extern (C) void thread_resumeHandler( int sig ) nothrow - in - { - assert( sig == resumeSignalNumber ); - } - body - { - - } - - // HACK libthr internal (thr_private.h) macro, used to - // avoid deadlocks in signal handler, see Issue 13416 - version (FreeBSD) bool THR_IN_CRITICAL(pthread_t p) nothrow @nogc - { - import core.sys.posix.config : c_long; - import core.sys.posix.sys.types : lwpid_t; - - // If the begin of pthread would be changed in libthr (unlikely) - // we'll run into undefined behavior, compare with thr_private.h. - static struct pthread - { - c_long tid; - static struct umutex { lwpid_t owner; uint flags; uint[2] ceilings; uint[4] spare; } - umutex lock; - uint cycle; - int locklevel; - int critical_count; - // ... - } - auto priv = cast(pthread*)p; - return priv.locklevel > 0 || priv.critical_count > 0; - } - } -} -else -{ - // NOTE: This is the only place threading versions are checked. If a new - // version is added, the module code will need to be searched for - // places where version-specific code may be required. This can be - // easily accomlished by searching for 'Windows' or 'Posix'. - static assert( false, "Unknown threading implementation." ); -} - - -/////////////////////////////////////////////////////////////////////////////// -// Thread -/////////////////////////////////////////////////////////////////////////////// - - -/** - * This class encapsulates all threading functionality for the D - * programming language. As thread manipulation is a required facility - * for garbage collection, all user threads should derive from this - * class, and instances of this class should never be explicitly deleted. - * A new thread may be created using either derivation or composition, as - * in the following example. - */ -class Thread -{ - /////////////////////////////////////////////////////////////////////////// - // Initialization - /////////////////////////////////////////////////////////////////////////// - - - /** - * Initializes a thread object which is associated with a static - * D function. - * - * Params: - * fn = The thread function. - * sz = The stack size for this thread. - * - * In: - * fn must not be null. - */ - this( void function() fn, size_t sz = 0 ) @safe pure nothrow @nogc - in - { - assert( fn ); - } - body - { - this(sz); - () @trusted { m_fn = fn; }(); - m_call = Call.FN; - m_curr = &m_main; - } - - - /** - * Initializes a thread object which is associated with a dynamic - * D function. - * - * Params: - * dg = The thread function. - * sz = The stack size for this thread. - * - * In: - * dg must not be null. - */ - this( void delegate() dg, size_t sz = 0 ) @safe pure nothrow @nogc - in - { - assert( dg ); - } - body - { - this(sz); - () @trusted { m_dg = dg; }(); - m_call = Call.DG; - m_curr = &m_main; - } - - - /** - * Cleans up any remaining resources used by this object. - */ - ~this() nothrow @nogc - { - if ( m_addr == m_addr.init ) - { - return; - } - - version (Windows) - { - m_addr = m_addr.init; - CloseHandle( m_hndl ); - m_hndl = m_hndl.init; - } - else version (Posix) - { - pthread_detach( m_addr ); - m_addr = m_addr.init; - } - version (Darwin) - { - m_tmach = m_tmach.init; - } - rt_tlsgc_destroy( m_tlsgcdata ); - m_tlsgcdata = null; - } - - - /////////////////////////////////////////////////////////////////////////// - // General Actions - /////////////////////////////////////////////////////////////////////////// - - - /** - * Starts the thread and invokes the function or delegate passed upon - * construction. - * - * In: - * This routine may only be called once per thread instance. - * - * Throws: - * ThreadException if the thread fails to start. - */ - final Thread start() nothrow - in - { - assert( !next && !prev ); - } - body - { - auto wasThreaded = multiThreadedFlag; - multiThreadedFlag = true; - scope( failure ) - { - if ( !wasThreaded ) - multiThreadedFlag = false; - } - - version (Windows) {} else - version (Posix) - { - pthread_attr_t attr; - - if ( pthread_attr_init( &attr ) ) - onThreadError( "Error initializing thread attributes" ); - if ( m_sz && pthread_attr_setstacksize( &attr, m_sz ) ) - onThreadError( "Error initializing thread stack size" ); - } - - version (Windows) - { - // NOTE: If a thread is just executing DllMain() - // while another thread is started here, it holds an OS internal - // lock that serializes DllMain with CreateThread. As the code - // might request a synchronization on slock (e.g. in thread_findByAddr()), - // we cannot hold that lock while creating the thread without - // creating a deadlock - // - // Solution: Create the thread in suspended state and then - // add and resume it with slock acquired - assert(m_sz <= uint.max, "m_sz must be less than or equal to uint.max"); - m_hndl = cast(HANDLE) _beginthreadex( null, cast(uint) m_sz, &thread_entryPoint, cast(void*) this, CREATE_SUSPENDED, &m_addr ); - if ( cast(size_t) m_hndl == 0 ) - onThreadError( "Error creating thread" ); - } - - slock.lock_nothrow(); - scope(exit) slock.unlock_nothrow(); - { - ++nAboutToStart; - pAboutToStart = cast(Thread*)realloc(pAboutToStart, Thread.sizeof * nAboutToStart); - pAboutToStart[nAboutToStart - 1] = this; - version (Windows) - { - if ( ResumeThread( m_hndl ) == -1 ) - onThreadError( "Error resuming thread" ); - } - else version (Posix) - { - // NOTE: This is also set to true by thread_entryPoint, but set it - // here as well so the calling thread will see the isRunning - // state immediately. - atomicStore!(MemoryOrder.raw)(m_isRunning, true); - scope( failure ) atomicStore!(MemoryOrder.raw)(m_isRunning, false); - - version (Shared) - { - import rt.sections; - auto libs = pinLoadedLibraries(); - auto ps = cast(void**).malloc(2 * size_t.sizeof); - if (ps is null) onOutOfMemoryError(); - ps[0] = cast(void*)this; - ps[1] = cast(void*)libs; - if ( pthread_create( &m_addr, &attr, &thread_entryPoint, ps ) != 0 ) - { - unpinLoadedLibraries(libs); - .free(ps); - onThreadError( "Error creating thread" ); - } - } - else - { - if ( pthread_create( &m_addr, &attr, &thread_entryPoint, cast(void*) this ) != 0 ) - onThreadError( "Error creating thread" ); - } - } - version (Darwin) - { - m_tmach = pthread_mach_thread_np( m_addr ); - if ( m_tmach == m_tmach.init ) - onThreadError( "Error creating thread" ); - } - - return this; - } - } - - /** - * Waits for this thread to complete. If the thread terminated as the - * result of an unhandled exception, this exception will be rethrown. - * - * Params: - * rethrow = Rethrow any unhandled exception which may have caused this - * thread to terminate. - * - * Throws: - * ThreadException if the operation fails. - * Any exception not handled by the joined thread. - * - * Returns: - * Any exception not handled by this thread if rethrow = false, null - * otherwise. - */ - final Throwable join( bool rethrow = true ) - { - version (Windows) - { - if ( WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 ) - throw new ThreadException( "Unable to join thread" ); - // NOTE: m_addr must be cleared before m_hndl is closed to avoid - // a race condition with isRunning. The operation is done - // with atomicStore to prevent compiler reordering. - atomicStore!(MemoryOrder.raw)(*cast(shared)&m_addr, m_addr.init); - CloseHandle( m_hndl ); - m_hndl = m_hndl.init; - } - else version (Posix) - { - if ( pthread_join( m_addr, null ) != 0 ) - throw new ThreadException( "Unable to join thread" ); - // NOTE: pthread_join acts as a substitute for pthread_detach, - // which is normally called by the dtor. Setting m_addr - // to zero ensures that pthread_detach will not be called - // on object destruction. - m_addr = m_addr.init; - } - if ( m_unhandled ) - { - if ( rethrow ) - throw m_unhandled; - return m_unhandled; - } - return null; - } - - - /////////////////////////////////////////////////////////////////////////// - // General Properties - /////////////////////////////////////////////////////////////////////////// - - - /** - * Gets the OS identifier for this thread. - * - * Returns: - * If the thread hasn't been started yet, returns $(LREF ThreadID)$(D.init). - * Otherwise, returns the result of $(D GetCurrentThreadId) on Windows, - * and $(D pthread_self) on POSIX. - * - * The value is unique for the current process. - */ - final @property ThreadID id() @safe @nogc - { - synchronized( this ) - { - return m_addr; - } - } - - - /** - * Gets the user-readable label for this thread. - * - * Returns: - * The name of this thread. - */ - final @property string name() @safe @nogc - { - synchronized( this ) - { - return m_name; - } - } - - - /** - * Sets the user-readable label for this thread. - * - * Params: - * val = The new name of this thread. - */ - final @property void name( string val ) @safe @nogc - { - synchronized( this ) - { - m_name = val; - } - } - - - /** - * Gets the daemon status for this thread. While the runtime will wait for - * all normal threads to complete before tearing down the process, daemon - * threads are effectively ignored and thus will not prevent the process - * from terminating. In effect, daemon threads will be terminated - * automatically by the OS when the process exits. - * - * Returns: - * true if this is a daemon thread. - */ - final @property bool isDaemon() @safe @nogc - { - synchronized( this ) - { - return m_isDaemon; - } - } - - - /** - * Sets the daemon status for this thread. While the runtime will wait for - * all normal threads to complete before tearing down the process, daemon - * threads are effectively ignored and thus will not prevent the process - * from terminating. In effect, daemon threads will be terminated - * automatically by the OS when the process exits. - * - * Params: - * val = The new daemon status for this thread. - */ - final @property void isDaemon( bool val ) @safe @nogc - { - synchronized( this ) - { - m_isDaemon = val; - } - } - - - /** - * Tests whether this thread is running. - * - * Returns: - * true if the thread is running, false if not. - */ - final @property bool isRunning() nothrow @nogc - { - if ( m_addr == m_addr.init ) - { - return false; - } - - version (Windows) - { - uint ecode = 0; - GetExitCodeThread( m_hndl, &ecode ); - return ecode == STILL_ACTIVE; - } - else version (Posix) - { - return atomicLoad(m_isRunning); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Thread Priority Actions - /////////////////////////////////////////////////////////////////////////// - - version (Windows) - { - @property static int PRIORITY_MIN() @nogc nothrow pure @safe - { - return THREAD_PRIORITY_IDLE; - } - - @property static const(int) PRIORITY_MAX() @nogc nothrow pure @safe - { - return THREAD_PRIORITY_TIME_CRITICAL; - } - - @property static int PRIORITY_DEFAULT() @nogc nothrow pure @safe - { - return THREAD_PRIORITY_NORMAL; - } - } - else - { - private struct Priority - { - int PRIORITY_MIN = int.min; - int PRIORITY_DEFAULT = int.min; - int PRIORITY_MAX = int.min; - } - - /* - Lazily loads one of the members stored in a hidden global variable of - type `Priority`. Upon the first access of either member, the entire - `Priority` structure is initialized. Multiple initializations from - different threads calling this function are tolerated. - - `which` must be one of `PRIORITY_MIN`, `PRIORITY_DEFAULT`, - `PRIORITY_MAX`. - */ - private static int loadGlobal(string which)() - { - static shared Priority cache; - auto local = atomicLoad(mixin("cache." ~ which)); - if (local != local.min) return local; - // There will be benign races - cache = loadPriorities; - return atomicLoad(mixin("cache." ~ which)); - } - - /* - Loads all priorities and returns them as a `Priority` structure. This - function is thread-neutral. - */ - private static Priority loadPriorities() @nogc nothrow @trusted - { - Priority result; - version (Solaris) - { - pcparms_t pcParms; - pcinfo_t pcInfo; - - pcParms.pc_cid = PC_CLNULL; - if (priocntl(idtype_t.P_PID, P_MYID, PC_GETPARMS, &pcParms) == -1) - assert( 0, "Unable to get scheduling class" ); - - pcInfo.pc_cid = pcParms.pc_cid; - // PC_GETCLINFO ignores the first two args, use dummy values - if (priocntl(idtype_t.P_PID, 0, PC_GETCLINFO, &pcInfo) == -1) - assert( 0, "Unable to get scheduling class info" ); - - pri_t* clparms = cast(pri_t*)&pcParms.pc_clparms; - pri_t* clinfo = cast(pri_t*)&pcInfo.pc_clinfo; - - result.PRIORITY_MAX = clparms[0]; - - if (pcInfo.pc_clname == "RT") - { - m_isRTClass = true; - - // For RT class, just assume it can't be changed - result.PRIORITY_MIN = clparms[0]; - result.PRIORITY_DEFAULT = clparms[0]; - } - else - { - m_isRTClass = false; - - // For all other scheduling classes, there are - // two key values -- uprilim and maxupri. - // maxupri is the maximum possible priority defined - // for the scheduling class, and valid priorities - // range are in [-maxupri, maxupri]. - // - // However, uprilim is an upper limit that the - // current thread can set for the current scheduling - // class, which can be less than maxupri. As such, - // use this value for priorityMax since this is - // the effective maximum. - - // maxupri - result.PRIORITY_MIN = -clinfo[0]; - // by definition - result.PRIORITY_DEFAULT = 0; - } - } - else version (Posix) - { - int policy; - sched_param param; - pthread_getschedparam( pthread_self(), &policy, ¶m ) == 0 - || assert(0, "Internal error in pthread_getschedparam"); - - result.PRIORITY_MIN = sched_get_priority_min( policy ); - result.PRIORITY_MIN != -1 - || assert(0, "Internal error in sched_get_priority_min"); - result.PRIORITY_DEFAULT = param.sched_priority; - result.PRIORITY_MAX = sched_get_priority_max( policy ); - result.PRIORITY_MAX != -1 || - assert(0, "Internal error in sched_get_priority_max"); - } - else - { - static assert(0, "Your code here."); - } - return result; - } - - /** - * The minimum scheduling priority that may be set for a thread. On - * systems where multiple scheduling policies are defined, this value - * represents the minimum valid priority for the scheduling policy of - * the process. - */ - @property static int PRIORITY_MIN() @nogc nothrow pure @trusted - { - return (cast(int function() @nogc nothrow pure @safe) - &loadGlobal!"PRIORITY_MIN")(); - } - - /** - * The maximum scheduling priority that may be set for a thread. On - * systems where multiple scheduling policies are defined, this value - * represents the maximum valid priority for the scheduling policy of - * the process. - */ - @property static const(int) PRIORITY_MAX() @nogc nothrow pure @trusted - { - return (cast(int function() @nogc nothrow pure @safe) - &loadGlobal!"PRIORITY_MAX")(); - } - - /** - * The default scheduling priority that is set for a thread. On - * systems where multiple scheduling policies are defined, this value - * represents the default priority for the scheduling policy of - * the process. - */ - @property static int PRIORITY_DEFAULT() @nogc nothrow pure @trusted - { - return (cast(int function() @nogc nothrow pure @safe) - &loadGlobal!"PRIORITY_DEFAULT")(); - } - } - - version (NetBSD) - { - //NetBSD does not support priority for default policy - // and it is not possible change policy without root access - int fakePriority = int.max; - } - - /** - * Gets the scheduling priority for the associated thread. - * - * Note: Getting the priority of a thread that already terminated - * might return the default priority. - * - * Returns: - * The scheduling priority of this thread. - */ - final @property int priority() - { - version (Windows) - { - return GetThreadPriority( m_hndl ); - } - else version (NetBSD) - { - return fakePriority==int.max? PRIORITY_DEFAULT : fakePriority; - } - else version (Posix) - { - int policy; - sched_param param; - - if (auto err = pthread_getschedparam(m_addr, &policy, ¶m)) - { - // ignore error if thread is not running => Bugzilla 8960 - if (!atomicLoad(m_isRunning)) return PRIORITY_DEFAULT; - throw new ThreadException("Unable to get thread priority"); - } - return param.sched_priority; - } - } - - - /** - * Sets the scheduling priority for the associated thread. - * - * Note: Setting the priority of a thread that already terminated - * might have no effect. - * - * Params: - * val = The new scheduling priority of this thread. - */ - final @property void priority( int val ) - in - { - assert(val >= PRIORITY_MIN); - assert(val <= PRIORITY_MAX); - } - body - { - version (Windows) - { - if ( !SetThreadPriority( m_hndl, val ) ) - throw new ThreadException( "Unable to set thread priority" ); - } - else version (Solaris) - { - // the pthread_setschedprio(3c) and pthread_setschedparam functions - // are broken for the default (TS / time sharing) scheduling class. - // instead, we use priocntl(2) which gives us the desired behavior. - - // We hardcode the min and max priorities to the current value - // so this is a no-op for RT threads. - if (m_isRTClass) - return; - - pcparms_t pcparm; - - pcparm.pc_cid = PC_CLNULL; - if (priocntl(idtype_t.P_LWPID, P_MYID, PC_GETPARMS, &pcparm) == -1) - throw new ThreadException( "Unable to get scheduling class" ); - - pri_t* clparms = cast(pri_t*)&pcparm.pc_clparms; - - // clparms is filled in by the PC_GETPARMS call, only necessary - // to adjust the element that contains the thread priority - clparms[1] = cast(pri_t) val; - - if (priocntl(idtype_t.P_LWPID, P_MYID, PC_SETPARMS, &pcparm) == -1) - throw new ThreadException( "Unable to set scheduling class" ); - } - else version (NetBSD) - { - fakePriority = val; - } - else version (Posix) - { - static if (__traits(compiles, pthread_setschedprio)) - { - if (auto err = pthread_setschedprio(m_addr, val)) - { - // ignore error if thread is not running => Bugzilla 8960 - if (!atomicLoad(m_isRunning)) return; - throw new ThreadException("Unable to set thread priority"); - } - } - else - { - // NOTE: pthread_setschedprio is not implemented on Darwin, FreeBSD, OpenBSD, - // or DragonFlyBSD, so use the more complicated get/set sequence below. - int policy; - sched_param param; - - if (auto err = pthread_getschedparam(m_addr, &policy, ¶m)) - { - // ignore error if thread is not running => Bugzilla 8960 - if (!atomicLoad(m_isRunning)) return; - throw new ThreadException("Unable to set thread priority"); - } - param.sched_priority = val; - if (auto err = pthread_setschedparam(m_addr, policy, ¶m)) - { - // ignore error if thread is not running => Bugzilla 8960 - if (!atomicLoad(m_isRunning)) return; - throw new ThreadException("Unable to set thread priority"); - } - } - } - } - - - unittest - { - auto thr = Thread.getThis(); - immutable prio = thr.priority; - scope (exit) thr.priority = prio; - - assert(prio == PRIORITY_DEFAULT); - assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX); - thr.priority = PRIORITY_MIN; - assert(thr.priority == PRIORITY_MIN); - thr.priority = PRIORITY_MAX; - assert(thr.priority == PRIORITY_MAX); - } - - unittest // Bugzilla 8960 - { - import core.sync.semaphore; - - auto thr = new Thread({}); - thr.start(); - Thread.sleep(1.msecs); // wait a little so the thread likely has finished - thr.priority = PRIORITY_MAX; // setting priority doesn't cause error - auto prio = thr.priority; // getting priority doesn't cause error - assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX); - } - - /////////////////////////////////////////////////////////////////////////// - // Actions on Calling Thread - /////////////////////////////////////////////////////////////////////////// - - - /** - * Suspends the calling thread for at least the supplied period. This may - * result in multiple OS calls if period is greater than the maximum sleep - * duration supported by the operating system. - * - * Params: - * val = The minimum duration the calling thread should be suspended. - * - * In: - * period must be non-negative. - * - * Example: - * ------------------------------------------------------------------------ - * - * Thread.sleep( dur!("msecs")( 50 ) ); // sleep for 50 milliseconds - * Thread.sleep( dur!("seconds")( 5 ) ); // sleep for 5 seconds - * - * ------------------------------------------------------------------------ - */ - static void sleep( Duration val ) @nogc nothrow - in - { - assert( !val.isNegative ); - } - body - { - version (Windows) - { - auto maxSleepMillis = dur!("msecs")( uint.max - 1 ); - - // avoid a non-zero time to be round down to 0 - if ( val > dur!"msecs"( 0 ) && val < dur!"msecs"( 1 ) ) - val = dur!"msecs"( 1 ); - - // NOTE: In instances where all other threads in the process have a - // lower priority than the current thread, the current thread - // will not yield with a sleep time of zero. However, unlike - // yield(), the user is not asking for a yield to occur but - // only for execution to suspend for the requested interval. - // Therefore, expected performance may not be met if a yield - // is forced upon the user. - while ( val > maxSleepMillis ) - { - Sleep( cast(uint) - maxSleepMillis.total!"msecs" ); - val -= maxSleepMillis; - } - Sleep( cast(uint) val.total!"msecs" ); - } - else version (Posix) - { - timespec tin = void; - timespec tout = void; - - val.split!("seconds", "nsecs")(tin.tv_sec, tin.tv_nsec); - if ( val.total!"seconds" > tin.tv_sec.max ) - tin.tv_sec = tin.tv_sec.max; - while ( true ) - { - if ( !nanosleep( &tin, &tout ) ) - return; - if ( errno != EINTR ) - assert(0, "Unable to sleep for the specified duration"); - tin = tout; - } - } - } - - - /** - * Forces a context switch to occur away from the calling thread. - */ - static void yield() @nogc nothrow - { - version (Windows) - SwitchToThread(); - else version (Posix) - sched_yield(); - } - - - /////////////////////////////////////////////////////////////////////////// - // Thread Accessors - /////////////////////////////////////////////////////////////////////////// - - /** - * Provides a reference to the calling thread. - * - * Returns: - * The thread object representing the calling thread. The result of - * deleting this object is undefined. If the current thread is not - * attached to the runtime, a null reference is returned. - */ - static Thread getThis() @safe nothrow @nogc - { - // NOTE: This function may not be called until thread_init has - // completed. See thread_suspendAll for more information - // on why this might occur. - return sm_this; - } - - - /** - * Provides a list of all threads currently being tracked by the system. - * Note that threads in the returned array might no longer run (see - * $(D Thread.)$(LREF isRunning)). - * - * Returns: - * An array containing references to all threads currently being - * tracked by the system. The result of deleting any contained - * objects is undefined. - */ - static Thread[] getAll() - { - static void resize(ref Thread[] buf, size_t nlen) - { - buf.length = nlen; - } - return getAllImpl!resize(); - } - - - /** - * Operates on all threads currently being tracked by the system. The - * result of deleting any Thread object is undefined. - * Note that threads passed to the callback might no longer run (see - * $(D Thread.)$(LREF isRunning)). - * - * Params: - * dg = The supplied code as a delegate. - * - * Returns: - * Zero if all elemented are visited, nonzero if not. - */ - static int opApply(scope int delegate(ref Thread) dg) - { - import core.stdc.stdlib : free, realloc; - - static void resize(ref Thread[] buf, size_t nlen) - { - buf = (cast(Thread*)realloc(buf.ptr, nlen * Thread.sizeof))[0 .. nlen]; - } - auto buf = getAllImpl!resize; - scope(exit) if (buf.ptr) free(buf.ptr); - - foreach (t; buf) - { - if (auto res = dg(t)) - return res; - } - return 0; - } - - unittest - { - auto t1 = new Thread({ - foreach (_; 0 .. 20) - Thread.getAll; - }).start; - auto t2 = new Thread({ - foreach (_; 0 .. 20) - GC.collect; - }).start; - t1.join(); - t2.join(); - } - - private static Thread[] getAllImpl(alias resize)() - { - import core.atomic; - - Thread[] buf; - while (true) - { - immutable len = atomicLoad!(MemoryOrder.raw)(*cast(shared)&sm_tlen); - resize(buf, len); - assert(buf.length == len); - synchronized (slock) - { - if (len == sm_tlen) - { - size_t pos; - for (Thread t = sm_tbeg; t; t = t.next) - buf[pos++] = t; - return buf; - } - } - } - } - - /////////////////////////////////////////////////////////////////////////// - // Stuff That Should Go Away - /////////////////////////////////////////////////////////////////////////// - - -private: - // - // Initializes a thread object which has no associated executable function. - // This is used for the main thread initialized in thread_init(). - // - this(size_t sz = 0) @safe pure nothrow @nogc - { - if (sz) - { - version (Posix) - { - // stack size must be a multiple of PAGESIZE - sz += PAGESIZE - 1; - sz -= sz % PAGESIZE; - // and at least PTHREAD_STACK_MIN - if (PTHREAD_STACK_MIN > sz) - sz = PTHREAD_STACK_MIN; - } - m_sz = sz; - } - m_call = Call.NO; - m_curr = &m_main; - } - - - // - // Thread entry point. Invokes the function or delegate passed on - // construction (if any). - // - final void run() - { - switch ( m_call ) - { - case Call.FN: - m_fn(); - break; - case Call.DG: - m_dg(); - break; - default: - break; - } - } - - -private: - // - // The type of routine passed on thread construction. - // - enum Call - { - NO, - FN, - DG - } - - - // - // Standard types - // - version (Windows) - { - alias TLSKey = uint; - } - else version (Posix) - { - alias TLSKey = pthread_key_t; - } - - - // - // Local storage - // - static Thread sm_this; - - - // - // Main process thread - // - __gshared Thread sm_main; - - version (FreeBSD) - { - // set when suspend failed and should be retried, see Issue 13416 - shared bool m_suspendagain; - } - - - // - // Standard thread data - // - version (Windows) - { - HANDLE m_hndl; - } - else version (Darwin) - { - mach_port_t m_tmach; - } - ThreadID m_addr; - Call m_call; - string m_name; - union - { - void function() m_fn; - void delegate() m_dg; - } - size_t m_sz; - version (Posix) - { - shared bool m_isRunning; - } - bool m_isDaemon; - bool m_isInCriticalRegion; - Throwable m_unhandled; - - version (Solaris) - { - __gshared bool m_isRTClass; - } - -private: - /////////////////////////////////////////////////////////////////////////// - // Storage of Active Thread - /////////////////////////////////////////////////////////////////////////// - - - // - // Sets a thread-local reference to the current thread object. - // - static void setThis( Thread t ) nothrow @nogc - { - sm_this = t; - } - - -private: - /////////////////////////////////////////////////////////////////////////// - // Thread Context and GC Scanning Support - /////////////////////////////////////////////////////////////////////////// - - - final void pushContext( Context* c ) nothrow @nogc - in - { - assert( !c.within ); - } - body - { - m_curr.ehContext = swapContext(c.ehContext); - c.within = m_curr; - m_curr = c; - } - - - final void popContext() nothrow @nogc - in - { - assert( m_curr && m_curr.within ); - } - body - { - Context* c = m_curr; - m_curr = c.within; - c.ehContext = swapContext(m_curr.ehContext); - c.within = null; - } - - - final Context* topContext() nothrow @nogc - in - { - assert( m_curr ); - } - body - { - return m_curr; - } - - - static struct Context - { - void* bstack, - tstack; - - /// Slot for the EH implementation to keep some state for each stack - /// (will be necessary for exception chaining, etc.). Opaque as far as - /// we are concerned here. - void* ehContext; - - Context* within; - Context* next, - prev; - } - - - Context m_main; - Context* m_curr; - bool m_lock; - void* m_tlsgcdata; - - version (Windows) - { - version (X86) - { - uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax - } - else version (X86_64) - { - ulong[16] m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax - // r8,r9,r10,r11,r12,r13,r14,r15 - } - else - { - static assert(false, "Architecture not supported." ); - } - } - else version (Darwin) - { - version (X86) - { - uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax - } - else version (X86_64) - { - ulong[16] m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax - // r8,r9,r10,r11,r12,r13,r14,r15 - } - else - { - static assert(false, "Architecture not supported." ); - } - } - - -private: - /////////////////////////////////////////////////////////////////////////// - // GC Scanning Support - /////////////////////////////////////////////////////////////////////////// - - - // NOTE: The GC scanning process works like so: - // - // 1. Suspend all threads. - // 2. Scan the stacks of all suspended threads for roots. - // 3. Resume all threads. - // - // Step 1 and 3 require a list of all threads in the system, while - // step 2 requires a list of all thread stacks (each represented by - // a Context struct). Traditionally, there was one stack per thread - // and the Context structs were not necessary. However, Fibers have - // changed things so that each thread has its own 'main' stack plus - // an arbitrary number of nested stacks (normally referenced via - // m_curr). Also, there may be 'free-floating' stacks in the system, - // which are Fibers that are not currently executing on any specific - // thread but are still being processed and still contain valid - // roots. - // - // To support all of this, the Context struct has been created to - // represent a stack range, and a global list of Context structs has - // been added to enable scanning of these stack ranges. The lifetime - // (and presence in the Context list) of a thread's 'main' stack will - // be equivalent to the thread's lifetime. So the Ccontext will be - // added to the list on thread entry, and removed from the list on - // thread exit (which is essentially the same as the presence of a - // Thread object in its own global list). The lifetime of a Fiber's - // context, however, will be tied to the lifetime of the Fiber object - // itself, and Fibers are expected to add/remove their Context struct - // on construction/deletion. - - - // - // All use of the global thread lists/array should synchronize on this lock. - // - // Careful as the GC acquires this lock after the GC lock to suspend all - // threads any GC usage with slock held can result in a deadlock through - // lock order inversion. - @property static Mutex slock() nothrow @nogc - { - return cast(Mutex)_slock.ptr; - } - - @property static Mutex criticalRegionLock() nothrow @nogc - { - return cast(Mutex)_criticalRegionLock.ptr; - } - - __gshared align(mutexAlign) void[mutexClassInstanceSize] _slock; - __gshared align(mutexAlign) void[mutexClassInstanceSize] _criticalRegionLock; - - static void initLocks() - { - _slock[] = typeid(Mutex).initializer[]; - (cast(Mutex)_slock.ptr).__ctor(); - - _criticalRegionLock[] = typeid(Mutex).initializer[]; - (cast(Mutex)_criticalRegionLock.ptr).__ctor(); - } - - static void termLocks() - { - (cast(Mutex)_slock.ptr).__dtor(); - (cast(Mutex)_criticalRegionLock.ptr).__dtor(); - } - - __gshared Context* sm_cbeg; - - __gshared Thread sm_tbeg; - __gshared size_t sm_tlen; - - // can't use rt.util.array in public code - __gshared Thread* pAboutToStart; - __gshared size_t nAboutToStart; - - // - // Used for ordering threads in the global thread list. - // - Thread prev; - Thread next; - - - /////////////////////////////////////////////////////////////////////////// - // Global Context List Operations - /////////////////////////////////////////////////////////////////////////// - - - // - // Add a context to the global context list. - // - static void add( Context* c ) nothrow @nogc - in - { - assert( c ); - assert( !c.next && !c.prev ); - } - body - { - slock.lock_nothrow(); - scope(exit) slock.unlock_nothrow(); - assert(!suspendDepth); // must be 0 b/c it's only set with slock held - - if (sm_cbeg) - { - c.next = sm_cbeg; - sm_cbeg.prev = c; - } - sm_cbeg = c; - } - - - // - // Remove a context from the global context list. - // - // This assumes slock being acquired. This isn't done here to - // avoid double locking when called from remove(Thread) - static void remove( Context* c ) nothrow @nogc - in - { - assert( c ); - assert( c.next || c.prev ); - } - body - { - if ( c.prev ) - c.prev.next = c.next; - if ( c.next ) - c.next.prev = c.prev; - if ( sm_cbeg == c ) - sm_cbeg = c.next; - // NOTE: Don't null out c.next or c.prev because opApply currently - // follows c.next after removing a node. This could be easily - // addressed by simply returning the next node from this - // function, however, a context should never be re-added to the - // list anyway and having next and prev be non-null is a good way - // to ensure that. - } - - - /////////////////////////////////////////////////////////////////////////// - // Global Thread List Operations - /////////////////////////////////////////////////////////////////////////// - - - // - // Add a thread to the global thread list. - // - static void add( Thread t, bool rmAboutToStart = true ) nothrow @nogc - in - { - assert( t ); - assert( !t.next && !t.prev ); - } - body - { - slock.lock_nothrow(); - scope(exit) slock.unlock_nothrow(); - assert(t.isRunning); // check this with slock to ensure pthread_create already returned - assert(!suspendDepth); // must be 0 b/c it's only set with slock held - - if (rmAboutToStart) - { - size_t idx = -1; - foreach (i, thr; pAboutToStart[0 .. nAboutToStart]) - { - if (thr is t) - { - idx = i; - break; - } - } - assert(idx != -1); - import core.stdc.string : memmove; - memmove(pAboutToStart + idx, pAboutToStart + idx + 1, Thread.sizeof * (nAboutToStart - idx - 1)); - pAboutToStart = - cast(Thread*)realloc(pAboutToStart, Thread.sizeof * --nAboutToStart); - } - - if (sm_tbeg) - { - t.next = sm_tbeg; - sm_tbeg.prev = t; - } - sm_tbeg = t; - ++sm_tlen; - } - - - // - // Remove a thread from the global thread list. - // - static void remove( Thread t ) nothrow @nogc - in - { - assert( t ); - } - body - { - // Thread was already removed earlier, might happen b/c of thread_detachInstance - if (!t.next && !t.prev) - return; - slock.lock_nothrow(); - { - // NOTE: When a thread is removed from the global thread list its - // main context is invalid and should be removed as well. - // It is possible that t.m_curr could reference more - // than just the main context if the thread exited abnormally - // (if it was terminated), but we must assume that the user - // retains a reference to them and that they may be re-used - // elsewhere. Therefore, it is the responsibility of any - // object that creates contexts to clean them up properly - // when it is done with them. - remove( &t.m_main ); - - if ( t.prev ) - t.prev.next = t.next; - if ( t.next ) - t.next.prev = t.prev; - if ( sm_tbeg is t ) - sm_tbeg = t.next; - t.prev = t.next = null; - --sm_tlen; - } - // NOTE: Don't null out t.next or t.prev because opApply currently - // follows t.next after removing a node. This could be easily - // addressed by simply returning the next node from this - // function, however, a thread should never be re-added to the - // list anyway and having next and prev be non-null is a good way - // to ensure that. - slock.unlock_nothrow(); - } -} - -/// -unittest -{ - class DerivedThread : Thread - { - this() - { - super(&run); - } - - private: - void run() - { - // Derived thread running. - } - } - - void threadFunc() - { - // Composed thread running. - } - - // create and start instances of each type - auto derived = new DerivedThread().start(); - auto composed = new Thread(&threadFunc).start(); - new Thread({ - // Codes to run in the newly created thread. - }).start(); -} - -unittest -{ - int x = 0; - - new Thread( - { - x++; - }).start().join(); - assert( x == 1 ); -} - - -unittest -{ - enum MSG = "Test message."; - string caughtMsg; - - try - { - new Thread( - { - throw new Exception( MSG ); - }).start().join(); - assert( false, "Expected rethrown exception." ); - } - catch ( Throwable t ) - { - assert( t.msg == MSG ); - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// GC Support Routines -/////////////////////////////////////////////////////////////////////////////// - -version (CoreDdoc) -{ - /** - * Instruct the thread module, when initialized, to use a different set of - * signals besides SIGUSR1 and SIGUSR2 for suspension and resumption of threads. - * This function should be called at most once, prior to thread_init(). - * This function is Posix-only. - */ - extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc - { - } -} -else version (Posix) -{ - extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc - in - { - assert(suspendSignalNumber == 0); - assert(resumeSignalNumber == 0); - assert(suspendSignalNo != 0); - assert(resumeSignalNo != 0); - } - out - { - assert(suspendSignalNumber != 0); - assert(resumeSignalNumber != 0); - } - body - { - suspendSignalNumber = suspendSignalNo; - resumeSignalNumber = resumeSignalNo; - } -} - -version (Posix) -{ - __gshared int suspendSignalNumber; - __gshared int resumeSignalNumber; -} - -/** - * Initializes the thread module. This function must be called by the - * garbage collector on startup and before any other thread routines - * are called. - */ -extern (C) void thread_init() -{ - // NOTE: If thread_init itself performs any allocations then the thread - // routines reserved for garbage collector use may be called while - // thread_init is being processed. However, since no memory should - // exist to be scanned at this point, it is sufficient for these - // functions to detect the condition and return immediately. - - Thread.initLocks(); - // The Android VM runtime intercepts SIGUSR1 and apparently doesn't allow - // its signal handler to run, so swap the two signals on Android, since - // thread_resumeHandler does nothing. - version (Android) thread_setGCSignals(SIGUSR2, SIGUSR1); - - version (Darwin) - { - } - else version (Posix) - { - if ( suspendSignalNumber == 0 ) - { - suspendSignalNumber = SIGUSR1; - } - - if ( resumeSignalNumber == 0 ) - { - resumeSignalNumber = SIGUSR2; - } - - int status; - sigaction_t sigusr1 = void; - sigaction_t sigusr2 = void; - - // This is a quick way to zero-initialize the structs without using - // memset or creating a link dependency on their static initializer. - (cast(byte*) &sigusr1)[0 .. sigaction_t.sizeof] = 0; - (cast(byte*) &sigusr2)[0 .. sigaction_t.sizeof] = 0; - - // NOTE: SA_RESTART indicates that system calls should restart if they - // are interrupted by a signal, but this is not available on all - // Posix systems, even those that support multithreading. - static if ( __traits( compiles, SA_RESTART ) ) - sigusr1.sa_flags = SA_RESTART; - else - sigusr1.sa_flags = 0; - sigusr1.sa_handler = &thread_suspendHandler; - // NOTE: We want to ignore all signals while in this handler, so fill - // sa_mask to indicate this. - status = sigfillset( &sigusr1.sa_mask ); - assert( status == 0 ); - - // NOTE: Since resumeSignalNumber should only be issued for threads within the - // suspend handler, we don't want this signal to trigger a - // restart. - sigusr2.sa_flags = 0; - sigusr2.sa_handler = &thread_resumeHandler; - // NOTE: We want to ignore all signals while in this handler, so fill - // sa_mask to indicate this. - status = sigfillset( &sigusr2.sa_mask ); - assert( status == 0 ); - - status = sigaction( suspendSignalNumber, &sigusr1, null ); - assert( status == 0 ); - - status = sigaction( resumeSignalNumber, &sigusr2, null ); - assert( status == 0 ); - - status = sem_init( &suspendCount, 0, 0 ); - assert( status == 0 ); - } - Thread.sm_main = thread_attachThis(); -} - - -/** - * Terminates the thread module. No other thread routine may be called - * afterwards. - */ -extern (C) void thread_term() -{ - assert(Thread.sm_tbeg && Thread.sm_tlen == 1); - assert(!Thread.nAboutToStart); - if (Thread.pAboutToStart) // in case realloc(p, 0) doesn't return null - { - free(Thread.pAboutToStart); - Thread.pAboutToStart = null; - } - Thread.termLocks(); -} - - -/** - * - */ -extern (C) bool thread_isMainThread() nothrow @nogc -{ - return Thread.getThis() is Thread.sm_main; -} - - -/** - * Registers the calling thread for use with the D Runtime. If this routine - * is called for a thread which is already registered, no action is performed. - * - * NOTE: This routine does not run thread-local static constructors when called. - * If full functionality as a D thread is desired, the following function - * must be called after thread_attachThis: - * - * extern (C) void rt_moduleTlsCtor(); - */ -extern (C) Thread thread_attachThis() -{ - GC.disable(); scope(exit) GC.enable(); - - if (auto t = Thread.getThis()) - return t; - - Thread thisThread = new Thread(); - Thread.Context* thisContext = &thisThread.m_main; - assert( thisContext == thisThread.m_curr ); - - version (Windows) - { - thisThread.m_addr = GetCurrentThreadId(); - thisThread.m_hndl = GetCurrentThreadHandle(); - thisContext.bstack = getStackBottom(); - thisContext.tstack = thisContext.bstack; - } - else version (Posix) - { - thisThread.m_addr = pthread_self(); - thisContext.bstack = getStackBottom(); - thisContext.tstack = thisContext.bstack; - - atomicStore!(MemoryOrder.raw)(thisThread.m_isRunning, true); - } - thisThread.m_isDaemon = true; - thisThread.m_tlsgcdata = rt_tlsgc_init(); - Thread.setThis( thisThread ); - - version (Darwin) - { - thisThread.m_tmach = pthread_mach_thread_np( thisThread.m_addr ); - assert( thisThread.m_tmach != thisThread.m_tmach.init ); - } - - Thread.add( thisThread, false ); - Thread.add( thisContext ); - if ( Thread.sm_main !is null ) - multiThreadedFlag = true; - return thisThread; -} - - -version (Windows) -{ - // NOTE: These calls are not safe on Posix systems that use signals to - // perform garbage collection. The suspendHandler uses getThis() - // to get the thread handle so getThis() must be a simple call. - // Mutexes can't safely be acquired inside signal handlers, and - // even if they could, the mutex needed (Thread.slock) is held by - // thread_suspendAll(). So in short, these routines will remain - // Windows-specific. If they are truly needed elsewhere, the - // suspendHandler will need a way to call a version of getThis() - // that only does the TLS lookup without the fancy fallback stuff. - - /// ditto - extern (C) Thread thread_attachByAddr( ThreadID addr ) - { - return thread_attachByAddrB( addr, getThreadStackBottom( addr ) ); - } - - - /// ditto - extern (C) Thread thread_attachByAddrB( ThreadID addr, void* bstack ) - { - GC.disable(); scope(exit) GC.enable(); - - if (auto t = thread_findByAddr(addr)) - return t; - - Thread thisThread = new Thread(); - Thread.Context* thisContext = &thisThread.m_main; - assert( thisContext == thisThread.m_curr ); - - thisThread.m_addr = addr; - thisContext.bstack = bstack; - thisContext.tstack = thisContext.bstack; - - thisThread.m_isDaemon = true; - - if ( addr == GetCurrentThreadId() ) - { - thisThread.m_hndl = GetCurrentThreadHandle(); - thisThread.m_tlsgcdata = rt_tlsgc_init(); - Thread.setThis( thisThread ); - } - else - { - thisThread.m_hndl = OpenThreadHandle( addr ); - impersonate_thread(addr, - { - thisThread.m_tlsgcdata = rt_tlsgc_init(); - Thread.setThis( thisThread ); - }); - } - - Thread.add( thisThread, false ); - Thread.add( thisContext ); - if ( Thread.sm_main !is null ) - multiThreadedFlag = true; - return thisThread; - } -} - - -/** - * Deregisters the calling thread from use with the runtime. If this routine - * is called for a thread which is not registered, the result is undefined. - * - * NOTE: This routine does not run thread-local static destructors when called. - * If full functionality as a D thread is desired, the following function - * must be called after thread_detachThis, particularly if the thread is - * being detached at some indeterminate time before program termination: - * - * $(D extern(C) void rt_moduleTlsDtor();) - */ -extern (C) void thread_detachThis() nothrow @nogc -{ - if (auto t = Thread.getThis()) - Thread.remove(t); -} - - -/** - * Deregisters the given thread from use with the runtime. If this routine - * is called for a thread which is not registered, the result is undefined. - * - * NOTE: This routine does not run thread-local static destructors when called. - * If full functionality as a D thread is desired, the following function - * must be called by the detached thread, particularly if the thread is - * being detached at some indeterminate time before program termination: - * - * $(D extern(C) void rt_moduleTlsDtor();) - */ -extern (C) void thread_detachByAddr( ThreadID addr ) -{ - if ( auto t = thread_findByAddr( addr ) ) - Thread.remove( t ); -} - - -/// ditto -extern (C) void thread_detachInstance( Thread t ) nothrow @nogc -{ - Thread.remove( t ); -} - - -unittest -{ - import core.sync.semaphore; - auto sem = new Semaphore(); - - auto t = new Thread( - { - sem.notify(); - Thread.sleep(100.msecs); - }).start(); - - sem.wait(); // thread cannot be detached while being started - thread_detachInstance(t); - foreach (t2; Thread) - assert(t !is t2); - t.join(); -} - - -/** - * Search the list of all threads for a thread with the given thread identifier. - * - * Params: - * addr = The thread identifier to search for. - * Returns: - * The thread object associated with the thread identifier, null if not found. - */ -static Thread thread_findByAddr( ThreadID addr ) -{ - Thread.slock.lock_nothrow(); - scope(exit) Thread.slock.unlock_nothrow(); - - // also return just spawned thread so that - // DLL_THREAD_ATTACH knows it's a D thread - foreach (t; Thread.pAboutToStart[0 .. Thread.nAboutToStart]) - if (t.m_addr == addr) - return t; - - foreach (t; Thread) - if (t.m_addr == addr) - return t; - - return null; -} - - -/** - * Sets the current thread to a specific reference. Only to be used - * when dealing with externally-created threads (in e.g. C code). - * The primary use of this function is when Thread.getThis() must - * return a sensible value in, for example, TLS destructors. In - * other words, don't touch this unless you know what you're doing. - * - * Params: - * t = A reference to the current thread. May be null. - */ -extern (C) void thread_setThis(Thread t) nothrow @nogc -{ - Thread.setThis(t); -} - - -/** - * Joins all non-daemon threads that are currently running. This is done by - * performing successive scans through the thread list until a scan consists - * of only daemon threads. - */ -extern (C) void thread_joinAll() -{ - Lagain: - Thread.slock.lock_nothrow(); - // wait for just spawned threads - if (Thread.nAboutToStart) - { - Thread.slock.unlock_nothrow(); - Thread.yield(); - goto Lagain; - } - - // join all non-daemon threads, the main thread is also a daemon - auto t = Thread.sm_tbeg; - while (t) - { - if (!t.isRunning) - { - auto tn = t.next; - Thread.remove(t); - t = tn; - } - else if (t.isDaemon) - { - t = t.next; - } - else - { - Thread.slock.unlock_nothrow(); - t.join(); // might rethrow - goto Lagain; // must restart iteration b/c of unlock - } - } - Thread.slock.unlock_nothrow(); -} - - -/** - * Performs intermediate shutdown of the thread module. - */ -shared static ~this() -{ - // NOTE: The functionality related to garbage collection must be minimally - // operable after this dtor completes. Therefore, only minimal - // cleanup may occur. - auto t = Thread.sm_tbeg; - while (t) - { - auto tn = t.next; - if (!t.isRunning) - Thread.remove(t); - t = tn; - } -} - - -// Used for needLock below. -private __gshared bool multiThreadedFlag = false; - -// Calls the given delegate, passing the current thread's stack pointer to it. -private void callWithStackShell(scope void delegate(void* sp) nothrow fn) nothrow -in -{ - assert(fn); -} -body -{ - // The purpose of the 'shell' is to ensure all the registers get - // put on the stack so they'll be scanned. We only need to push - // the callee-save registers. - void *sp = void; - - version (GNU) - { - __builtin_unwind_init(); - sp = &sp; - } - else version (AsmX86_Posix) - { - size_t[3] regs = void; - asm pure nothrow @nogc - { - mov [regs + 0 * 4], EBX; - mov [regs + 1 * 4], ESI; - mov [regs + 2 * 4], EDI; - - mov sp[EBP], ESP; - } - } - else version (AsmX86_Windows) - { - size_t[3] regs = void; - asm pure nothrow @nogc - { - mov [regs + 0 * 4], EBX; - mov [regs + 1 * 4], ESI; - mov [regs + 2 * 4], EDI; - - mov sp[EBP], ESP; - } - } - else version (AsmX86_64_Posix) - { - size_t[5] regs = void; - asm pure nothrow @nogc - { - mov [regs + 0 * 8], RBX; - mov [regs + 1 * 8], R12; - mov [regs + 2 * 8], R13; - mov [regs + 3 * 8], R14; - mov [regs + 4 * 8], R15; - - mov sp[RBP], RSP; - } - } - else version (AsmX86_64_Windows) - { - size_t[7] regs = void; - asm pure nothrow @nogc - { - mov [regs + 0 * 8], RBX; - mov [regs + 1 * 8], RSI; - mov [regs + 2 * 8], RDI; - mov [regs + 3 * 8], R12; - mov [regs + 4 * 8], R13; - mov [regs + 5 * 8], R14; - mov [regs + 6 * 8], R15; - - mov sp[RBP], RSP; - } - } - else - { - static assert(false, "Architecture not supported."); - } - - fn(sp); -} - -// Used for suspendAll/resumeAll below. -private __gshared uint suspendDepth = 0; - -/** - * Suspend the specified thread and load stack and register information for - * use by thread_scanAll. If the supplied thread is the calling thread, - * stack and register information will be loaded but the thread will not - * be suspended. If the suspend operation fails and the thread is not - * running then it will be removed from the global thread list, otherwise - * an exception will be thrown. - * - * Params: - * t = The thread to suspend. - * - * Throws: - * ThreadError if the suspend operation fails for a running thread. - * Returns: - * Whether the thread is now suspended (true) or terminated (false). - */ -private bool suspend( Thread t ) nothrow -{ - Duration waittime = dur!"usecs"(10); - Lagain: - if (!t.isRunning) - { - Thread.remove(t); - return false; - } - else if (t.m_isInCriticalRegion) - { - Thread.criticalRegionLock.unlock_nothrow(); - Thread.sleep(waittime); - if (waittime < dur!"msecs"(10)) waittime *= 2; - Thread.criticalRegionLock.lock_nothrow(); - goto Lagain; - } - - version (Windows) - { - if ( t.m_addr != GetCurrentThreadId() && SuspendThread( t.m_hndl ) == 0xFFFFFFFF ) - { - if ( !t.isRunning ) - { - Thread.remove( t ); - return false; - } - onThreadError( "Unable to suspend thread" ); - } - - CONTEXT context = void; - context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL; - - if ( !GetThreadContext( t.m_hndl, &context ) ) - onThreadError( "Unable to load thread context" ); - version (X86) - { - if ( !t.m_lock ) - t.m_curr.tstack = cast(void*) context.Esp; - // eax,ebx,ecx,edx,edi,esi,ebp,esp - t.m_reg[0] = context.Eax; - t.m_reg[1] = context.Ebx; - t.m_reg[2] = context.Ecx; - t.m_reg[3] = context.Edx; - t.m_reg[4] = context.Edi; - t.m_reg[5] = context.Esi; - t.m_reg[6] = context.Ebp; - t.m_reg[7] = context.Esp; - } - else version (X86_64) - { - if ( !t.m_lock ) - t.m_curr.tstack = cast(void*) context.Rsp; - // rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp - t.m_reg[0] = context.Rax; - t.m_reg[1] = context.Rbx; - t.m_reg[2] = context.Rcx; - t.m_reg[3] = context.Rdx; - t.m_reg[4] = context.Rdi; - t.m_reg[5] = context.Rsi; - t.m_reg[6] = context.Rbp; - t.m_reg[7] = context.Rsp; - // r8,r9,r10,r11,r12,r13,r14,r15 - t.m_reg[8] = context.R8; - t.m_reg[9] = context.R9; - t.m_reg[10] = context.R10; - t.m_reg[11] = context.R11; - t.m_reg[12] = context.R12; - t.m_reg[13] = context.R13; - t.m_reg[14] = context.R14; - t.m_reg[15] = context.R15; - } - else - { - static assert(false, "Architecture not supported." ); - } - } - else version (Darwin) - { - if ( t.m_addr != pthread_self() && thread_suspend( t.m_tmach ) != KERN_SUCCESS ) - { - if ( !t.isRunning ) - { - Thread.remove( t ); - return false; - } - onThreadError( "Unable to suspend thread" ); - } - - version (X86) - { - x86_thread_state32_t state = void; - mach_msg_type_number_t count = x86_THREAD_STATE32_COUNT; - - if ( thread_get_state( t.m_tmach, x86_THREAD_STATE32, &state, &count ) != KERN_SUCCESS ) - onThreadError( "Unable to load thread state" ); - if ( !t.m_lock ) - t.m_curr.tstack = cast(void*) state.esp; - // eax,ebx,ecx,edx,edi,esi,ebp,esp - t.m_reg[0] = state.eax; - t.m_reg[1] = state.ebx; - t.m_reg[2] = state.ecx; - t.m_reg[3] = state.edx; - t.m_reg[4] = state.edi; - t.m_reg[5] = state.esi; - t.m_reg[6] = state.ebp; - t.m_reg[7] = state.esp; - } - else version (X86_64) - { - x86_thread_state64_t state = void; - mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; - - if ( thread_get_state( t.m_tmach, x86_THREAD_STATE64, &state, &count ) != KERN_SUCCESS ) - onThreadError( "Unable to load thread state" ); - if ( !t.m_lock ) - t.m_curr.tstack = cast(void*) state.rsp; - // rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp - t.m_reg[0] = state.rax; - t.m_reg[1] = state.rbx; - t.m_reg[2] = state.rcx; - t.m_reg[3] = state.rdx; - t.m_reg[4] = state.rdi; - t.m_reg[5] = state.rsi; - t.m_reg[6] = state.rbp; - t.m_reg[7] = state.rsp; - // r8,r9,r10,r11,r12,r13,r14,r15 - t.m_reg[8] = state.r8; - t.m_reg[9] = state.r9; - t.m_reg[10] = state.r10; - t.m_reg[11] = state.r11; - t.m_reg[12] = state.r12; - t.m_reg[13] = state.r13; - t.m_reg[14] = state.r14; - t.m_reg[15] = state.r15; - } - else - { - static assert(false, "Architecture not supported." ); - } - } - else version (Posix) - { - if ( t.m_addr != pthread_self() ) - { - if ( pthread_kill( t.m_addr, suspendSignalNumber ) != 0 ) - { - if ( !t.isRunning ) - { - Thread.remove( t ); - return false; - } - onThreadError( "Unable to suspend thread" ); - } - } - else if ( !t.m_lock ) - { - t.m_curr.tstack = getStackTop(); - } - } - return true; -} - -/** - * Suspend all threads but the calling thread for "stop the world" garbage - * collection runs. This function may be called multiple times, and must - * be followed by a matching number of calls to thread_resumeAll before - * processing is resumed. - * - * Throws: - * ThreadError if the suspend operation fails for a running thread. - */ -extern (C) void thread_suspendAll() nothrow -{ - // NOTE: We've got an odd chicken & egg problem here, because while the GC - // is required to call thread_init before calling any other thread - // routines, thread_init may allocate memory which could in turn - // trigger a collection. Thus, thread_suspendAll, thread_scanAll, - // and thread_resumeAll must be callable before thread_init - // completes, with the assumption that no other GC memory has yet - // been allocated by the system, and thus there is no risk of losing - // data if the global thread list is empty. The check of - // Thread.sm_tbeg below is done to ensure thread_init has completed, - // and therefore that calling Thread.getThis will not result in an - // error. For the short time when Thread.sm_tbeg is null, there is - // no reason not to simply call the multithreaded code below, with - // the expectation that the foreach loop will never be entered. - if ( !multiThreadedFlag && Thread.sm_tbeg ) - { - if ( ++suspendDepth == 1 ) - suspend( Thread.getThis() ); - - return; - } - - Thread.slock.lock_nothrow(); - { - if ( ++suspendDepth > 1 ) - return; - - Thread.criticalRegionLock.lock_nothrow(); - scope (exit) Thread.criticalRegionLock.unlock_nothrow(); - size_t cnt; - auto t = Thread.sm_tbeg; - while (t) - { - auto tn = t.next; - if (suspend(t)) - ++cnt; - t = tn; - } - - version (Darwin) - {} - else version (Posix) - { - // subtract own thread - assert(cnt >= 1); - --cnt; - Lagain: - // wait for semaphore notifications - for (; cnt; --cnt) - { - while (sem_wait(&suspendCount) != 0) - { - if (errno != EINTR) - onThreadError("Unable to wait for semaphore"); - errno = 0; - } - } - version (FreeBSD) - { - // avoid deadlocks, see Issue 13416 - t = Thread.sm_tbeg; - while (t) - { - auto tn = t.next; - if (t.m_suspendagain && suspend(t)) - ++cnt; - t = tn; - } - if (cnt) - goto Lagain; - } - } - } -} - -/** - * Resume the specified thread and unload stack and register information. - * If the supplied thread is the calling thread, stack and register - * information will be unloaded but the thread will not be resumed. If - * the resume operation fails and the thread is not running then it will - * be removed from the global thread list, otherwise an exception will be - * thrown. - * - * Params: - * t = The thread to resume. - * - * Throws: - * ThreadError if the resume fails for a running thread. - */ -private void resume( Thread t ) nothrow -{ - version (Windows) - { - if ( t.m_addr != GetCurrentThreadId() && ResumeThread( t.m_hndl ) == 0xFFFFFFFF ) - { - if ( !t.isRunning ) - { - Thread.remove( t ); - return; - } - onThreadError( "Unable to resume thread" ); - } - - if ( !t.m_lock ) - t.m_curr.tstack = t.m_curr.bstack; - t.m_reg[0 .. $] = 0; - } - else version (Darwin) - { - if ( t.m_addr != pthread_self() && thread_resume( t.m_tmach ) != KERN_SUCCESS ) - { - if ( !t.isRunning ) - { - Thread.remove( t ); - return; - } - onThreadError( "Unable to resume thread" ); - } - - if ( !t.m_lock ) - t.m_curr.tstack = t.m_curr.bstack; - t.m_reg[0 .. $] = 0; - } - else version (Posix) - { - if ( t.m_addr != pthread_self() ) - { - if ( pthread_kill( t.m_addr, resumeSignalNumber ) != 0 ) - { - if ( !t.isRunning ) - { - Thread.remove( t ); - return; - } - onThreadError( "Unable to resume thread" ); - } - } - else if ( !t.m_lock ) - { - t.m_curr.tstack = t.m_curr.bstack; - } - } -} - -/** - * Resume all threads but the calling thread for "stop the world" garbage - * collection runs. This function must be called once for each preceding - * call to thread_suspendAll before the threads are actually resumed. - * - * In: - * This routine must be preceded by a call to thread_suspendAll. - * - * Throws: - * ThreadError if the resume operation fails for a running thread. - */ -extern (C) void thread_resumeAll() nothrow -in -{ - assert( suspendDepth > 0 ); -} -body -{ - // NOTE: See thread_suspendAll for the logic behind this. - if ( !multiThreadedFlag && Thread.sm_tbeg ) - { - if ( --suspendDepth == 0 ) - resume( Thread.getThis() ); - return; - } - - scope(exit) Thread.slock.unlock_nothrow(); - { - if ( --suspendDepth > 0 ) - return; - - for ( Thread t = Thread.sm_tbeg; t; t = t.next ) - { - // NOTE: We do not need to care about critical regions at all - // here. thread_suspendAll takes care of everything. - resume( t ); - } - } -} - -/** - * Indicates the kind of scan being performed by $(D thread_scanAllType). - */ -enum ScanType -{ - stack, /// The stack and/or registers are being scanned. - tls, /// TLS data is being scanned. -} - -alias ScanAllThreadsFn = void delegate(void*, void*) nothrow; /// The scanning function. -alias ScanAllThreadsTypeFn = void delegate(ScanType, void*, void*) nothrow; /// ditto - -/** - * The main entry point for garbage collection. The supplied delegate - * will be passed ranges representing both stack and register values. - * - * Params: - * scan = The scanner function. It should scan from p1 through p2 - 1. - * - * In: - * This routine must be preceded by a call to thread_suspendAll. - */ -extern (C) void thread_scanAllType( scope ScanAllThreadsTypeFn scan ) nothrow -in -{ - assert( suspendDepth > 0 ); -} -body -{ - callWithStackShell(sp => scanAllTypeImpl(scan, sp)); -} - - -private void scanAllTypeImpl( scope ScanAllThreadsTypeFn scan, void* curStackTop ) nothrow -{ - Thread thisThread = null; - void* oldStackTop = null; - - if ( Thread.sm_tbeg ) - { - thisThread = Thread.getThis(); - if ( !thisThread.m_lock ) - { - oldStackTop = thisThread.m_curr.tstack; - thisThread.m_curr.tstack = curStackTop; - } - } - - scope( exit ) - { - if ( Thread.sm_tbeg ) - { - if ( !thisThread.m_lock ) - { - thisThread.m_curr.tstack = oldStackTop; - } - } - } - - // NOTE: Synchronizing on Thread.slock is not needed because this - // function may only be called after all other threads have - // been suspended from within the same lock. - if (Thread.nAboutToStart) - scan(ScanType.stack, Thread.pAboutToStart, Thread.pAboutToStart + Thread.nAboutToStart); - - for ( Thread.Context* c = Thread.sm_cbeg; c; c = c.next ) - { - version (StackGrowsDown) - { - // NOTE: We can't index past the bottom of the stack - // so don't do the "+1" for StackGrowsDown. - if ( c.tstack && c.tstack < c.bstack ) - scan( ScanType.stack, c.tstack, c.bstack ); - } - else - { - if ( c.bstack && c.bstack < c.tstack ) - scan( ScanType.stack, c.bstack, c.tstack + 1 ); - } - } - - for ( Thread t = Thread.sm_tbeg; t; t = t.next ) - { - version (Windows) - { - // Ideally, we'd pass ScanType.regs or something like that, but this - // would make portability annoying because it only makes sense on Windows. - scan( ScanType.stack, t.m_reg.ptr, t.m_reg.ptr + t.m_reg.length ); - } - - if (t.m_tlsgcdata !is null) - rt_tlsgc_scan(t.m_tlsgcdata, (p1, p2) => scan(ScanType.tls, p1, p2)); - } -} - -/** - * The main entry point for garbage collection. The supplied delegate - * will be passed ranges representing both stack and register values. - * - * Params: - * scan = The scanner function. It should scan from p1 through p2 - 1. - * - * In: - * This routine must be preceded by a call to thread_suspendAll. - */ -extern (C) void thread_scanAll( scope ScanAllThreadsFn scan ) nothrow -{ - thread_scanAllType((type, p1, p2) => scan(p1, p2)); -} - - -/** - * Signals that the code following this call is a critical region. Any code in - * this region must finish running before the calling thread can be suspended - * by a call to thread_suspendAll. - * - * This function is, in particular, meant to help maintain garbage collector - * invariants when a lock is not used. - * - * A critical region is exited with thread_exitCriticalRegion. - * - * $(RED Warning): - * Using critical regions is extremely error-prone. For instance, using locks - * inside a critical region can easily result in a deadlock when another thread - * holding the lock already got suspended. - * - * The term and concept of a 'critical region' comes from - * $(LINK2 https://github.com/mono/mono/blob/521f4a198e442573c400835ef19bbb36b60b0ebb/mono/metadata/sgen-gc.h#L925 Mono's SGen garbage collector). - * - * In: - * The calling thread must be attached to the runtime. - */ -extern (C) void thread_enterCriticalRegion() @nogc -in -{ - assert(Thread.getThis()); -} -body -{ - synchronized (Thread.criticalRegionLock) - Thread.getThis().m_isInCriticalRegion = true; -} - - -/** - * Signals that the calling thread is no longer in a critical region. Following - * a call to this function, the thread can once again be suspended. - * - * In: - * The calling thread must be attached to the runtime. - */ -extern (C) void thread_exitCriticalRegion() @nogc -in -{ - assert(Thread.getThis()); -} -body -{ - synchronized (Thread.criticalRegionLock) - Thread.getThis().m_isInCriticalRegion = false; -} - - -/** - * Returns true if the current thread is in a critical region; otherwise, false. - * - * In: - * The calling thread must be attached to the runtime. - */ -extern (C) bool thread_inCriticalRegion() @nogc -in -{ - assert(Thread.getThis()); -} -body -{ - synchronized (Thread.criticalRegionLock) - return Thread.getThis().m_isInCriticalRegion; -} - - -/** -* A callback for thread errors in D during collections. Since an allocation is not possible -* a preallocated ThreadError will be used as the Error instance -* -* Throws: -* ThreadError. -*/ -private void onThreadError(string msg = null, Throwable next = null) nothrow -{ - __gshared ThreadError error = new ThreadError(null); - error.msg = msg; - error.next = next; - import core.exception : SuppressTraceInfo; - error.info = SuppressTraceInfo.instance; - throw error; -} - - -unittest -{ - assert(!thread_inCriticalRegion()); - - { - thread_enterCriticalRegion(); - - scope (exit) - thread_exitCriticalRegion(); - - assert(thread_inCriticalRegion()); - } - - assert(!thread_inCriticalRegion()); -} - -unittest -{ - // NOTE: This entire test is based on the assumption that no - // memory is allocated after the child thread is - // started. If an allocation happens, a collection could - // trigger, which would cause the synchronization below - // to cause a deadlock. - // NOTE: DO NOT USE LOCKS IN CRITICAL REGIONS IN NORMAL CODE. - - import core.sync.semaphore; - - auto sema = new Semaphore(), - semb = new Semaphore(); - - auto thr = new Thread( - { - thread_enterCriticalRegion(); - assert(thread_inCriticalRegion()); - sema.notify(); - - semb.wait(); - assert(thread_inCriticalRegion()); - - thread_exitCriticalRegion(); - assert(!thread_inCriticalRegion()); - sema.notify(); - - semb.wait(); - assert(!thread_inCriticalRegion()); - }); - - thr.start(); - - sema.wait(); - synchronized (Thread.criticalRegionLock) - assert(thr.m_isInCriticalRegion); - semb.notify(); - - sema.wait(); - synchronized (Thread.criticalRegionLock) - assert(!thr.m_isInCriticalRegion); - semb.notify(); - - thr.join(); -} - -unittest -{ - import core.sync.semaphore; - - shared bool inCriticalRegion; - auto sema = new Semaphore(), - semb = new Semaphore(); - - auto thr = new Thread( - { - thread_enterCriticalRegion(); - inCriticalRegion = true; - sema.notify(); - semb.wait(); - - Thread.sleep(dur!"msecs"(1)); - inCriticalRegion = false; - thread_exitCriticalRegion(); - }); - thr.start(); - - sema.wait(); - assert(inCriticalRegion); - semb.notify(); - - thread_suspendAll(); - assert(!inCriticalRegion); - thread_resumeAll(); -} - -/** - * Indicates whether an address has been marked by the GC. - */ -enum IsMarked : int -{ - no, /// Address is not marked. - yes, /// Address is marked. - unknown, /// Address is not managed by the GC. -} - -alias IsMarkedDg = int delegate( void* addr ) nothrow; /// The isMarked callback function. - -/** - * This routine allows the runtime to process any special per-thread handling - * for the GC. This is needed for taking into account any memory that is - * referenced by non-scanned pointers but is about to be freed. That currently - * means the array append cache. - * - * Params: - * isMarked = The function used to check if $(D addr) is marked. - * - * In: - * This routine must be called just prior to resuming all threads. - */ -extern(C) void thread_processGCMarks( scope IsMarkedDg isMarked ) nothrow -{ - for ( Thread t = Thread.sm_tbeg; t; t = t.next ) - { - /* Can be null if collection was triggered between adding a - * thread and calling rt_tlsgc_init. - */ - if (t.m_tlsgcdata !is null) - rt_tlsgc_processGCMarks(t.m_tlsgcdata, isMarked); - } -} - - -extern (C) @nogc nothrow -{ - version (CRuntime_Glibc) int pthread_getattr_np(pthread_t thread, pthread_attr_t* attr); - version (FreeBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr); - version (NetBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr); - version (OpenBSD) int pthread_stackseg_np(pthread_t thread, stack_t* sinfo); - version (DragonFlyBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr); - version (Solaris) int thr_stksegment(stack_t* stk); - version (CRuntime_Bionic) int pthread_getattr_np(pthread_t thid, pthread_attr_t* attr); - version (CRuntime_Musl) int pthread_getattr_np(pthread_t, pthread_attr_t*); - version (CRuntime_UClibc) int pthread_getattr_np(pthread_t thread, pthread_attr_t* attr); -} - - -private void* getStackTop() nothrow @nogc -{ - version (D_InlineAsm_X86) - asm pure nothrow @nogc { naked; mov EAX, ESP; ret; } - else version (D_InlineAsm_X86_64) - asm pure nothrow @nogc { naked; mov RAX, RSP; ret; } - else version (GNU) - return __builtin_frame_address(0); - else - static assert(false, "Architecture not supported."); -} - - -private void* getStackBottom() nothrow @nogc -{ - version (Windows) - { - version (D_InlineAsm_X86) - asm pure nothrow @nogc { naked; mov EAX, FS:4; ret; } - else version (D_InlineAsm_X86_64) - asm pure nothrow @nogc - { naked; - mov RAX, 8; - mov RAX, GS:[RAX]; - ret; - } - else version (GNU_InlineAsm) - { - void *bottom; - - version (X86) - asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; } - else version (X86_64) - asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; } - else - static assert(false, "Platform not supported."); - - return bottom; - } - else - static assert(false, "Architecture not supported."); - } - else version (Darwin) - { - import core.sys.darwin.pthread; - return pthread_get_stackaddr_np(pthread_self()); - } - else version (CRuntime_Glibc) - { - pthread_attr_t attr; - void* addr; size_t size; - - pthread_getattr_np(pthread_self(), &attr); - pthread_attr_getstack(&attr, &addr, &size); - pthread_attr_destroy(&attr); - version (StackGrowsDown) - addr += size; - return addr; - } - else version (FreeBSD) - { - pthread_attr_t attr; - void* addr; size_t size; - - pthread_attr_init(&attr); - pthread_attr_get_np(pthread_self(), &attr); - pthread_attr_getstack(&attr, &addr, &size); - pthread_attr_destroy(&attr); - version (StackGrowsDown) - addr += size; - return addr; - } - else version (NetBSD) - { - pthread_attr_t attr; - void* addr; size_t size; - - pthread_attr_init(&attr); - pthread_attr_get_np(pthread_self(), &attr); - pthread_attr_getstack(&attr, &addr, &size); - pthread_attr_destroy(&attr); - version (StackGrowsDown) - addr += size; - return addr; - } - else version (OpenBSD) - { - stack_t stk; - - pthread_stackseg_np(pthread_self(), &stk); - return stk.ss_sp; - } - else version (DragonFlyBSD) - { - pthread_attr_t attr; - void* addr; size_t size; - - pthread_attr_init(&attr); - pthread_attr_get_np(pthread_self(), &attr); - pthread_attr_getstack(&attr, &addr, &size); - pthread_attr_destroy(&attr); - version (StackGrowsDown) - addr += size; - return addr; - } - else version (Solaris) - { - stack_t stk; - - thr_stksegment(&stk); - return stk.ss_sp; - } - else version (CRuntime_Bionic) - { - pthread_attr_t attr; - void* addr; size_t size; - - pthread_getattr_np(pthread_self(), &attr); - pthread_attr_getstack(&attr, &addr, &size); - pthread_attr_destroy(&attr); - version (StackGrowsDown) - addr += size; - return addr; - } - else version (CRuntime_Musl) - { - pthread_attr_t attr; - void* addr; size_t size; - - pthread_getattr_np(pthread_self(), &attr); - pthread_attr_getstack(&attr, &addr, &size); - pthread_attr_destroy(&attr); - version (StackGrowsDown) - addr += size; - return addr; - } - else version (CRuntime_UClibc) - { - pthread_attr_t attr; - void* addr; size_t size; - - pthread_getattr_np(pthread_self(), &attr); - pthread_attr_getstack(&attr, &addr, &size); - pthread_attr_destroy(&attr); - version (StackGrowsDown) - addr += size; - return addr; - } - else - static assert(false, "Platform not supported."); -} - - -/** - * Returns the stack top of the currently active stack within the calling - * thread. - * - * In: - * The calling thread must be attached to the runtime. - * - * Returns: - * The address of the stack top. - */ -extern (C) void* thread_stackTop() nothrow @nogc -in -{ - // Not strictly required, but it gives us more flexibility. - assert(Thread.getThis()); -} -body -{ - return getStackTop(); -} - - -/** - * Returns the stack bottom of the currently active stack within the calling - * thread. - * - * In: - * The calling thread must be attached to the runtime. - * - * Returns: - * The address of the stack bottom. - */ -extern (C) void* thread_stackBottom() nothrow @nogc -in -{ - assert(Thread.getThis()); -} -body -{ - return Thread.getThis().topContext().bstack; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Thread Group -/////////////////////////////////////////////////////////////////////////////// - - -/** - * This class is intended to simplify certain common programming techniques. - */ -class ThreadGroup -{ - /** - * Creates and starts a new Thread object that executes fn and adds it to - * the list of tracked threads. - * - * Params: - * fn = The thread function. - * - * Returns: - * A reference to the newly created thread. - */ - final Thread create( void function() fn ) - { - Thread t = new Thread( fn ).start(); - - synchronized( this ) - { - m_all[t] = t; - } - return t; - } - - - /** - * Creates and starts a new Thread object that executes dg and adds it to - * the list of tracked threads. - * - * Params: - * dg = The thread function. - * - * Returns: - * A reference to the newly created thread. - */ - final Thread create( void delegate() dg ) - { - Thread t = new Thread( dg ).start(); - - synchronized( this ) - { - m_all[t] = t; - } - return t; - } - - - /** - * Add t to the list of tracked threads if it is not already being tracked. - * - * Params: - * t = The thread to add. - * - * In: - * t must not be null. - */ - final void add( Thread t ) - in - { - assert( t ); - } - body - { - synchronized( this ) - { - m_all[t] = t; - } - } - - - /** - * Removes t from the list of tracked threads. No operation will be - * performed if t is not currently being tracked by this object. - * - * Params: - * t = The thread to remove. - * - * In: - * t must not be null. - */ - final void remove( Thread t ) - in - { - assert( t ); - } - body - { - synchronized( this ) - { - m_all.remove( t ); - } - } - - - /** - * Operates on all threads currently tracked by this object. - */ - final int opApply( scope int delegate( ref Thread ) dg ) - { - synchronized( this ) - { - int ret = 0; - - // NOTE: This loop relies on the knowledge that m_all uses the - // Thread object for both the key and the mapped value. - foreach ( Thread t; m_all.keys ) - { - ret = dg( t ); - if ( ret ) - break; - } - return ret; - } - } - - - /** - * Iteratively joins all tracked threads. This function will block add, - * remove, and opApply until it completes. - * - * Params: - * rethrow = Rethrow any unhandled exception which may have caused the - * current thread to terminate. - * - * Throws: - * Any exception not handled by the joined threads. - */ - final void joinAll( bool rethrow = true ) - { - synchronized( this ) - { - // NOTE: This loop relies on the knowledge that m_all uses the - // Thread object for both the key and the mapped value. - foreach ( Thread t; m_all.keys ) - { - t.join( rethrow ); - } - } - } - - -private: - Thread[Thread] m_all; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Fiber Platform Detection and Memory Allocation -/////////////////////////////////////////////////////////////////////////////// - - -private -{ - version (D_InlineAsm_X86) - { - version (Windows) - version = AsmX86_Windows; - else version (Posix) - version = AsmX86_Posix; - - version (Darwin) - version = AlignFiberStackTo16Byte; - } - else version (D_InlineAsm_X86_64) - { - version (Windows) - { - version = AsmX86_64_Windows; - version = AlignFiberStackTo16Byte; - } - else version (Posix) - { - version = AsmX86_64_Posix; - version = AlignFiberStackTo16Byte; - } - } - else version (X86) - { - version = AlignFiberStackTo16Byte; - - version (CET) - { - // fiber_switchContext does not support shadow stack from - // Intel CET. So use ucontext implementation. - } - else - { - version = AsmExternal; - - version (MinGW) - version = GNU_AsmX86_Windows; - else version (Posix) - version = AsmX86_Posix; - } - } - else version (X86_64) - { - version = AlignFiberStackTo16Byte; - - version (CET) - { - // fiber_switchContext does not support shadow stack from - // Intel CET. So use ucontext implementation. - } - else version (D_X32) - { - // let X32 be handled by ucontext swapcontext - } - else - { - version = AsmExternal; - - version (MinGW) - version = GNU_AsmX86_64_Windows; - else version (Posix) - version = AsmX86_64_Posix; - } - } - else version (PPC) - { - version (Posix) - { - version = AsmPPC_Posix; - version = AsmExternal; - } - } - else version (PPC64) - { - version (Posix) - { - version = AlignFiberStackTo16Byte; - } - } - else version (MIPS_O32) - { - version (Posix) - { - version = AsmMIPS_O32_Posix; - version = AsmExternal; - } - } - else version (AArch64) - { - version (Posix) - { - version = AsmAArch64_Posix; - version = AsmExternal; - version = AlignFiberStackTo16Byte; - } - } - else version (ARM) - { - version (Posix) - { - version = AsmARM_Posix; - version = AsmExternal; - } - } - else version (SPARC) - { - // NOTE: The SPARC ABI specifies only doubleword alignment. - version = AlignFiberStackTo16Byte; - } - else version (SPARC64) - { - version = AlignFiberStackTo16Byte; - } - - version (Posix) - { - import core.sys.posix.unistd; // for sysconf - - version (AsmX86_Windows) {} else - version (AsmX86_Posix) {} else - version (AsmX86_64_Windows) {} else - version (AsmX86_64_Posix) {} else - version (AsmExternal) {} else - { - // NOTE: The ucontext implementation requires architecture specific - // data definitions to operate so testing for it must be done - // by checking for the existence of ucontext_t rather than by - // a version identifier. Please note that this is considered - // an obsolescent feature according to the POSIX spec, so a - // custom solution is still preferred. - import core.sys.posix.ucontext; - } - } - - static immutable size_t PAGESIZE; - version (Posix) static immutable size_t PTHREAD_STACK_MIN; -} - - -shared static this() -{ - version (Windows) - { - SYSTEM_INFO info; - GetSystemInfo(&info); - - PAGESIZE = info.dwPageSize; - assert(PAGESIZE < int.max); - } - else version (Posix) - { - PAGESIZE = cast(size_t)sysconf(_SC_PAGESIZE); - PTHREAD_STACK_MIN = cast(size_t)sysconf(_SC_THREAD_STACK_MIN); - } - else - { - static assert(0, "unimplemented"); - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// Fiber Entry Point and Context Switch -/////////////////////////////////////////////////////////////////////////////// - - -private -{ - extern (C) void fiber_entryPoint() nothrow - { - Fiber obj = Fiber.getThis(); - assert( obj ); - - assert( Thread.getThis().m_curr is obj.m_ctxt ); - atomicStore!(MemoryOrder.raw)(*cast(shared)&Thread.getThis().m_lock, false); - obj.m_ctxt.tstack = obj.m_ctxt.bstack; - obj.m_state = Fiber.State.EXEC; - - try - { - obj.run(); - } - catch ( Throwable t ) - { - obj.m_unhandled = t; - } - - static if ( __traits( compiles, ucontext_t ) ) - obj.m_ucur = &obj.m_utxt; - - obj.m_state = Fiber.State.TERM; - obj.switchOut(); - } - - // Look above the definition of 'class Fiber' for some information about the implementation of this routine - version (AsmExternal) - { - extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc; - version (AArch64) - extern (C) void fiber_trampoline() nothrow; - } - else - extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc - { - // NOTE: The data pushed and popped in this routine must match the - // default stack created by Fiber.initStack or the initial - // switch into a new context will fail. - - version (AsmX86_Windows) - { - asm pure nothrow @nogc - { - naked; - - // save current stack state - push EBP; - mov EBP, ESP; - push EDI; - push ESI; - push EBX; - push dword ptr FS:[0]; - push dword ptr FS:[4]; - push dword ptr FS:[8]; - push EAX; - - // store oldp again with more accurate address - mov EAX, dword ptr 8[EBP]; - mov [EAX], ESP; - // load newp to begin context switch - mov ESP, dword ptr 12[EBP]; - - // load saved state from new stack - pop EAX; - pop dword ptr FS:[8]; - pop dword ptr FS:[4]; - pop dword ptr FS:[0]; - pop EBX; - pop ESI; - pop EDI; - pop EBP; - - // 'return' to complete switch - pop ECX; - jmp ECX; - } - } - else version (AsmX86_64_Windows) - { - asm pure nothrow @nogc - { - naked; - - // save current stack state - // NOTE: When changing the layout of registers on the stack, - // make sure that the XMM registers are still aligned. - // On function entry, the stack is guaranteed to not - // be aligned to 16 bytes because of the return address - // on the stack. - push RBP; - mov RBP, RSP; - push R12; - push R13; - push R14; - push R15; - push RDI; - push RSI; - // 7 registers = 56 bytes; stack is now aligned to 16 bytes - sub RSP, 160; - movdqa [RSP + 144], XMM6; - movdqa [RSP + 128], XMM7; - movdqa [RSP + 112], XMM8; - movdqa [RSP + 96], XMM9; - movdqa [RSP + 80], XMM10; - movdqa [RSP + 64], XMM11; - movdqa [RSP + 48], XMM12; - movdqa [RSP + 32], XMM13; - movdqa [RSP + 16], XMM14; - movdqa [RSP], XMM15; - push RBX; - xor RAX,RAX; - push qword ptr GS:[RAX]; - push qword ptr GS:8[RAX]; - push qword ptr GS:16[RAX]; - - // store oldp - mov [RCX], RSP; - // load newp to begin context switch - mov RSP, RDX; - - // load saved state from new stack - pop qword ptr GS:16[RAX]; - pop qword ptr GS:8[RAX]; - pop qword ptr GS:[RAX]; - pop RBX; - movdqa XMM15, [RSP]; - movdqa XMM14, [RSP + 16]; - movdqa XMM13, [RSP + 32]; - movdqa XMM12, [RSP + 48]; - movdqa XMM11, [RSP + 64]; - movdqa XMM10, [RSP + 80]; - movdqa XMM9, [RSP + 96]; - movdqa XMM8, [RSP + 112]; - movdqa XMM7, [RSP + 128]; - movdqa XMM6, [RSP + 144]; - add RSP, 160; - pop RSI; - pop RDI; - pop R15; - pop R14; - pop R13; - pop R12; - pop RBP; - - // 'return' to complete switch - pop RCX; - jmp RCX; - } - } - else version (AsmX86_Posix) - { - asm pure nothrow @nogc - { - naked; - - // save current stack state - push EBP; - mov EBP, ESP; - push EDI; - push ESI; - push EBX; - push EAX; - - // store oldp again with more accurate address - mov EAX, dword ptr 8[EBP]; - mov [EAX], ESP; - // load newp to begin context switch - mov ESP, dword ptr 12[EBP]; - - // load saved state from new stack - pop EAX; - pop EBX; - pop ESI; - pop EDI; - pop EBP; - - // 'return' to complete switch - pop ECX; - jmp ECX; - } - } - else version (AsmX86_64_Posix) - { - asm pure nothrow @nogc - { - naked; - - // save current stack state - push RBP; - mov RBP, RSP; - push RBX; - push R12; - push R13; - push R14; - push R15; - - // store oldp - mov [RDI], RSP; - // load newp to begin context switch - mov RSP, RSI; - - // load saved state from new stack - pop R15; - pop R14; - pop R13; - pop R12; - pop RBX; - pop RBP; - - // 'return' to complete switch - pop RCX; - jmp RCX; - } - } - else static if ( __traits( compiles, ucontext_t ) ) - { - Fiber cfib = Fiber.getThis(); - void* ucur = cfib.m_ucur; - - *oldp = &ucur; - swapcontext( **(cast(ucontext_t***) oldp), - *(cast(ucontext_t**) newp) ); - } - else - static assert(0, "Not implemented"); - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// Fiber -/////////////////////////////////////////////////////////////////////////////// -/* - * Documentation of Fiber internals: - * - * The main routines to implement when porting Fibers to new architectures are - * fiber_switchContext and initStack. Some version constants have to be defined - * for the new platform as well, search for "Fiber Platform Detection and Memory Allocation". - * - * Fibers are based on a concept called 'Context'. A Context describes the execution - * state of a Fiber or main thread which is fully described by the stack, some - * registers and a return address at which the Fiber/Thread should continue executing. - * Please note that not only each Fiber has a Context, but each thread also has got a - * Context which describes the threads stack and state. If you call Fiber fib; fib.call - * the first time in a thread you switch from Threads Context into the Fibers Context. - * If you call fib.yield in that Fiber you switch out of the Fibers context and back - * into the Thread Context. (However, this is not always the case. You can call a Fiber - * from within another Fiber, then you switch Contexts between the Fibers and the Thread - * Context is not involved) - * - * In all current implementations the registers and the return address are actually - * saved on a Contexts stack. - * - * The fiber_switchContext routine has got two parameters: - * void** a: This is the _location_ where we have to store the current stack pointer, - * the stack pointer of the currently executing Context (Fiber or Thread). - * void* b: This is the pointer to the stack of the Context which we want to switch into. - * Note that we get the same pointer here as the one we stored into the void** a - * in a previous call to fiber_switchContext. - * - * In the simplest case, a fiber_switchContext rountine looks like this: - * fiber_switchContext: - * push {return Address} - * push {registers} - * copy {stack pointer} into {location pointed to by a} - * //We have now switch to the stack of a different Context! - * copy {b} into {stack pointer} - * pop {registers} - * pop {return Address} - * jump to {return Address} - * - * The GC uses the value returned in parameter a to scan the Fibers stack. It scans from - * the stack base to that value. As the GC dislikes false pointers we can actually optimize - * this a little: By storing registers which can not contain references to memory managed - * by the GC outside of the region marked by the stack base pointer and the stack pointer - * saved in fiber_switchContext we can prevent the GC from scanning them. - * Such registers are usually floating point registers and the return address. In order to - * implement this, we return a modified stack pointer from fiber_switchContext. However, - * we have to remember that when we restore the registers from the stack! - * - * --------------------------- <= Stack Base - * | Frame | <= Many other stack frames - * | Frame | - * |-------------------------| <= The last stack frame. This one is created by fiber_switchContext - * | registers with pointers | - * | | <= Stack pointer. GC stops scanning here - * | return address | - * |floating point registers | - * --------------------------- <= Real Stack End - * - * fiber_switchContext: - * push {registers with pointers} - * copy {stack pointer} into {location pointed to by a} - * push {return Address} - * push {Floating point registers} - * //We have now switch to the stack of a different Context! - * copy {b} into {stack pointer} - * //We now have to adjust the stack pointer to point to 'Real Stack End' so we can pop - * //the FP registers - * //+ or - depends on if your stack grows downwards or upwards - * {stack pointer} = {stack pointer} +- ({FPRegisters}.sizeof + {return address}.sizeof} - * pop {Floating point registers} - * pop {return Address} - * pop {registers with pointers} - * jump to {return Address} - * - * So the question now is which registers need to be saved? This depends on the specific - * architecture ABI of course, but here are some general guidelines: - * - If a register is callee-save (if the callee modifies the register it must saved and - * restored by the callee) it needs to be saved/restored in switchContext - * - If a register is caller-save it needn't be saved/restored. (Calling fiber_switchContext - * is a function call and the compiler therefore already must save these registers before - * calling fiber_switchContext) - * - Argument registers used for passing parameters to functions needn't be saved/restored - * - The return register needn't be saved/restored (fiber_switchContext hasn't got a return type) - * - All scratch registers needn't be saved/restored - * - The link register usually needn't be saved/restored (but sometimes it must be cleared - - * see below for details) - * - The frame pointer register - if it exists - is usually callee-save - * - All current implementations do not save control registers - * - * What happens on the first switch into a Fiber? We never saved a state for this fiber before, - * but the initial state is prepared in the initStack routine. (This routine will also be called - * when a Fiber is being resetted). initStack must produce exactly the same stack layout as the - * part of fiber_switchContext which saves the registers. Pay special attention to set the stack - * pointer correctly if you use the GC optimization mentioned before. the return Address saved in - * initStack must be the address of fiber_entrypoint. - * - * There's now a small but important difference between the first context switch into a fiber and - * further context switches. On the first switch, Fiber.call is used and the returnAddress in - * fiber_switchContext will point to fiber_entrypoint. The important thing here is that this jump - * is a _function call_, we call fiber_entrypoint by jumping before it's function prologue. On later - * calls, the user used yield() in a function, and therefore the return address points into a user - * function, after the yield call. So here the jump in fiber_switchContext is a _function return_, - * not a function call! - * - * The most important result of this is that on entering a function, i.e. fiber_entrypoint, we - * would have to provide a return address / set the link register once fiber_entrypoint - * returns. Now fiber_entrypoint does never return and therefore the actual value of the return - * address / link register is never read/used and therefore doesn't matter. When fiber_switchContext - * performs a _function return_ the value in the link register doesn't matter either. - * However, the link register will still be saved to the stack in fiber_entrypoint and some - * exception handling / stack unwinding code might read it from this stack location and crash. - * The exact solution depends on your architecture, but see the ARM implementation for a way - * to deal with this issue. - * - * The ARM implementation is meant to be used as a kind of documented example implementation. - * Look there for a concrete example. - * - * FIXME: fiber_entrypoint might benefit from a @noreturn attribute, but D doesn't have one. - */ - -/** - * This class provides a cooperative concurrency mechanism integrated with the - * threading and garbage collection functionality. Calling a fiber may be - * considered a blocking operation that returns when the fiber yields (via - * Fiber.yield()). Execution occurs within the context of the calling thread - * so synchronization is not necessary to guarantee memory visibility so long - * as the same thread calls the fiber each time. Please note that there is no - * requirement that a fiber be bound to one specific thread. Rather, fibers - * may be freely passed between threads so long as they are not currently - * executing. Like threads, a new fiber thread may be created using either - * derivation or composition, as in the following example. - * - * Warning: - * Status registers are not saved by the current implementations. This means - * floating point exception status bits (overflow, divide by 0), rounding mode - * and similar stuff is set per-thread, not per Fiber! - * - * Warning: - * On ARM FPU registers are not saved if druntime was compiled as ARM_SoftFloat. - * If such a build is used on a ARM_SoftFP system which actually has got a FPU - * and other libraries are using the FPU registers (other code is compiled - * as ARM_SoftFP) this can cause problems. Druntime must be compiled as - * ARM_SoftFP in this case. - * - * Example: - * ---------------------------------------------------------------------- - * - * class DerivedFiber : Fiber - * { - * this() - * { - * super( &run ); - * } - * - * private : - * void run() - * { - * printf( "Derived fiber running.\n" ); - * } - * } - * - * void fiberFunc() - * { - * printf( "Composed fiber running.\n" ); - * Fiber.yield(); - * printf( "Composed fiber running.\n" ); - * } - * - * // create instances of each type - * Fiber derived = new DerivedFiber(); - * Fiber composed = new Fiber( &fiberFunc ); - * - * // call both fibers once - * derived.call(); - * composed.call(); - * printf( "Execution returned to calling context.\n" ); - * composed.call(); - * - * // since each fiber has run to completion, each should have state TERM - * assert( derived.state == Fiber.State.TERM ); - * assert( composed.state == Fiber.State.TERM ); - * - * ---------------------------------------------------------------------- - * - * Authors: Based on a design by Mikola Lysenko. - */ -class Fiber -{ - /////////////////////////////////////////////////////////////////////////// - // Initialization - /////////////////////////////////////////////////////////////////////////// - - - /** - * Initializes a fiber object which is associated with a static - * D function. - * - * Params: - * fn = The fiber function. - * sz = The stack size for this fiber. - * guardPageSize = size of the guard page to trap fiber's stack - * overflows - * - * In: - * fn must not be null. - */ - this( void function() fn, size_t sz = PAGESIZE*4, - size_t guardPageSize = PAGESIZE ) nothrow - in - { - assert( fn ); - } - body - { - allocStack( sz, guardPageSize ); - reset( fn ); - } - - - /** - * Initializes a fiber object which is associated with a dynamic - * D function. - * - * Params: - * dg = The fiber function. - * sz = The stack size for this fiber. - * guardPageSize = size of the guard page to trap fiber's stack - * overflows - * - * In: - * dg must not be null. - */ - this( void delegate() dg, size_t sz = PAGESIZE*4, - size_t guardPageSize = PAGESIZE ) nothrow - in - { - assert( dg ); - } - body - { - allocStack( sz, guardPageSize); - reset( dg ); - } - - - /** - * Cleans up any remaining resources used by this object. - */ - ~this() nothrow @nogc - { - // NOTE: A live reference to this object will exist on its associated - // stack from the first time its call() method has been called - // until its execution completes with State.TERM. Thus, the only - // times this dtor should be called are either if the fiber has - // terminated (and therefore has no active stack) or if the user - // explicitly deletes this object. The latter case is an error - // but is not easily tested for, since State.HOLD may imply that - // the fiber was just created but has never been run. There is - // not a compelling case to create a State.INIT just to offer a - // means of ensuring the user isn't violating this object's - // contract, so for now this requirement will be enforced by - // documentation only. - freeStack(); - } - - - /////////////////////////////////////////////////////////////////////////// - // General Actions - /////////////////////////////////////////////////////////////////////////// - - - /** - * Transfers execution to this fiber object. The calling context will be - * suspended until the fiber calls Fiber.yield() or until it terminates - * via an unhandled exception. - * - * Params: - * rethrow = Rethrow any unhandled exception which may have caused this - * fiber to terminate. - * - * In: - * This fiber must be in state HOLD. - * - * Throws: - * Any exception not handled by the joined thread. - * - * Returns: - * Any exception not handled by this fiber if rethrow = false, null - * otherwise. - */ - // Not marked with any attributes, even though `nothrow @nogc` works - // because it calls arbitrary user code. Most of the implementation - // is already `@nogc nothrow`, but in order for `Fiber.call` to - // propagate the attributes of the user's function, the Fiber - // class needs to be templated. - final Throwable call( Rethrow rethrow = Rethrow.yes ) - { - return rethrow ? call!(Rethrow.yes)() : call!(Rethrow.no); - } - - /// ditto - final Throwable call( Rethrow rethrow )() - { - callImpl(); - if ( m_unhandled ) - { - Throwable t = m_unhandled; - m_unhandled = null; - static if ( rethrow ) - throw t; - else - return t; - } - return null; - } - - /// ditto - deprecated("Please pass Fiber.Rethrow.yes or .no instead of a boolean.") - final Throwable call( bool rethrow ) - { - return rethrow ? call!(Rethrow.yes)() : call!(Rethrow.no); - } - - private void callImpl() nothrow @nogc - in - { - assert( m_state == State.HOLD ); - } - body - { - Fiber cur = getThis(); - - static if ( __traits( compiles, ucontext_t ) ) - m_ucur = cur ? &cur.m_utxt : &Fiber.sm_utxt; - - setThis( this ); - this.switchIn(); - setThis( cur ); - - static if ( __traits( compiles, ucontext_t ) ) - m_ucur = null; - - // NOTE: If the fiber has terminated then the stack pointers must be - // reset. This ensures that the stack for this fiber is not - // scanned if the fiber has terminated. This is necessary to - // prevent any references lingering on the stack from delaying - // the collection of otherwise dead objects. The most notable - // being the current object, which is referenced at the top of - // fiber_entryPoint. - if ( m_state == State.TERM ) - { - m_ctxt.tstack = m_ctxt.bstack; - } - } - - /// Flag to control rethrow behavior of $(D $(LREF call)) - enum Rethrow : bool { no, yes } - - /** - * Resets this fiber so that it may be re-used, optionally with a - * new function/delegate. This routine should only be called for - * fibers that have terminated, as doing otherwise could result in - * scope-dependent functionality that is not executed. - * Stack-based classes, for example, may not be cleaned up - * properly if a fiber is reset before it has terminated. - * - * In: - * This fiber must be in state TERM or HOLD. - */ - final void reset() nothrow @nogc - in - { - assert( m_state == State.TERM || m_state == State.HOLD ); - } - body - { - m_ctxt.tstack = m_ctxt.bstack; - m_state = State.HOLD; - initStack(); - m_unhandled = null; - } - - /// ditto - final void reset( void function() fn ) nothrow @nogc - { - reset(); - m_fn = fn; - m_call = Call.FN; - } - - /// ditto - final void reset( void delegate() dg ) nothrow @nogc - { - reset(); - m_dg = dg; - m_call = Call.DG; - } - - /////////////////////////////////////////////////////////////////////////// - // General Properties - /////////////////////////////////////////////////////////////////////////// - - - /** - * A fiber may occupy one of three states: HOLD, EXEC, and TERM. The HOLD - * state applies to any fiber that is suspended and ready to be called. - * The EXEC state will be set for any fiber that is currently executing. - * And the TERM state is set when a fiber terminates. Once a fiber - * terminates, it must be reset before it may be called again. - */ - enum State - { - HOLD, /// - EXEC, /// - TERM /// - } - - - /** - * Gets the current state of this fiber. - * - * Returns: - * The state of this fiber as an enumerated value. - */ - final @property State state() const @safe pure nothrow @nogc - { - return m_state; - } - - - /////////////////////////////////////////////////////////////////////////// - // Actions on Calling Fiber - /////////////////////////////////////////////////////////////////////////// - - - /** - * Forces a context switch to occur away from the calling fiber. - */ - static void yield() nothrow @nogc - { - Fiber cur = getThis(); - assert( cur, "Fiber.yield() called with no active fiber" ); - assert( cur.m_state == State.EXEC ); - - static if ( __traits( compiles, ucontext_t ) ) - cur.m_ucur = &cur.m_utxt; - - cur.m_state = State.HOLD; - cur.switchOut(); - cur.m_state = State.EXEC; - } - - - /** - * Forces a context switch to occur away from the calling fiber and then - * throws obj in the calling fiber. - * - * Params: - * t = The object to throw. - * - * In: - * t must not be null. - */ - static void yieldAndThrow( Throwable t ) nothrow @nogc - in - { - assert( t ); - } - body - { - Fiber cur = getThis(); - assert( cur, "Fiber.yield() called with no active fiber" ); - assert( cur.m_state == State.EXEC ); - - static if ( __traits( compiles, ucontext_t ) ) - cur.m_ucur = &cur.m_utxt; - - cur.m_unhandled = t; - cur.m_state = State.HOLD; - cur.switchOut(); - cur.m_state = State.EXEC; - } - - - /////////////////////////////////////////////////////////////////////////// - // Fiber Accessors - /////////////////////////////////////////////////////////////////////////// - - - /** - * Provides a reference to the calling fiber or null if no fiber is - * currently active. - * - * Returns: - * The fiber object representing the calling fiber or null if no fiber - * is currently active within this thread. The result of deleting this object is undefined. - */ - static Fiber getThis() @safe nothrow @nogc - { - return sm_this; - } - - - /////////////////////////////////////////////////////////////////////////// - // Static Initialization - /////////////////////////////////////////////////////////////////////////// - - - version (Posix) - { - static this() - { - static if ( __traits( compiles, ucontext_t ) ) - { - int status = getcontext( &sm_utxt ); - assert( status == 0 ); - } - } - } - -private: - // - // Initializes a fiber object which has no associated executable function. - // - this() @safe pure nothrow @nogc - { - m_call = Call.NO; - } - - - // - // Fiber entry point. Invokes the function or delegate passed on - // construction (if any). - // - final void run() - { - switch ( m_call ) - { - case Call.FN: - m_fn(); - break; - case Call.DG: - m_dg(); - break; - default: - break; - } - } - - -private: - // - // The type of routine passed on fiber construction. - // - enum Call - { - NO, - FN, - DG - } - - - // - // Standard fiber data - // - Call m_call; - union - { - void function() m_fn; - void delegate() m_dg; - } - bool m_isRunning; - Throwable m_unhandled; - State m_state; - - -private: - /////////////////////////////////////////////////////////////////////////// - // Stack Management - /////////////////////////////////////////////////////////////////////////// - - - // - // Allocate a new stack for this fiber. - // - final void allocStack( size_t sz, size_t guardPageSize ) nothrow - in - { - assert( !m_pmem && !m_ctxt ); - } - body - { - // adjust alloc size to a multiple of PAGESIZE - sz += PAGESIZE - 1; - sz -= sz % PAGESIZE; - - // NOTE: This instance of Thread.Context is dynamic so Fiber objects - // can be collected by the GC so long as no user level references - // to the object exist. If m_ctxt were not dynamic then its - // presence in the global context list would be enough to keep - // this object alive indefinitely. An alternative to allocating - // room for this struct explicitly would be to mash it into the - // base of the stack being allocated below. However, doing so - // requires too much special logic to be worthwhile. - m_ctxt = new Thread.Context; - - static if ( __traits( compiles, VirtualAlloc ) ) - { - // reserve memory for stack - m_pmem = VirtualAlloc( null, - sz + guardPageSize, - MEM_RESERVE, - PAGE_NOACCESS ); - if ( !m_pmem ) - onOutOfMemoryError(); - - version (StackGrowsDown) - { - void* stack = m_pmem + guardPageSize; - void* guard = m_pmem; - void* pbase = stack + sz; - } - else - { - void* stack = m_pmem; - void* guard = m_pmem + sz; - void* pbase = stack; - } - - // allocate reserved stack segment - stack = VirtualAlloc( stack, - sz, - MEM_COMMIT, - PAGE_READWRITE ); - if ( !stack ) - onOutOfMemoryError(); - - if (guardPageSize) - { - // allocate reserved guard page - guard = VirtualAlloc( guard, - guardPageSize, - MEM_COMMIT, - PAGE_READWRITE | PAGE_GUARD ); - if ( !guard ) - onOutOfMemoryError(); - } - - m_ctxt.bstack = pbase; - m_ctxt.tstack = pbase; - m_size = sz; - } - else - { - version (Posix) import core.sys.posix.sys.mman; // mmap - version (FreeBSD) import core.sys.freebsd.sys.mman : MAP_ANON; - version (NetBSD) import core.sys.netbsd.sys.mman : MAP_ANON; - version (OpenBSD) import core.sys.openbsd.sys.mman : MAP_ANON; - version (DragonFlyBSD) import core.sys.dragonflybsd.sys.mman : MAP_ANON; - version (CRuntime_Glibc) import core.sys.linux.sys.mman : MAP_ANON; - version (Darwin) import core.sys.darwin.sys.mman : MAP_ANON; - version (CRuntime_UClibc) import core.sys.linux.sys.mman : MAP_ANON; - - static if ( __traits( compiles, mmap ) ) - { - // Allocate more for the memory guard - sz += guardPageSize; - - m_pmem = mmap( null, - sz, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, - -1, - 0 ); - if ( m_pmem == MAP_FAILED ) - m_pmem = null; - } - else static if ( __traits( compiles, valloc ) ) - { - m_pmem = valloc( sz ); - } - else static if ( __traits( compiles, malloc ) ) - { - m_pmem = malloc( sz ); - } - else - { - m_pmem = null; - } - - if ( !m_pmem ) - onOutOfMemoryError(); - - version (StackGrowsDown) - { - m_ctxt.bstack = m_pmem + sz; - m_ctxt.tstack = m_pmem + sz; - void* guard = m_pmem; - } - else - { - m_ctxt.bstack = m_pmem; - m_ctxt.tstack = m_pmem; - void* guard = m_pmem + sz - guardPageSize; - } - m_size = sz; - - static if ( __traits( compiles, mmap ) ) - { - if (guardPageSize) - { - // protect end of stack - if ( mprotect(guard, guardPageSize, PROT_NONE) == -1 ) - abort(); - } - } - else - { - // Supported only for mmap allocated memory - results are - // undefined if applied to memory not obtained by mmap - } - } - - Thread.add( m_ctxt ); - } - - - // - // Free this fiber's stack. - // - final void freeStack() nothrow @nogc - in - { - assert( m_pmem && m_ctxt ); - } - body - { - // NOTE: m_ctxt is guaranteed to be alive because it is held in the - // global context list. - Thread.slock.lock_nothrow(); - scope(exit) Thread.slock.unlock_nothrow(); - Thread.remove( m_ctxt ); - - static if ( __traits( compiles, VirtualAlloc ) ) - { - VirtualFree( m_pmem, 0, MEM_RELEASE ); - } - else - { - import core.sys.posix.sys.mman; // munmap - - static if ( __traits( compiles, mmap ) ) - { - munmap( m_pmem, m_size ); - } - else static if ( __traits( compiles, valloc ) ) - { - free( m_pmem ); - } - else static if ( __traits( compiles, malloc ) ) - { - free( m_pmem ); - } - } - m_pmem = null; - m_ctxt = null; - } - - - // - // Initialize the allocated stack. - // Look above the definition of 'class Fiber' for some information about the implementation of this routine - // - final void initStack() nothrow @nogc - in - { - assert( m_ctxt.tstack && m_ctxt.tstack == m_ctxt.bstack ); - assert( cast(size_t) m_ctxt.bstack % (void*).sizeof == 0 ); - } - body - { - void* pstack = m_ctxt.tstack; - scope( exit ) m_ctxt.tstack = pstack; - - void push( size_t val ) nothrow - { - version (StackGrowsDown) - { - pstack -= size_t.sizeof; - *(cast(size_t*) pstack) = val; - } - else - { - pstack += size_t.sizeof; - *(cast(size_t*) pstack) = val; - } - } - - // NOTE: On OS X the stack must be 16-byte aligned according - // to the IA-32 call spec. For x86_64 the stack also needs to - // be aligned to 16-byte according to SysV AMD64 ABI. - version (AlignFiberStackTo16Byte) - { - version (StackGrowsDown) - { - pstack = cast(void*)(cast(size_t)(pstack) - (cast(size_t)(pstack) & 0x0F)); - } - else - { - pstack = cast(void*)(cast(size_t)(pstack) + (cast(size_t)(pstack) & 0x0F)); - } - } - - version (AsmX86_Windows) - { - version (StackGrowsDown) {} else static assert( false ); - - // On Windows Server 2008 and 2008 R2, an exploit mitigation - // technique known as SEHOP is activated by default. To avoid - // hijacking of the exception handler chain, the presence of a - // Windows-internal handler (ntdll.dll!FinalExceptionHandler) at - // its end is tested by RaiseException. If it is not present, all - // handlers are disregarded, and the program is thus aborted - // (see http://blogs.technet.com/b/srd/archive/2009/02/02/ - // preventing-the-exploitation-of-seh-overwrites-with-sehop.aspx). - // For new threads, this handler is installed by Windows immediately - // after creation. To make exception handling work in fibers, we - // have to insert it for our new stacks manually as well. - // - // To do this, we first determine the handler by traversing the SEH - // chain of the current thread until its end, and then construct a - // registration block for the last handler on the newly created - // thread. We then continue to push all the initial register values - // for the first context switch as for the other implementations. - // - // Note that this handler is never actually invoked, as we install - // our own one on top of it in the fiber entry point function. - // Thus, it should not have any effects on OSes not implementing - // exception chain verification. - - alias fp_t = void function(); // Actual signature not relevant. - static struct EXCEPTION_REGISTRATION - { - EXCEPTION_REGISTRATION* next; // sehChainEnd if last one. - fp_t handler; - } - enum sehChainEnd = cast(EXCEPTION_REGISTRATION*) 0xFFFFFFFF; - - __gshared static fp_t finalHandler = null; - if ( finalHandler is null ) - { - static EXCEPTION_REGISTRATION* fs0() nothrow - { - asm pure nothrow @nogc - { - naked; - mov EAX, FS:[0]; - ret; - } - } - auto reg = fs0(); - while ( reg.next != sehChainEnd ) reg = reg.next; - - // Benign races are okay here, just to avoid re-lookup on every - // fiber creation. - finalHandler = reg.handler; - } - - // When linking with /safeseh (supported by LDC, but not DMD) - // the exception chain must not extend to the very top - // of the stack, otherwise the exception chain is also considered - // invalid. Reserving additional 4 bytes at the top of the stack will - // keep the EXCEPTION_REGISTRATION below that limit - size_t reserve = EXCEPTION_REGISTRATION.sizeof + 4; - pstack -= reserve; - *(cast(EXCEPTION_REGISTRATION*)pstack) = - EXCEPTION_REGISTRATION( sehChainEnd, finalHandler ); - - push( cast(size_t) &fiber_entryPoint ); // EIP - push( cast(size_t) m_ctxt.bstack - reserve ); // EBP - push( 0x00000000 ); // EDI - push( 0x00000000 ); // ESI - push( 0x00000000 ); // EBX - push( cast(size_t) m_ctxt.bstack - reserve ); // FS:[0] - push( cast(size_t) m_ctxt.bstack ); // FS:[4] - push( cast(size_t) m_ctxt.bstack - m_size ); // FS:[8] - push( 0x00000000 ); // EAX - } - else version (AsmX86_64_Windows) - { - // Using this trampoline instead of the raw fiber_entryPoint - // ensures that during context switches, source and destination - // stacks have the same alignment. Otherwise, the stack would need - // to be shifted by 8 bytes for the first call, as fiber_entryPoint - // is an actual function expecting a stack which is not aligned - // to 16 bytes. - static void trampoline() - { - asm pure nothrow @nogc - { - naked; - sub RSP, 32; // Shadow space (Win64 calling convention) - call fiber_entryPoint; - xor RCX, RCX; // This should never be reached, as - jmp RCX; // fiber_entryPoint must never return. - } - } - - push( cast(size_t) &trampoline ); // RIP - push( 0x00000000_00000000 ); // RBP - push( 0x00000000_00000000 ); // R12 - push( 0x00000000_00000000 ); // R13 - push( 0x00000000_00000000 ); // R14 - push( 0x00000000_00000000 ); // R15 - push( 0x00000000_00000000 ); // RDI - push( 0x00000000_00000000 ); // RSI - push( 0x00000000_00000000 ); // XMM6 (high) - push( 0x00000000_00000000 ); // XMM6 (low) - push( 0x00000000_00000000 ); // XMM7 (high) - push( 0x00000000_00000000 ); // XMM7 (low) - push( 0x00000000_00000000 ); // XMM8 (high) - push( 0x00000000_00000000 ); // XMM8 (low) - push( 0x00000000_00000000 ); // XMM9 (high) - push( 0x00000000_00000000 ); // XMM9 (low) - push( 0x00000000_00000000 ); // XMM10 (high) - push( 0x00000000_00000000 ); // XMM10 (low) - push( 0x00000000_00000000 ); // XMM11 (high) - push( 0x00000000_00000000 ); // XMM11 (low) - push( 0x00000000_00000000 ); // XMM12 (high) - push( 0x00000000_00000000 ); // XMM12 (low) - push( 0x00000000_00000000 ); // XMM13 (high) - push( 0x00000000_00000000 ); // XMM13 (low) - push( 0x00000000_00000000 ); // XMM14 (high) - push( 0x00000000_00000000 ); // XMM14 (low) - push( 0x00000000_00000000 ); // XMM15 (high) - push( 0x00000000_00000000 ); // XMM15 (low) - push( 0x00000000_00000000 ); // RBX - push( 0xFFFFFFFF_FFFFFFFF ); // GS:[0] - version (StackGrowsDown) - { - push( cast(size_t) m_ctxt.bstack ); // GS:[8] - push( cast(size_t) m_ctxt.bstack - m_size ); // GS:[16] - } - else - { - push( cast(size_t) m_ctxt.bstack ); // GS:[8] - push( cast(size_t) m_ctxt.bstack + m_size ); // GS:[16] - } - } - else version (AsmX86_Posix) - { - push( 0x00000000 ); // Return address of fiber_entryPoint call - push( cast(size_t) &fiber_entryPoint ); // EIP - push( cast(size_t) m_ctxt.bstack ); // EBP - push( 0x00000000 ); // EDI - push( 0x00000000 ); // ESI - push( 0x00000000 ); // EBX - push( 0x00000000 ); // EAX - } - else version (AsmX86_64_Posix) - { - push( 0x00000000_00000000 ); // Return address of fiber_entryPoint call - push( cast(size_t) &fiber_entryPoint ); // RIP - push( cast(size_t) m_ctxt.bstack ); // RBP - push( 0x00000000_00000000 ); // RBX - push( 0x00000000_00000000 ); // R12 - push( 0x00000000_00000000 ); // R13 - push( 0x00000000_00000000 ); // R14 - push( 0x00000000_00000000 ); // R15 - } - else version (AsmPPC_Posix) - { - version (StackGrowsDown) - { - pstack -= int.sizeof * 5; - } - else - { - pstack += int.sizeof * 5; - } - - push( cast(size_t) &fiber_entryPoint ); // link register - push( 0x00000000 ); // control register - push( 0x00000000 ); // old stack pointer - - // GPR values - version (StackGrowsDown) - { - pstack -= int.sizeof * 20; - } - else - { - pstack += int.sizeof * 20; - } - - assert( (cast(size_t) pstack & 0x0f) == 0 ); - } - else version (AsmMIPS_O32_Posix) - { - version (StackGrowsDown) {} - else static assert(0); - - /* We keep the FP registers and the return address below - * the stack pointer, so they don't get scanned by the - * GC. The last frame before swapping the stack pointer is - * organized like the following. - * - * |-----------|<= frame pointer - * | $gp | - * | $s0-8 | - * |-----------|<= stack pointer - * | $ra | - * | align(8) | - * | $f20-30 | - * |-----------| - * - */ - enum SZ_GP = 10 * size_t.sizeof; // $gp + $s0-8 - enum SZ_RA = size_t.sizeof; // $ra - version (MIPS_HardFloat) - { - enum SZ_FP = 6 * 8; // $f20-30 - enum ALIGN = -(SZ_FP + SZ_RA) & (8 - 1); - } - else - { - enum SZ_FP = 0; - enum ALIGN = 0; - } - - enum BELOW = SZ_FP + ALIGN + SZ_RA; - enum ABOVE = SZ_GP; - enum SZ = BELOW + ABOVE; - - (cast(ubyte*)pstack - SZ)[0 .. SZ] = 0; - pstack -= ABOVE; - *cast(size_t*)(pstack - SZ_RA) = cast(size_t)&fiber_entryPoint; - } - else version (AsmAArch64_Posix) - { - // Like others, FP registers and return address (lr) are kept - // below the saved stack top (tstack) to hide from GC scanning. - // fiber_switchContext expects newp sp to look like this: - // 19: x19 - // ... - // 9: x29 (fp) <-- newp tstack - // 8: x30 (lr) [&fiber_entryPoint] - // 7: d8 - // ... - // 0: d15 - - version (StackGrowsDown) {} - else - static assert(false, "Only full descending stacks supported on AArch64"); - - // Only need to set return address (lr). Everything else is fine - // zero initialized. - pstack -= size_t.sizeof * 11; // skip past x19-x29 - push(cast(size_t) &fiber_trampoline); // see threadasm.S for docs - pstack += size_t.sizeof; // adjust sp (newp) above lr - } - else version (AsmARM_Posix) - { - /* We keep the FP registers and the return address below - * the stack pointer, so they don't get scanned by the - * GC. The last frame before swapping the stack pointer is - * organized like the following. - * - * | |-----------|<= 'frame starts here' - * | | fp | (the actual frame pointer, r11 isn't - * | | r10-r4 | updated and still points to the previous frame) - * | |-----------|<= stack pointer - * | | lr | - * | | 4byte pad | - * | | d15-d8 |(if FP supported) - * | |-----------| - * Y - * stack grows down: The pointer value here is smaller than some lines above - */ - // frame pointer can be zero, r10-r4 also zero initialized - version (StackGrowsDown) - pstack -= int.sizeof * 8; - else - static assert(false, "Only full descending stacks supported on ARM"); - - // link register - push( cast(size_t) &fiber_entryPoint ); - /* - * We do not push padding and d15-d8 as those are zero initialized anyway - * Position the stack pointer above the lr register - */ - pstack += int.sizeof * 1; - } - else version (GNU_AsmX86_Windows) - { - version (StackGrowsDown) {} else static assert( false ); - - // Currently, MinGW doesn't utilize SEH exceptions. - // See DMD AsmX86_Windows If this code ever becomes fails and SEH is used. - - push( 0x00000000 ); // Return address of fiber_entryPoint call - push( cast(size_t) &fiber_entryPoint ); // EIP - push( 0x00000000 ); // EBP - push( 0x00000000 ); // EDI - push( 0x00000000 ); // ESI - push( 0x00000000 ); // EBX - push( 0xFFFFFFFF ); // FS:[0] - Current SEH frame - push( cast(size_t) m_ctxt.bstack ); // FS:[4] - Top of stack - push( cast(size_t) m_ctxt.bstack - m_size ); // FS:[8] - Bottom of stack - push( 0x00000000 ); // EAX - } - else version (GNU_AsmX86_64_Windows) - { - push( 0x00000000_00000000 ); // Return address of fiber_entryPoint call - push( cast(size_t) &fiber_entryPoint ); // RIP - push( 0x00000000_00000000 ); // RBP - push( 0x00000000_00000000 ); // RBX - push( 0x00000000_00000000 ); // R12 - push( 0x00000000_00000000 ); // R13 - push( 0x00000000_00000000 ); // R14 - push( 0x00000000_00000000 ); // R15 - push( 0xFFFFFFFF_FFFFFFFF ); // GS:[0] - Current SEH frame - version (StackGrowsDown) - { - push( cast(size_t) m_ctxt.bstack ); // GS:[8] - Top of stack - push( cast(size_t) m_ctxt.bstack - m_size ); // GS:[16] - Bottom of stack - } - else - { - push( cast(size_t) m_ctxt.bstack ); // GS:[8] - Top of stack - push( cast(size_t) m_ctxt.bstack + m_size ); // GS:[16] - Bottom of stack - } - } - else static if ( __traits( compiles, ucontext_t ) ) - { - getcontext( &m_utxt ); - m_utxt.uc_stack.ss_sp = m_pmem; - m_utxt.uc_stack.ss_size = m_size; - makecontext( &m_utxt, &fiber_entryPoint, 0 ); - // NOTE: If ucontext is being used then the top of the stack will - // be a pointer to the ucontext_t struct for that fiber. - push( cast(size_t) &m_utxt ); - } - else - static assert(0, "Not implemented"); - } - - - Thread.Context* m_ctxt; - size_t m_size; - void* m_pmem; - - static if ( __traits( compiles, ucontext_t ) ) - { - // NOTE: The static ucontext instance is used to represent the context - // of the executing thread. - static ucontext_t sm_utxt = void; - ucontext_t m_utxt = void; - ucontext_t* m_ucur = null; - } - else static if (GNU_Enable_CET) - { - // When libphobos was built with --enable-cet, these fields need to - // always be present in the Fiber class layout. - import core.sys.posix.ucontext; - static ucontext_t sm_utxt = void; - ucontext_t m_utxt = void; - ucontext_t* m_ucur = null; - } - - -private: - /////////////////////////////////////////////////////////////////////////// - // Storage of Active Fiber - /////////////////////////////////////////////////////////////////////////// - - - // - // Sets a thread-local reference to the current fiber object. - // - static void setThis( Fiber f ) nothrow @nogc - { - sm_this = f; - } - - static Fiber sm_this; - - -private: - /////////////////////////////////////////////////////////////////////////// - // Context Switching - /////////////////////////////////////////////////////////////////////////// - - - // - // Switches into the stack held by this fiber. - // - final void switchIn() nothrow @nogc - { - Thread tobj = Thread.getThis(); - void** oldp = &tobj.m_curr.tstack; - void* newp = m_ctxt.tstack; - - // NOTE: The order of operations here is very important. The current - // stack top must be stored before m_lock is set, and pushContext - // must not be called until after m_lock is set. This process - // is intended to prevent a race condition with the suspend - // mechanism used for garbage collection. If it is not followed, - // a badly timed collection could cause the GC to scan from the - // bottom of one stack to the top of another, or to miss scanning - // a stack that still contains valid data. The old stack pointer - // oldp will be set again before the context switch to guarantee - // that it points to exactly the correct stack location so the - // successive pop operations will succeed. - *oldp = getStackTop(); - atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, true); - tobj.pushContext( m_ctxt ); - - fiber_switchContext( oldp, newp ); - - // NOTE: As above, these operations must be performed in a strict order - // to prevent Bad Things from happening. - tobj.popContext(); - atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, false); - tobj.m_curr.tstack = tobj.m_curr.bstack; - } - - - // - // Switches out of the current stack and into the enclosing stack. - // - final void switchOut() nothrow @nogc - { - Thread tobj = Thread.getThis(); - void** oldp = &m_ctxt.tstack; - void* newp = tobj.m_curr.within.tstack; - - // NOTE: The order of operations here is very important. The current - // stack top must be stored before m_lock is set, and pushContext - // must not be called until after m_lock is set. This process - // is intended to prevent a race condition with the suspend - // mechanism used for garbage collection. If it is not followed, - // a badly timed collection could cause the GC to scan from the - // bottom of one stack to the top of another, or to miss scanning - // a stack that still contains valid data. The old stack pointer - // oldp will be set again before the context switch to guarantee - // that it points to exactly the correct stack location so the - // successive pop operations will succeed. - *oldp = getStackTop(); - atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, true); - - fiber_switchContext( oldp, newp ); - - // NOTE: As above, these operations must be performed in a strict order - // to prevent Bad Things from happening. - // NOTE: If use of this fiber is multiplexed across threads, the thread - // executing here may be different from the one above, so get the - // current thread handle before unlocking, etc. - tobj = Thread.getThis(); - atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, false); - tobj.m_curr.tstack = tobj.m_curr.bstack; - } -} - - -version (unittest) -{ - class TestFiber : Fiber - { - this() - { - super(&run); - } - - void run() - { - foreach (i; 0 .. 1000) - { - sum += i; - Fiber.yield(); - } - } - - enum expSum = 1000 * 999 / 2; - size_t sum; - } - - void runTen() - { - TestFiber[10] fibs; - foreach (ref fib; fibs) - fib = new TestFiber(); - - bool cont; - do { - cont = false; - foreach (fib; fibs) { - if (fib.state == Fiber.State.HOLD) - { - fib.call(); - cont |= fib.state != Fiber.State.TERM; - } - } - } while (cont); - - foreach (fib; fibs) - { - assert(fib.sum == TestFiber.expSum); - } - } -} - - -// Single thread running separate fibers -unittest -{ - runTen(); -} - - -// Multiple threads running separate fibers -unittest -{ - auto group = new ThreadGroup(); - foreach (_; 0 .. 4) - { - group.create(&runTen); - } - group.joinAll(); -} - - -// Multiple threads running shared fibers -version (PPC) version = UnsafeFiberMigration; -version (PPC64) version = UnsafeFiberMigration; - -version (UnsafeFiberMigration) -{ - // XBUG: core.thread fibers are supposed to be safe to migrate across - // threads, however, there is a problem: GCC always assumes that the - // address of thread-local variables don't change while on a given stack. - // In consequence, migrating fibers between threads currently is an unsafe - // thing to do, and will break on some targets (possibly PR26461). -} -else -{ - version = FiberMigrationUnittest; -} - -version (FiberMigrationUnittest) -unittest -{ - shared bool[10] locks; - TestFiber[10] fibs; - - void runShared() - { - bool cont; - do { - cont = false; - foreach (idx; 0 .. 10) - { - if (cas(&locks[idx], false, true)) - { - if (fibs[idx].state == Fiber.State.HOLD) - { - fibs[idx].call(); - cont |= fibs[idx].state != Fiber.State.TERM; - } - locks[idx] = false; - } - else - { - cont = true; - } - } - } while (cont); - } - - foreach (ref fib; fibs) - { - fib = new TestFiber(); - } - - auto group = new ThreadGroup(); - foreach (_; 0 .. 4) - { - group.create(&runShared); - } - group.joinAll(); - - foreach (fib; fibs) - { - assert(fib.sum == TestFiber.expSum); - } -} - - -// Test exception handling inside fibers. -version (Win32) { - // broken on win32 under windows server 2012: bug 13821 -} else unittest { - enum MSG = "Test message."; - string caughtMsg; - (new Fiber({ - try - { - throw new Exception(MSG); - } - catch (Exception e) - { - caughtMsg = e.msg; - } - })).call(); - assert(caughtMsg == MSG); -} - - -unittest -{ - int x = 0; - - (new Fiber({ - x++; - })).call(); - assert( x == 1 ); -} - -nothrow unittest -{ - new Fiber({}).call!(Fiber.Rethrow.no)(); -} - -unittest -{ - new Fiber({}).call(Fiber.Rethrow.yes); - new Fiber({}).call(Fiber.Rethrow.no); -} - -deprecated unittest -{ - new Fiber({}).call(true); - new Fiber({}).call(false); -} - -version (Win32) { - // broken on win32 under windows server 2012: bug 13821 -} else unittest { - enum MSG = "Test message."; - - try - { - (new Fiber({ - throw new Exception( MSG ); - })).call(); - assert( false, "Expected rethrown exception." ); - } - catch ( Throwable t ) - { - assert( t.msg == MSG ); - } -} - -// Test exception chaining when switching contexts in finally blocks. -unittest -{ - static void throwAndYield(string msg) { - try { - throw new Exception(msg); - } finally { - Fiber.yield(); - } - } - - static void fiber(string name) { - try { - try { - throwAndYield(name ~ ".1"); - } finally { - throwAndYield(name ~ ".2"); - } - } catch (Exception e) { - assert(e.msg == name ~ ".1"); - assert(e.next); - assert(e.next.msg == name ~ ".2"); - assert(!e.next.next); - } - } - - auto first = new Fiber(() => fiber("first")); - auto second = new Fiber(() => fiber("second")); - first.call(); - second.call(); - first.call(); - second.call(); - first.call(); - second.call(); - assert(first.state == Fiber.State.TERM); - assert(second.state == Fiber.State.TERM); -} - -// Test Fiber resetting -unittest -{ - static string method; - - static void foo() - { - method = "foo"; - } - - void bar() - { - method = "bar"; - } - - static void expect(Fiber fib, string s) - { - assert(fib.state == Fiber.State.HOLD); - fib.call(); - assert(fib.state == Fiber.State.TERM); - assert(method == s); method = null; - } - auto fib = new Fiber(&foo); - expect(fib, "foo"); - - fib.reset(); - expect(fib, "foo"); - - fib.reset(&foo); - expect(fib, "foo"); - - fib.reset(&bar); - expect(fib, "bar"); - - fib.reset(function void(){method = "function";}); - expect(fib, "function"); - - fib.reset(delegate void(){method = "delegate";}); - expect(fib, "delegate"); -} - -// Test unsafe reset in hold state -unittest -{ - auto fib = new Fiber(function {ubyte[2048] buf = void; Fiber.yield();}, 4096); - foreach (_; 0 .. 10) - { - fib.call(); - assert(fib.state == Fiber.State.HOLD); - fib.reset(); - } -} - -// stress testing GC stack scanning -unittest -{ - import core.memory; - - static void unreferencedThreadObject() - { - static void sleep() { Thread.sleep(dur!"msecs"(100)); } - auto thread = new Thread(&sleep).start(); - } - unreferencedThreadObject(); - GC.collect(); - - static class Foo - { - this(int value) - { - _value = value; - } - - int bar() - { - return _value; - } - - int _value; - } - - static void collect() - { - auto foo = new Foo(2); - assert(foo.bar() == 2); - GC.collect(); - Fiber.yield(); - GC.collect(); - assert(foo.bar() == 2); - } - - auto fiber = new Fiber(&collect); - - fiber.call(); - GC.collect(); - fiber.call(); - - // thread reference - auto foo = new Foo(2); - - void collect2() - { - assert(foo.bar() == 2); - GC.collect(); - Fiber.yield(); - GC.collect(); - assert(foo.bar() == 2); - } - - fiber = new Fiber(&collect2); - - fiber.call(); - GC.collect(); - fiber.call(); - - static void recurse(size_t cnt) - { - --cnt; - Fiber.yield(); - if (cnt) - { - auto fib = new Fiber(() { recurse(cnt); }); - fib.call(); - GC.collect(); - fib.call(); - } - } - fiber = new Fiber(() { recurse(20); }); - fiber.call(); -} - - -version (AsmX86_64_Windows) -{ - // Test Windows x64 calling convention - unittest - { - void testNonvolatileRegister(alias REG)() - { - auto zeroRegister = new Fiber(() { - mixin("asm pure nothrow @nogc { naked; xor "~REG~", "~REG~"; ret; }"); - }); - long after; - - mixin("asm pure nothrow @nogc { mov "~REG~", 0xFFFFFFFFFFFFFFFF; }"); - zeroRegister.call(); - mixin("asm pure nothrow @nogc { mov after, "~REG~"; }"); - - assert(after == -1); - } - - void testNonvolatileRegisterSSE(alias REG)() - { - auto zeroRegister = new Fiber(() { - mixin("asm pure nothrow @nogc { naked; xorpd "~REG~", "~REG~"; ret; }"); - }); - long[2] before = [0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF], after; - - mixin("asm pure nothrow @nogc { movdqu "~REG~", before; }"); - zeroRegister.call(); - mixin("asm pure nothrow @nogc { movdqu after, "~REG~"; }"); - - assert(before == after); - } - - testNonvolatileRegister!("R12")(); - testNonvolatileRegister!("R13")(); - testNonvolatileRegister!("R14")(); - testNonvolatileRegister!("R15")(); - testNonvolatileRegister!("RDI")(); - testNonvolatileRegister!("RSI")(); - testNonvolatileRegister!("RBX")(); - - testNonvolatileRegisterSSE!("XMM6")(); - testNonvolatileRegisterSSE!("XMM7")(); - testNonvolatileRegisterSSE!("XMM8")(); - testNonvolatileRegisterSSE!("XMM9")(); - testNonvolatileRegisterSSE!("XMM10")(); - testNonvolatileRegisterSSE!("XMM11")(); - testNonvolatileRegisterSSE!("XMM12")(); - testNonvolatileRegisterSSE!("XMM13")(); - testNonvolatileRegisterSSE!("XMM14")(); - testNonvolatileRegisterSSE!("XMM15")(); - } -} - - -version (D_InlineAsm_X86_64) -{ - unittest - { - void testStackAlignment() - { - void* pRSP; - asm pure nothrow @nogc - { - mov pRSP, RSP; - } - assert((cast(size_t)pRSP & 0xF) == 0); - } - - auto fib = new Fiber(&testStackAlignment); - fib.call(); - } -} - -// regression test for Issue 13416 -version (FreeBSD) unittest -{ - static void loop() - { - pthread_attr_t attr; - pthread_attr_init(&attr); - auto thr = pthread_self(); - foreach (i; 0 .. 50) - pthread_attr_get_np(thr, &attr); - pthread_attr_destroy(&attr); - } - - auto thr = new Thread(&loop).start(); - foreach (i; 0 .. 50) - { - thread_suspendAll(); - thread_resumeAll(); - } - thr.join(); -} - -version (DragonFlyBSD) unittest -{ - static void loop() - { - pthread_attr_t attr; - pthread_attr_init(&attr); - auto thr = pthread_self(); - foreach (i; 0 .. 50) - pthread_attr_get_np(thr, &attr); - pthread_attr_destroy(&attr); - } - - auto thr = new Thread(&loop).start(); - foreach (i; 0 .. 50) - { - thread_suspendAll(); - thread_resumeAll(); - } - thr.join(); -} - -unittest -{ - // use >PAGESIZE to avoid stack overflow (e.g. in an syscall) - auto thr = new Thread(function{}, 4096 + 1).start(); - thr.join(); -} - -/** - * Represents the ID of a thread, as returned by $(D Thread.)$(LREF id). - * The exact type varies from platform to platform. - */ -version (Windows) - alias ThreadID = uint; -else -version (Posix) - alias ThreadID = pthread_t; diff --git a/libphobos/libdruntime/core/thread/context.d b/libphobos/libdruntime/core/thread/context.d new file mode 100644 index 00000000000..1b3c0cabbba --- /dev/null +++ b/libphobos/libdruntime/core/thread/context.d @@ -0,0 +1,65 @@ +/** + * The thread module provides support for thread creation and management. + * + * Copyright: Copyright Sean Kelly 2005 - 2012. + * License: Distributed under the + * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). + * (See accompanying file LICENSE) + * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak + * Source: $(DRUNTIMESRC core/thread/package.d) + */ + +module core.thread.context; + +struct StackContext +{ + void* bstack, tstack; + + /// Slot for the EH implementation to keep some state for each stack + /// (will be necessary for exception chaining, etc.). Opaque as far as + /// we are concerned here. + void* ehContext; + StackContext* within; + StackContext* next, prev; +} + +struct Callable +{ + void opAssign(void function() fn) pure nothrow @nogc @safe + { + () @trusted { m_fn = fn; }(); + m_type = Call.FN; + } + void opAssign(void delegate() dg) pure nothrow @nogc @safe + { + () @trusted { m_dg = dg; }(); + m_type = Call.DG; + } + void opCall() + { + switch (m_type) + { + case Call.FN: + m_fn(); + break; + case Call.DG: + m_dg(); + break; + default: + break; + } + } +private: + enum Call + { + NO, + FN, + DG + } + Call m_type = Call.NO; + union + { + void function() m_fn; + void delegate() m_dg; + } +} diff --git a/libphobos/libdruntime/core/thread/fiber.d b/libphobos/libdruntime/core/thread/fiber.d new file mode 100644 index 00000000000..3270f2e7094 --- /dev/null +++ b/libphobos/libdruntime/core/thread/fiber.d @@ -0,0 +1,2097 @@ +/** + * The fiber module provides OS-indepedent lightweight threads aka fibers. + * + * Copyright: Copyright Sean Kelly 2005 - 2012. + * License: Distributed under the + * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). + * (See accompanying file LICENSE) + * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak + * Source: $(DRUNTIMESRC core/thread/fiber.d) + */ + +/* NOTE: This file has been patched from the original DMD distribution to + * work with the GDC compiler. + */ +module core.thread.fiber; + +import core.thread.osthread; +import core.thread.threadgroup; +import core.thread.types; +import core.thread.context; + +/////////////////////////////////////////////////////////////////////////////// +// Fiber Platform Detection +/////////////////////////////////////////////////////////////////////////////// + +version (GNU) +{ + import gcc.builtins; + import gcc.config; + version (GNU_StackGrowsDown) + version = StackGrowsDown; +} +else +{ + // this should be true for most architectures + version = StackGrowsDown; +} + +version (Windows) +{ + import core.stdc.stdlib : malloc, free; + import core.sys.windows.winbase; + import core.sys.windows.winnt; +} + +private +{ + version (D_InlineAsm_X86) + { + version (Windows) + version = AsmX86_Windows; + else version (Posix) + version = AsmX86_Posix; + + version = AlignFiberStackTo16Byte; + } + else version (D_InlineAsm_X86_64) + { + version (Windows) + { + version = AsmX86_64_Windows; + version = AlignFiberStackTo16Byte; + } + else version (Posix) + { + version = AsmX86_64_Posix; + version = AlignFiberStackTo16Byte; + } + } + else version (X86) + { + version = AlignFiberStackTo16Byte; + + version (CET) + { + // fiber_switchContext does not support shadow stack from + // Intel CET. So use ucontext implementation. + } + else + { + version = AsmExternal; + + version (MinGW) + version = GNU_AsmX86_Windows; + else version (Posix) + version = AsmX86_Posix; + } + } + else version (X86_64) + { + version = AlignFiberStackTo16Byte; + + version (CET) + { + // fiber_switchContext does not support shadow stack from + // Intel CET. So use ucontext implementation. + } + else version (D_X32) + { + // let X32 be handled by ucontext swapcontext + } + else + { + version = AsmExternal; + + version (MinGW) + version = GNU_AsmX86_64_Windows; + else version (Posix) + version = AsmX86_64_Posix; + } + } + else version (PPC) + { + version (Posix) + { + version = AsmPPC_Posix; + version = AsmExternal; + } + } + else version (PPC64) + { + version (Posix) + { + version = AlignFiberStackTo16Byte; + } + } + else version (MIPS_O32) + { + version (Posix) + { + version = AsmMIPS_O32_Posix; + version = AsmExternal; + } + } + else version (AArch64) + { + version (Posix) + { + version = AsmAArch64_Posix; + version = AsmExternal; + version = AlignFiberStackTo16Byte; + } + } + else version (ARM) + { + version (Posix) + { + version = AsmARM_Posix; + version = AsmExternal; + } + } + else version (SPARC) + { + // NOTE: The SPARC ABI specifies only doubleword alignment. + version = AlignFiberStackTo16Byte; + } + else version (SPARC64) + { + version = AlignFiberStackTo16Byte; + } + + version (Posix) + { + version (AsmX86_Windows) {} else + version (AsmX86_Posix) {} else + version (AsmX86_64_Windows) {} else + version (AsmX86_64_Posix) {} else + version (AsmExternal) {} else + { + // NOTE: The ucontext implementation requires architecture specific + // data definitions to operate so testing for it must be done + // by checking for the existence of ucontext_t rather than by + // a version identifier. Please note that this is considered + // an obsolescent feature according to the POSIX spec, so a + // custom solution is still preferred. + import core.sys.posix.ucontext; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Fiber Entry Point and Context Switch +/////////////////////////////////////////////////////////////////////////////// + +private +{ + import core.atomic : atomicStore, cas, MemoryOrder; + import core.exception : onOutOfMemoryError; + import core.stdc.stdlib : abort; + + extern (C) void fiber_entryPoint() nothrow + { + Fiber obj = Fiber.getThis(); + assert( obj ); + + assert( Thread.getThis().m_curr is obj.m_ctxt ); + atomicStore!(MemoryOrder.raw)(*cast(shared)&Thread.getThis().m_lock, false); + obj.m_ctxt.tstack = obj.m_ctxt.bstack; + obj.m_state = Fiber.State.EXEC; + + try + { + obj.run(); + } + catch ( Throwable t ) + { + obj.m_unhandled = t; + } + + static if ( __traits( compiles, ucontext_t ) ) + obj.m_ucur = &obj.m_utxt; + + obj.m_state = Fiber.State.TERM; + obj.switchOut(); + } + + // Look above the definition of 'class Fiber' for some information about the implementation of this routine + version (AsmExternal) + { + extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc; + version (AArch64) + extern (C) void fiber_trampoline() nothrow; + } + else + extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc + { + // NOTE: The data pushed and popped in this routine must match the + // default stack created by Fiber.initStack or the initial + // switch into a new context will fail. + + version (AsmX86_Windows) + { + asm pure nothrow @nogc + { + naked; + + // save current stack state + push EBP; + mov EBP, ESP; + push EDI; + push ESI; + push EBX; + push dword ptr FS:[0]; + push dword ptr FS:[4]; + push dword ptr FS:[8]; + push EAX; + + // store oldp again with more accurate address + mov EAX, dword ptr 8[EBP]; + mov [EAX], ESP; + // load newp to begin context switch + mov ESP, dword ptr 12[EBP]; + + // load saved state from new stack + pop EAX; + pop dword ptr FS:[8]; + pop dword ptr FS:[4]; + pop dword ptr FS:[0]; + pop EBX; + pop ESI; + pop EDI; + pop EBP; + + // 'return' to complete switch + pop ECX; + jmp ECX; + } + } + else version (AsmX86_64_Windows) + { + asm pure nothrow @nogc + { + naked; + + // save current stack state + // NOTE: When changing the layout of registers on the stack, + // make sure that the XMM registers are still aligned. + // On function entry, the stack is guaranteed to not + // be aligned to 16 bytes because of the return address + // on the stack. + push RBP; + mov RBP, RSP; + push R12; + push R13; + push R14; + push R15; + push RDI; + push RSI; + // 7 registers = 56 bytes; stack is now aligned to 16 bytes + sub RSP, 160; + movdqa [RSP + 144], XMM6; + movdqa [RSP + 128], XMM7; + movdqa [RSP + 112], XMM8; + movdqa [RSP + 96], XMM9; + movdqa [RSP + 80], XMM10; + movdqa [RSP + 64], XMM11; + movdqa [RSP + 48], XMM12; + movdqa [RSP + 32], XMM13; + movdqa [RSP + 16], XMM14; + movdqa [RSP], XMM15; + push RBX; + xor RAX,RAX; + push qword ptr GS:[RAX]; + push qword ptr GS:8[RAX]; + push qword ptr GS:16[RAX]; + + // store oldp + mov [RCX], RSP; + // load newp to begin context switch + mov RSP, RDX; + + // load saved state from new stack + pop qword ptr GS:16[RAX]; + pop qword ptr GS:8[RAX]; + pop qword ptr GS:[RAX]; + pop RBX; + movdqa XMM15, [RSP]; + movdqa XMM14, [RSP + 16]; + movdqa XMM13, [RSP + 32]; + movdqa XMM12, [RSP + 48]; + movdqa XMM11, [RSP + 64]; + movdqa XMM10, [RSP + 80]; + movdqa XMM9, [RSP + 96]; + movdqa XMM8, [RSP + 112]; + movdqa XMM7, [RSP + 128]; + movdqa XMM6, [RSP + 144]; + add RSP, 160; + pop RSI; + pop RDI; + pop R15; + pop R14; + pop R13; + pop R12; + pop RBP; + + // 'return' to complete switch + pop RCX; + jmp RCX; + } + } + else version (AsmX86_Posix) + { + asm pure nothrow @nogc + { + naked; + + // save current stack state + push EBP; + mov EBP, ESP; + push EDI; + push ESI; + push EBX; + push EAX; + + // store oldp again with more accurate address + mov EAX, dword ptr 8[EBP]; + mov [EAX], ESP; + // load newp to begin context switch + mov ESP, dword ptr 12[EBP]; + + // load saved state from new stack + pop EAX; + pop EBX; + pop ESI; + pop EDI; + pop EBP; + + // 'return' to complete switch + pop ECX; + jmp ECX; + } + } + else version (AsmX86_64_Posix) + { + asm pure nothrow @nogc + { + naked; + + // save current stack state + push RBP; + mov RBP, RSP; + push RBX; + push R12; + push R13; + push R14; + push R15; + + // store oldp + mov [RDI], RSP; + // load newp to begin context switch + mov RSP, RSI; + + // load saved state from new stack + pop R15; + pop R14; + pop R13; + pop R12; + pop RBX; + pop RBP; + + // 'return' to complete switch + pop RCX; + jmp RCX; + } + } + else static if ( __traits( compiles, ucontext_t ) ) + { + Fiber cfib = Fiber.getThis(); + void* ucur = cfib.m_ucur; + + *oldp = &ucur; + swapcontext( **(cast(ucontext_t***) oldp), + *(cast(ucontext_t**) newp) ); + } + else + static assert(0, "Not implemented"); + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// Fiber +/////////////////////////////////////////////////////////////////////////////// +/* + * Documentation of Fiber internals: + * + * The main routines to implement when porting Fibers to new architectures are + * fiber_switchContext and initStack. Some version constants have to be defined + * for the new platform as well, search for "Fiber Platform Detection and Memory Allocation". + * + * Fibers are based on a concept called 'Context'. A Context describes the execution + * state of a Fiber or main thread which is fully described by the stack, some + * registers and a return address at which the Fiber/Thread should continue executing. + * Please note that not only each Fiber has a Context, but each thread also has got a + * Context which describes the threads stack and state. If you call Fiber fib; fib.call + * the first time in a thread you switch from Threads Context into the Fibers Context. + * If you call fib.yield in that Fiber you switch out of the Fibers context and back + * into the Thread Context. (However, this is not always the case. You can call a Fiber + * from within another Fiber, then you switch Contexts between the Fibers and the Thread + * Context is not involved) + * + * In all current implementations the registers and the return address are actually + * saved on a Contexts stack. + * + * The fiber_switchContext routine has got two parameters: + * void** a: This is the _location_ where we have to store the current stack pointer, + * the stack pointer of the currently executing Context (Fiber or Thread). + * void* b: This is the pointer to the stack of the Context which we want to switch into. + * Note that we get the same pointer here as the one we stored into the void** a + * in a previous call to fiber_switchContext. + * + * In the simplest case, a fiber_switchContext rountine looks like this: + * fiber_switchContext: + * push {return Address} + * push {registers} + * copy {stack pointer} into {location pointed to by a} + * //We have now switch to the stack of a different Context! + * copy {b} into {stack pointer} + * pop {registers} + * pop {return Address} + * jump to {return Address} + * + * The GC uses the value returned in parameter a to scan the Fibers stack. It scans from + * the stack base to that value. As the GC dislikes false pointers we can actually optimize + * this a little: By storing registers which can not contain references to memory managed + * by the GC outside of the region marked by the stack base pointer and the stack pointer + * saved in fiber_switchContext we can prevent the GC from scanning them. + * Such registers are usually floating point registers and the return address. In order to + * implement this, we return a modified stack pointer from fiber_switchContext. However, + * we have to remember that when we restore the registers from the stack! + * + * --------------------------- <= Stack Base + * | Frame | <= Many other stack frames + * | Frame | + * |-------------------------| <= The last stack frame. This one is created by fiber_switchContext + * | registers with pointers | + * | | <= Stack pointer. GC stops scanning here + * | return address | + * |floating point registers | + * --------------------------- <= Real Stack End + * + * fiber_switchContext: + * push {registers with pointers} + * copy {stack pointer} into {location pointed to by a} + * push {return Address} + * push {Floating point registers} + * //We have now switch to the stack of a different Context! + * copy {b} into {stack pointer} + * //We now have to adjust the stack pointer to point to 'Real Stack End' so we can pop + * //the FP registers + * //+ or - depends on if your stack grows downwards or upwards + * {stack pointer} = {stack pointer} +- ({FPRegisters}.sizeof + {return address}.sizeof} + * pop {Floating point registers} + * pop {return Address} + * pop {registers with pointers} + * jump to {return Address} + * + * So the question now is which registers need to be saved? This depends on the specific + * architecture ABI of course, but here are some general guidelines: + * - If a register is callee-save (if the callee modifies the register it must saved and + * restored by the callee) it needs to be saved/restored in switchContext + * - If a register is caller-save it needn't be saved/restored. (Calling fiber_switchContext + * is a function call and the compiler therefore already must save these registers before + * calling fiber_switchContext) + * - Argument registers used for passing parameters to functions needn't be saved/restored + * - The return register needn't be saved/restored (fiber_switchContext hasn't got a return type) + * - All scratch registers needn't be saved/restored + * - The link register usually needn't be saved/restored (but sometimes it must be cleared - + * see below for details) + * - The frame pointer register - if it exists - is usually callee-save + * - All current implementations do not save control registers + * + * What happens on the first switch into a Fiber? We never saved a state for this fiber before, + * but the initial state is prepared in the initStack routine. (This routine will also be called + * when a Fiber is being resetted). initStack must produce exactly the same stack layout as the + * part of fiber_switchContext which saves the registers. Pay special attention to set the stack + * pointer correctly if you use the GC optimization mentioned before. the return Address saved in + * initStack must be the address of fiber_entrypoint. + * + * There's now a small but important difference between the first context switch into a fiber and + * further context switches. On the first switch, Fiber.call is used and the returnAddress in + * fiber_switchContext will point to fiber_entrypoint. The important thing here is that this jump + * is a _function call_, we call fiber_entrypoint by jumping before it's function prologue. On later + * calls, the user used yield() in a function, and therefore the return address points into a user + * function, after the yield call. So here the jump in fiber_switchContext is a _function return_, + * not a function call! + * + * The most important result of this is that on entering a function, i.e. fiber_entrypoint, we + * would have to provide a return address / set the link register once fiber_entrypoint + * returns. Now fiber_entrypoint does never return and therefore the actual value of the return + * address / link register is never read/used and therefore doesn't matter. When fiber_switchContext + * performs a _function return_ the value in the link register doesn't matter either. + * However, the link register will still be saved to the stack in fiber_entrypoint and some + * exception handling / stack unwinding code might read it from this stack location and crash. + * The exact solution depends on your architecture, but see the ARM implementation for a way + * to deal with this issue. + * + * The ARM implementation is meant to be used as a kind of documented example implementation. + * Look there for a concrete example. + * + * FIXME: fiber_entrypoint might benefit from a @noreturn attribute, but D doesn't have one. + */ + +/** + * This class provides a cooperative concurrency mechanism integrated with the + * threading and garbage collection functionality. Calling a fiber may be + * considered a blocking operation that returns when the fiber yields (via + * Fiber.yield()). Execution occurs within the context of the calling thread + * so synchronization is not necessary to guarantee memory visibility so long + * as the same thread calls the fiber each time. Please note that there is no + * requirement that a fiber be bound to one specific thread. Rather, fibers + * may be freely passed between threads so long as they are not currently + * executing. Like threads, a new fiber thread may be created using either + * derivation or composition, as in the following example. + * + * Warning: + * Status registers are not saved by the current implementations. This means + * floating point exception status bits (overflow, divide by 0), rounding mode + * and similar stuff is set per-thread, not per Fiber! + * + * Warning: + * On ARM FPU registers are not saved if druntime was compiled as ARM_SoftFloat. + * If such a build is used on a ARM_SoftFP system which actually has got a FPU + * and other libraries are using the FPU registers (other code is compiled + * as ARM_SoftFP) this can cause problems. Druntime must be compiled as + * ARM_SoftFP in this case. + * + * Authors: Based on a design by Mikola Lysenko. + */ +class Fiber +{ + /////////////////////////////////////////////////////////////////////////// + // Initialization + /////////////////////////////////////////////////////////////////////////// + + version (Windows) + // exception handling walks the stack, invoking DbgHelp.dll which + // needs up to 16k of stack space depending on the version of DbgHelp.dll, + // the existence of debug symbols and other conditions. Avoid causing + // stack overflows by defaulting to a larger stack size + enum defaultStackPages = 8; + else + enum defaultStackPages = 4; + + /** + * Initializes a fiber object which is associated with a static + * D function. + * + * Params: + * fn = The fiber function. + * sz = The stack size for this fiber. + * guardPageSize = size of the guard page to trap fiber's stack + * overflows. Beware that using this will increase + * the number of mmaped regions on platforms using mmap + * so an OS-imposed limit may be hit. + * + * In: + * fn must not be null. + */ + this( void function() fn, size_t sz = PAGESIZE * defaultStackPages, + size_t guardPageSize = PAGESIZE ) nothrow + in + { + assert( fn ); + } + do + { + allocStack( sz, guardPageSize ); + reset( fn ); + } + + + /** + * Initializes a fiber object which is associated with a dynamic + * D function. + * + * Params: + * dg = The fiber function. + * sz = The stack size for this fiber. + * guardPageSize = size of the guard page to trap fiber's stack + * overflows. Beware that using this will increase + * the number of mmaped regions on platforms using mmap + * so an OS-imposed limit may be hit. + * + * In: + * dg must not be null. + */ + this( void delegate() dg, size_t sz = PAGESIZE * defaultStackPages, + size_t guardPageSize = PAGESIZE ) nothrow + in + { + assert( dg ); + } + do + { + allocStack( sz, guardPageSize ); + reset( dg ); + } + + + /** + * Cleans up any remaining resources used by this object. + */ + ~this() nothrow @nogc + { + // NOTE: A live reference to this object will exist on its associated + // stack from the first time its call() method has been called + // until its execution completes with State.TERM. Thus, the only + // times this dtor should be called are either if the fiber has + // terminated (and therefore has no active stack) or if the user + // explicitly deletes this object. The latter case is an error + // but is not easily tested for, since State.HOLD may imply that + // the fiber was just created but has never been run. There is + // not a compelling case to create a State.INIT just to offer a + // means of ensuring the user isn't violating this object's + // contract, so for now this requirement will be enforced by + // documentation only. + freeStack(); + } + + + /////////////////////////////////////////////////////////////////////////// + // General Actions + /////////////////////////////////////////////////////////////////////////// + + + /** + * Transfers execution to this fiber object. The calling context will be + * suspended until the fiber calls Fiber.yield() or until it terminates + * via an unhandled exception. + * + * Params: + * rethrow = Rethrow any unhandled exception which may have caused this + * fiber to terminate. + * + * In: + * This fiber must be in state HOLD. + * + * Throws: + * Any exception not handled by the joined thread. + * + * Returns: + * Any exception not handled by this fiber if rethrow = false, null + * otherwise. + */ + // Not marked with any attributes, even though `nothrow @nogc` works + // because it calls arbitrary user code. Most of the implementation + // is already `@nogc nothrow`, but in order for `Fiber.call` to + // propagate the attributes of the user's function, the Fiber + // class needs to be templated. + final Throwable call( Rethrow rethrow = Rethrow.yes ) + { + return rethrow ? call!(Rethrow.yes)() : call!(Rethrow.no); + } + + /// ditto + final Throwable call( Rethrow rethrow )() + { + callImpl(); + if ( m_unhandled ) + { + Throwable t = m_unhandled; + m_unhandled = null; + static if ( rethrow ) + throw t; + else + return t; + } + return null; + } + + private void callImpl() nothrow @nogc + in + { + assert( m_state == State.HOLD ); + } + do + { + Fiber cur = getThis(); + + static if ( __traits( compiles, ucontext_t ) ) + m_ucur = cur ? &cur.m_utxt : &Fiber.sm_utxt; + + setThis( this ); + this.switchIn(); + setThis( cur ); + + static if ( __traits( compiles, ucontext_t ) ) + m_ucur = null; + + // NOTE: If the fiber has terminated then the stack pointers must be + // reset. This ensures that the stack for this fiber is not + // scanned if the fiber has terminated. This is necessary to + // prevent any references lingering on the stack from delaying + // the collection of otherwise dead objects. The most notable + // being the current object, which is referenced at the top of + // fiber_entryPoint. + if ( m_state == State.TERM ) + { + m_ctxt.tstack = m_ctxt.bstack; + } + } + + /// Flag to control rethrow behavior of $(D $(LREF call)) + enum Rethrow : bool { no, yes } + + /** + * Resets this fiber so that it may be re-used, optionally with a + * new function/delegate. This routine should only be called for + * fibers that have terminated, as doing otherwise could result in + * scope-dependent functionality that is not executed. + * Stack-based classes, for example, may not be cleaned up + * properly if a fiber is reset before it has terminated. + * + * In: + * This fiber must be in state TERM or HOLD. + */ + final void reset() nothrow @nogc + in + { + assert( m_state == State.TERM || m_state == State.HOLD ); + } + do + { + m_ctxt.tstack = m_ctxt.bstack; + m_state = State.HOLD; + initStack(); + m_unhandled = null; + } + + /// ditto + final void reset( void function() fn ) nothrow @nogc + { + reset(); + m_call = fn; + } + + /// ditto + final void reset( void delegate() dg ) nothrow @nogc + { + reset(); + m_call = dg; + } + + /////////////////////////////////////////////////////////////////////////// + // General Properties + /////////////////////////////////////////////////////////////////////////// + + + /// A fiber may occupy one of three states: HOLD, EXEC, and TERM. + enum State + { + /** The HOLD state applies to any fiber that is suspended and ready to + be called. */ + HOLD, + /** The EXEC state will be set for any fiber that is currently + executing. */ + EXEC, + /** The TERM state is set when a fiber terminates. Once a fiber + terminates, it must be reset before it may be called again. */ + TERM + } + + + /** + * Gets the current state of this fiber. + * + * Returns: + * The state of this fiber as an enumerated value. + */ + final @property State state() const @safe pure nothrow @nogc + { + return m_state; + } + + + /////////////////////////////////////////////////////////////////////////// + // Actions on Calling Fiber + /////////////////////////////////////////////////////////////////////////// + + + /** + * Forces a context switch to occur away from the calling fiber. + */ + static void yield() nothrow @nogc + { + Fiber cur = getThis(); + assert( cur, "Fiber.yield() called with no active fiber" ); + assert( cur.m_state == State.EXEC ); + + static if ( __traits( compiles, ucontext_t ) ) + cur.m_ucur = &cur.m_utxt; + + cur.m_state = State.HOLD; + cur.switchOut(); + cur.m_state = State.EXEC; + } + + + /** + * Forces a context switch to occur away from the calling fiber and then + * throws obj in the calling fiber. + * + * Params: + * t = The object to throw. + * + * In: + * t must not be null. + */ + static void yieldAndThrow( Throwable t ) nothrow @nogc + in + { + assert( t ); + } + do + { + Fiber cur = getThis(); + assert( cur, "Fiber.yield() called with no active fiber" ); + assert( cur.m_state == State.EXEC ); + + static if ( __traits( compiles, ucontext_t ) ) + cur.m_ucur = &cur.m_utxt; + + cur.m_unhandled = t; + cur.m_state = State.HOLD; + cur.switchOut(); + cur.m_state = State.EXEC; + } + + + /////////////////////////////////////////////////////////////////////////// + // Fiber Accessors + /////////////////////////////////////////////////////////////////////////// + + + /** + * Provides a reference to the calling fiber or null if no fiber is + * currently active. + * + * Returns: + * The fiber object representing the calling fiber or null if no fiber + * is currently active within this thread. The result of deleting this object is undefined. + */ + static Fiber getThis() @safe nothrow @nogc + { + return sm_this; + } + + + /////////////////////////////////////////////////////////////////////////// + // Static Initialization + /////////////////////////////////////////////////////////////////////////// + + + version (Posix) + { + static this() + { + static if ( __traits( compiles, ucontext_t ) ) + { + int status = getcontext( &sm_utxt ); + assert( status == 0 ); + } + } + } + +private: + + // + // Fiber entry point. Invokes the function or delegate passed on + // construction (if any). + // + final void run() + { + m_call(); + } + + // + // Standard fiber data + // + Callable m_call; + bool m_isRunning; + Throwable m_unhandled; + State m_state; + + +private: + /////////////////////////////////////////////////////////////////////////// + // Stack Management + /////////////////////////////////////////////////////////////////////////// + + + // + // Allocate a new stack for this fiber. + // + final void allocStack( size_t sz, size_t guardPageSize ) nothrow + in + { + assert( !m_pmem && !m_ctxt ); + } + do + { + // adjust alloc size to a multiple of PAGESIZE + sz += PAGESIZE - 1; + sz -= sz % PAGESIZE; + + // NOTE: This instance of Thread.Context is dynamic so Fiber objects + // can be collected by the GC so long as no user level references + // to the object exist. If m_ctxt were not dynamic then its + // presence in the global context list would be enough to keep + // this object alive indefinitely. An alternative to allocating + // room for this struct explicitly would be to mash it into the + // base of the stack being allocated below. However, doing so + // requires too much special logic to be worthwhile. + m_ctxt = new StackContext; + + version (Windows) + { + // reserve memory for stack + m_pmem = VirtualAlloc( null, + sz + guardPageSize, + MEM_RESERVE, + PAGE_NOACCESS ); + if ( !m_pmem ) + onOutOfMemoryError(); + + version (StackGrowsDown) + { + void* stack = m_pmem + guardPageSize; + void* guard = m_pmem; + void* pbase = stack + sz; + } + else + { + void* stack = m_pmem; + void* guard = m_pmem + sz; + void* pbase = stack; + } + + // allocate reserved stack segment + stack = VirtualAlloc( stack, + sz, + MEM_COMMIT, + PAGE_READWRITE ); + if ( !stack ) + onOutOfMemoryError(); + + if (guardPageSize) + { + // allocate reserved guard page + guard = VirtualAlloc( guard, + guardPageSize, + MEM_COMMIT, + PAGE_READWRITE | PAGE_GUARD ); + if ( !guard ) + onOutOfMemoryError(); + } + + m_ctxt.bstack = pbase; + m_ctxt.tstack = pbase; + m_size = sz; + } + else + { + version (Posix) import core.sys.posix.sys.mman; // mmap, MAP_ANON + + static if ( __traits( compiles, ucontext_t ) ) + { + // Stack size must be at least the minimum allowable by the OS. + if (sz < MINSIGSTKSZ) + sz = MINSIGSTKSZ; + } + + static if ( __traits( compiles, mmap ) ) + { + // Allocate more for the memory guard + sz += guardPageSize; + + m_pmem = mmap( null, + sz, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, + -1, + 0 ); + if ( m_pmem == MAP_FAILED ) + m_pmem = null; + } + else static if ( __traits( compiles, valloc ) ) + { + m_pmem = valloc( sz ); + } + else static if ( __traits( compiles, malloc ) ) + { + m_pmem = malloc( sz ); + } + else + { + m_pmem = null; + } + + if ( !m_pmem ) + onOutOfMemoryError(); + + version (StackGrowsDown) + { + m_ctxt.bstack = m_pmem + sz; + m_ctxt.tstack = m_pmem + sz; + void* guard = m_pmem; + } + else + { + m_ctxt.bstack = m_pmem; + m_ctxt.tstack = m_pmem; + void* guard = m_pmem + sz - guardPageSize; + } + m_size = sz; + + static if ( __traits( compiles, mmap ) ) + { + if (guardPageSize) + { + // protect end of stack + if ( mprotect(guard, guardPageSize, PROT_NONE) == -1 ) + abort(); + } + } + else + { + // Supported only for mmap allocated memory - results are + // undefined if applied to memory not obtained by mmap + } + } + + Thread.add( m_ctxt ); + } + + + // + // Free this fiber's stack. + // + final void freeStack() nothrow @nogc + in + { + assert( m_pmem && m_ctxt ); + } + do + { + // NOTE: m_ctxt is guaranteed to be alive because it is held in the + // global context list. + Thread.slock.lock_nothrow(); + scope(exit) Thread.slock.unlock_nothrow(); + Thread.remove( m_ctxt ); + + version (Windows) + { + VirtualFree( m_pmem, 0, MEM_RELEASE ); + } + else + { + import core.sys.posix.sys.mman; // munmap + + static if ( __traits( compiles, mmap ) ) + { + munmap( m_pmem, m_size ); + } + else static if ( __traits( compiles, valloc ) ) + { + free( m_pmem ); + } + else static if ( __traits( compiles, malloc ) ) + { + free( m_pmem ); + } + } + m_pmem = null; + m_ctxt = null; + } + + + // + // Initialize the allocated stack. + // Look above the definition of 'class Fiber' for some information about the implementation of this routine + // + final void initStack() nothrow @nogc + in + { + assert( m_ctxt.tstack && m_ctxt.tstack == m_ctxt.bstack ); + assert( cast(size_t) m_ctxt.bstack % (void*).sizeof == 0 ); + } + do + { + void* pstack = m_ctxt.tstack; + scope( exit ) m_ctxt.tstack = pstack; + + void push( size_t val ) nothrow + { + version (StackGrowsDown) + { + pstack -= size_t.sizeof; + *(cast(size_t*) pstack) = val; + } + else + { + pstack += size_t.sizeof; + *(cast(size_t*) pstack) = val; + } + } + + // NOTE: On OS X the stack must be 16-byte aligned according + // to the IA-32 call spec. For x86_64 the stack also needs to + // be aligned to 16-byte according to SysV AMD64 ABI. + version (AlignFiberStackTo16Byte) + { + version (StackGrowsDown) + { + pstack = cast(void*)(cast(size_t)(pstack) - (cast(size_t)(pstack) & 0x0F)); + } + else + { + pstack = cast(void*)(cast(size_t)(pstack) + (cast(size_t)(pstack) & 0x0F)); + } + } + + version (AsmX86_Windows) + { + version (StackGrowsDown) {} else static assert( false ); + + // On Windows Server 2008 and 2008 R2, an exploit mitigation + // technique known as SEHOP is activated by default. To avoid + // hijacking of the exception handler chain, the presence of a + // Windows-internal handler (ntdll.dll!FinalExceptionHandler) at + // its end is tested by RaiseException. If it is not present, all + // handlers are disregarded, and the program is thus aborted + // (see http://blogs.technet.com/b/srd/archive/2009/02/02/ + // preventing-the-exploitation-of-seh-overwrites-with-sehop.aspx). + // For new threads, this handler is installed by Windows immediately + // after creation. To make exception handling work in fibers, we + // have to insert it for our new stacks manually as well. + // + // To do this, we first determine the handler by traversing the SEH + // chain of the current thread until its end, and then construct a + // registration block for the last handler on the newly created + // thread. We then continue to push all the initial register values + // for the first context switch as for the other implementations. + // + // Note that this handler is never actually invoked, as we install + // our own one on top of it in the fiber entry point function. + // Thus, it should not have any effects on OSes not implementing + // exception chain verification. + + alias fp_t = void function(); // Actual signature not relevant. + static struct EXCEPTION_REGISTRATION + { + EXCEPTION_REGISTRATION* next; // sehChainEnd if last one. + fp_t handler; + } + enum sehChainEnd = cast(EXCEPTION_REGISTRATION*) 0xFFFFFFFF; + + __gshared static fp_t finalHandler = null; + if ( finalHandler is null ) + { + static EXCEPTION_REGISTRATION* fs0() nothrow + { + asm pure nothrow @nogc + { + naked; + mov EAX, FS:[0]; + ret; + } + } + auto reg = fs0(); + while ( reg.next != sehChainEnd ) reg = reg.next; + + // Benign races are okay here, just to avoid re-lookup on every + // fiber creation. + finalHandler = reg.handler; + } + + // When linking with /safeseh (supported by LDC, but not DMD) + // the exception chain must not extend to the very top + // of the stack, otherwise the exception chain is also considered + // invalid. Reserving additional 4 bytes at the top of the stack will + // keep the EXCEPTION_REGISTRATION below that limit + size_t reserve = EXCEPTION_REGISTRATION.sizeof + 4; + pstack -= reserve; + *(cast(EXCEPTION_REGISTRATION*)pstack) = + EXCEPTION_REGISTRATION( sehChainEnd, finalHandler ); + auto pChainEnd = pstack; + + push( cast(size_t) &fiber_entryPoint ); // EIP + push( cast(size_t) m_ctxt.bstack - reserve ); // EBP + push( 0x00000000 ); // EDI + push( 0x00000000 ); // ESI + push( 0x00000000 ); // EBX + push( cast(size_t) pChainEnd ); // FS:[0] + push( cast(size_t) m_ctxt.bstack ); // FS:[4] + push( cast(size_t) m_ctxt.bstack - m_size ); // FS:[8] + push( 0x00000000 ); // EAX + } + else version (AsmX86_64_Windows) + { + // Using this trampoline instead of the raw fiber_entryPoint + // ensures that during context switches, source and destination + // stacks have the same alignment. Otherwise, the stack would need + // to be shifted by 8 bytes for the first call, as fiber_entryPoint + // is an actual function expecting a stack which is not aligned + // to 16 bytes. + static void trampoline() + { + asm pure nothrow @nogc + { + naked; + sub RSP, 32; // Shadow space (Win64 calling convention) + call fiber_entryPoint; + xor RCX, RCX; // This should never be reached, as + jmp RCX; // fiber_entryPoint must never return. + } + } + + push( cast(size_t) &trampoline ); // RIP + push( 0x00000000_00000000 ); // RBP + push( 0x00000000_00000000 ); // R12 + push( 0x00000000_00000000 ); // R13 + push( 0x00000000_00000000 ); // R14 + push( 0x00000000_00000000 ); // R15 + push( 0x00000000_00000000 ); // RDI + push( 0x00000000_00000000 ); // RSI + push( 0x00000000_00000000 ); // XMM6 (high) + push( 0x00000000_00000000 ); // XMM6 (low) + push( 0x00000000_00000000 ); // XMM7 (high) + push( 0x00000000_00000000 ); // XMM7 (low) + push( 0x00000000_00000000 ); // XMM8 (high) + push( 0x00000000_00000000 ); // XMM8 (low) + push( 0x00000000_00000000 ); // XMM9 (high) + push( 0x00000000_00000000 ); // XMM9 (low) + push( 0x00000000_00000000 ); // XMM10 (high) + push( 0x00000000_00000000 ); // XMM10 (low) + push( 0x00000000_00000000 ); // XMM11 (high) + push( 0x00000000_00000000 ); // XMM11 (low) + push( 0x00000000_00000000 ); // XMM12 (high) + push( 0x00000000_00000000 ); // XMM12 (low) + push( 0x00000000_00000000 ); // XMM13 (high) + push( 0x00000000_00000000 ); // XMM13 (low) + push( 0x00000000_00000000 ); // XMM14 (high) + push( 0x00000000_00000000 ); // XMM14 (low) + push( 0x00000000_00000000 ); // XMM15 (high) + push( 0x00000000_00000000 ); // XMM15 (low) + push( 0x00000000_00000000 ); // RBX + push( 0xFFFFFFFF_FFFFFFFF ); // GS:[0] + version (StackGrowsDown) + { + push( cast(size_t) m_ctxt.bstack ); // GS:[8] + push( cast(size_t) m_ctxt.bstack - m_size ); // GS:[16] + } + else + { + push( cast(size_t) m_ctxt.bstack ); // GS:[8] + push( cast(size_t) m_ctxt.bstack + m_size ); // GS:[16] + } + } + else version (AsmX86_Posix) + { + push( 0x00000000 ); // Return address of fiber_entryPoint call + push( cast(size_t) &fiber_entryPoint ); // EIP + push( cast(size_t) m_ctxt.bstack ); // EBP + push( 0x00000000 ); // EDI + push( 0x00000000 ); // ESI + push( 0x00000000 ); // EBX + push( 0x00000000 ); // EAX + } + else version (AsmX86_64_Posix) + { + push( 0x00000000_00000000 ); // Return address of fiber_entryPoint call + push( cast(size_t) &fiber_entryPoint ); // RIP + push( cast(size_t) m_ctxt.bstack ); // RBP + push( 0x00000000_00000000 ); // RBX + push( 0x00000000_00000000 ); // R12 + push( 0x00000000_00000000 ); // R13 + push( 0x00000000_00000000 ); // R14 + push( 0x00000000_00000000 ); // R15 + } + else version (AsmPPC_Posix) + { + version (StackGrowsDown) + { + pstack -= int.sizeof * 5; + } + else + { + pstack += int.sizeof * 5; + } + + push( cast(size_t) &fiber_entryPoint ); // link register + push( 0x00000000 ); // control register + push( 0x00000000 ); // old stack pointer + + // GPR values + version (StackGrowsDown) + { + pstack -= int.sizeof * 20; + } + else + { + pstack += int.sizeof * 20; + } + + assert( (cast(size_t) pstack & 0x0f) == 0 ); + } + else version (AsmMIPS_O32_Posix) + { + version (StackGrowsDown) {} + else static assert(0); + + /* We keep the FP registers and the return address below + * the stack pointer, so they don't get scanned by the + * GC. The last frame before swapping the stack pointer is + * organized like the following. + * + * |-----------|<= frame pointer + * | $gp | + * | $s0-8 | + * |-----------|<= stack pointer + * | $ra | + * | align(8) | + * | $f20-30 | + * |-----------| + * + */ + enum SZ_GP = 10 * size_t.sizeof; // $gp + $s0-8 + enum SZ_RA = size_t.sizeof; // $ra + version (MIPS_HardFloat) + { + enum SZ_FP = 6 * 8; // $f20-30 + enum ALIGN = -(SZ_FP + SZ_RA) & (8 - 1); + } + else + { + enum SZ_FP = 0; + enum ALIGN = 0; + } + + enum BELOW = SZ_FP + ALIGN + SZ_RA; + enum ABOVE = SZ_GP; + enum SZ = BELOW + ABOVE; + + (cast(ubyte*)pstack - SZ)[0 .. SZ] = 0; + pstack -= ABOVE; + *cast(size_t*)(pstack - SZ_RA) = cast(size_t)&fiber_entryPoint; + } + else version (AsmAArch64_Posix) + { + // Like others, FP registers and return address (lr) are kept + // below the saved stack top (tstack) to hide from GC scanning. + // fiber_switchContext expects newp sp to look like this: + // 19: x19 + // ... + // 9: x29 (fp) <-- newp tstack + // 8: x30 (lr) [&fiber_entryPoint] + // 7: d8 + // ... + // 0: d15 + + version (StackGrowsDown) {} + else + static assert(false, "Only full descending stacks supported on AArch64"); + + // Only need to set return address (lr). Everything else is fine + // zero initialized. + pstack -= size_t.sizeof * 11; // skip past x19-x29 + push(cast(size_t) &fiber_trampoline); // see threadasm.S for docs + pstack += size_t.sizeof; // adjust sp (newp) above lr + } + else version (AsmARM_Posix) + { + /* We keep the FP registers and the return address below + * the stack pointer, so they don't get scanned by the + * GC. The last frame before swapping the stack pointer is + * organized like the following. + * + * | |-----------|<= 'frame starts here' + * | | fp | (the actual frame pointer, r11 isn't + * | | r10-r4 | updated and still points to the previous frame) + * | |-----------|<= stack pointer + * | | lr | + * | | 4byte pad | + * | | d15-d8 |(if FP supported) + * | |-----------| + * Y + * stack grows down: The pointer value here is smaller than some lines above + */ + // frame pointer can be zero, r10-r4 also zero initialized + version (StackGrowsDown) + pstack -= int.sizeof * 8; + else + static assert(false, "Only full descending stacks supported on ARM"); + + // link register + push( cast(size_t) &fiber_entryPoint ); + /* + * We do not push padding and d15-d8 as those are zero initialized anyway + * Position the stack pointer above the lr register + */ + pstack += int.sizeof * 1; + } + else version (GNU_AsmX86_Windows) + { + version (StackGrowsDown) {} else static assert( false ); + + // Currently, MinGW doesn't utilize SEH exceptions. + // See DMD AsmX86_Windows If this code ever becomes fails and SEH is used. + + push( 0x00000000 ); // Return address of fiber_entryPoint call + push( cast(size_t) &fiber_entryPoint ); // EIP + push( 0x00000000 ); // EBP + push( 0x00000000 ); // EDI + push( 0x00000000 ); // ESI + push( 0x00000000 ); // EBX + push( 0xFFFFFFFF ); // FS:[0] - Current SEH frame + push( cast(size_t) m_ctxt.bstack ); // FS:[4] - Top of stack + push( cast(size_t) m_ctxt.bstack - m_size ); // FS:[8] - Bottom of stack + push( 0x00000000 ); // EAX + } + else version (GNU_AsmX86_64_Windows) + { + push( 0x00000000_00000000 ); // Return address of fiber_entryPoint call + push( cast(size_t) &fiber_entryPoint ); // RIP + push( 0x00000000_00000000 ); // RBP + push( 0x00000000_00000000 ); // RBX + push( 0x00000000_00000000 ); // R12 + push( 0x00000000_00000000 ); // R13 + push( 0x00000000_00000000 ); // R14 + push( 0x00000000_00000000 ); // R15 + push( 0xFFFFFFFF_FFFFFFFF ); // GS:[0] - Current SEH frame + version (StackGrowsDown) + { + push( cast(size_t) m_ctxt.bstack ); // GS:[8] - Top of stack + push( cast(size_t) m_ctxt.bstack - m_size ); // GS:[16] - Bottom of stack + } + else + { + push( cast(size_t) m_ctxt.bstack ); // GS:[8] - Top of stack + push( cast(size_t) m_ctxt.bstack + m_size ); // GS:[16] - Bottom of stack + } + } + else static if ( __traits( compiles, ucontext_t ) ) + { + getcontext( &m_utxt ); + m_utxt.uc_stack.ss_sp = m_pmem; + m_utxt.uc_stack.ss_size = m_size; + makecontext( &m_utxt, &fiber_entryPoint, 0 ); + // NOTE: If ucontext is being used then the top of the stack will + // be a pointer to the ucontext_t struct for that fiber. + push( cast(size_t) &m_utxt ); + } + else + static assert(0, "Not implemented"); + } + + + StackContext* m_ctxt; + size_t m_size; + void* m_pmem; + + static if ( __traits( compiles, ucontext_t ) ) + { + // NOTE: The static ucontext instance is used to represent the context + // of the executing thread. + static ucontext_t sm_utxt = void; + ucontext_t m_utxt = void; + ucontext_t* m_ucur = null; + } + else static if (GNU_Enable_CET) + { + // When libphobos was built with --enable-cet, these fields need to + // always be present in the Fiber class layout. + import core.sys.posix.ucontext; + static ucontext_t sm_utxt = void; + ucontext_t m_utxt = void; + ucontext_t* m_ucur = null; + } + + +private: + /////////////////////////////////////////////////////////////////////////// + // Storage of Active Fiber + /////////////////////////////////////////////////////////////////////////// + + + // + // Sets a thread-local reference to the current fiber object. + // + static void setThis( Fiber f ) nothrow @nogc + { + sm_this = f; + } + + static Fiber sm_this; + + +private: + /////////////////////////////////////////////////////////////////////////// + // Context Switching + /////////////////////////////////////////////////////////////////////////// + + + // + // Switches into the stack held by this fiber. + // + final void switchIn() nothrow @nogc + { + Thread tobj = Thread.getThis(); + void** oldp = &tobj.m_curr.tstack; + void* newp = m_ctxt.tstack; + + // NOTE: The order of operations here is very important. The current + // stack top must be stored before m_lock is set, and pushContext + // must not be called until after m_lock is set. This process + // is intended to prevent a race condition with the suspend + // mechanism used for garbage collection. If it is not followed, + // a badly timed collection could cause the GC to scan from the + // bottom of one stack to the top of another, or to miss scanning + // a stack that still contains valid data. The old stack pointer + // oldp will be set again before the context switch to guarantee + // that it points to exactly the correct stack location so the + // successive pop operations will succeed. + *oldp = getStackTop(); + atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, true); + tobj.pushContext( m_ctxt ); + + fiber_switchContext( oldp, newp ); + + // NOTE: As above, these operations must be performed in a strict order + // to prevent Bad Things from happening. + tobj.popContext(); + atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, false); + tobj.m_curr.tstack = tobj.m_curr.bstack; + } + + + // + // Switches out of the current stack and into the enclosing stack. + // + final void switchOut() nothrow @nogc + { + Thread tobj = Thread.getThis(); + void** oldp = &m_ctxt.tstack; + void* newp = tobj.m_curr.within.tstack; + + // NOTE: The order of operations here is very important. The current + // stack top must be stored before m_lock is set, and pushContext + // must not be called until after m_lock is set. This process + // is intended to prevent a race condition with the suspend + // mechanism used for garbage collection. If it is not followed, + // a badly timed collection could cause the GC to scan from the + // bottom of one stack to the top of another, or to miss scanning + // a stack that still contains valid data. The old stack pointer + // oldp will be set again before the context switch to guarantee + // that it points to exactly the correct stack location so the + // successive pop operations will succeed. + *oldp = getStackTop(); + atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, true); + + fiber_switchContext( oldp, newp ); + + // NOTE: As above, these operations must be performed in a strict order + // to prevent Bad Things from happening. + // NOTE: If use of this fiber is multiplexed across threads, the thread + // executing here may be different from the one above, so get the + // current thread handle before unlocking, etc. + tobj = Thread.getThis(); + atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, false); + tobj.m_curr.tstack = tobj.m_curr.bstack; + } +} + +/// +unittest { + int counter; + + class DerivedFiber : Fiber + { + this() + { + super( &run ); + } + + private : + void run() + { + counter += 2; + } + } + + void fiberFunc() + { + counter += 4; + Fiber.yield(); + counter += 8; + } + + // create instances of each type + Fiber derived = new DerivedFiber(); + Fiber composed = new Fiber( &fiberFunc ); + + assert( counter == 0 ); + + derived.call(); + assert( counter == 2, "Derived fiber increment." ); + + composed.call(); + assert( counter == 6, "First composed fiber increment." ); + + counter += 16; + assert( counter == 22, "Calling context increment." ); + + composed.call(); + assert( counter == 30, "Second composed fiber increment." ); + + // since each fiber has run to completion, each should have state TERM + assert( derived.state == Fiber.State.TERM ); + assert( composed.state == Fiber.State.TERM ); +} + +version (unittest) +{ + class TestFiber : Fiber + { + this() + { + super(&run); + } + + void run() + { + foreach (i; 0 .. 1000) + { + sum += i; + Fiber.yield(); + } + } + + enum expSum = 1000 * 999 / 2; + size_t sum; + } + + void runTen() + { + TestFiber[10] fibs; + foreach (ref fib; fibs) + fib = new TestFiber(); + + bool cont; + do { + cont = false; + foreach (fib; fibs) { + if (fib.state == Fiber.State.HOLD) + { + fib.call(); + cont |= fib.state != Fiber.State.TERM; + } + } + } while (cont); + + foreach (fib; fibs) + { + assert(fib.sum == TestFiber.expSum); + } + } +} + + +// Single thread running separate fibers +unittest +{ + runTen(); +} + + +// Multiple threads running separate fibers +unittest +{ + auto group = new ThreadGroup(); + foreach (_; 0 .. 4) + { + group.create(&runTen); + } + group.joinAll(); +} + + +// Multiple threads running shared fibers +version (PPC) version = UnsafeFiberMigration; +version (PPC64) version = UnsafeFiberMigration; + +version (UnsafeFiberMigration) +{ + // XBUG: core.thread fibers are supposed to be safe to migrate across + // threads, however, there is a problem: GCC always assumes that the + // address of thread-local variables don't change while on a given stack. + // In consequence, migrating fibers between threads currently is an unsafe + // thing to do, and will break on some targets (possibly PR26461). +} +else +{ + version = FiberMigrationUnittest; +} + +version (FiberMigrationUnittest) +unittest +{ + shared bool[10] locks; + TestFiber[10] fibs; + + void runShared() + { + bool cont; + do { + cont = false; + foreach (idx; 0 .. 10) + { + if (cas(&locks[idx], false, true)) + { + if (fibs[idx].state == Fiber.State.HOLD) + { + fibs[idx].call(); + cont |= fibs[idx].state != Fiber.State.TERM; + } + locks[idx] = false; + } + else + { + cont = true; + } + } + } while (cont); + } + + foreach (ref fib; fibs) + { + fib = new TestFiber(); + } + + auto group = new ThreadGroup(); + foreach (_; 0 .. 4) + { + group.create(&runShared); + } + group.joinAll(); + + foreach (fib; fibs) + { + assert(fib.sum == TestFiber.expSum); + } +} + + +// Test exception handling inside fibers. +unittest +{ + enum MSG = "Test message."; + string caughtMsg; + (new Fiber({ + try + { + throw new Exception(MSG); + } + catch (Exception e) + { + caughtMsg = e.msg; + } + })).call(); + assert(caughtMsg == MSG); +} + + +unittest +{ + int x = 0; + + (new Fiber({ + x++; + })).call(); + assert( x == 1 ); +} + +nothrow unittest +{ + new Fiber({}).call!(Fiber.Rethrow.no)(); +} + +unittest +{ + new Fiber({}).call(Fiber.Rethrow.yes); + new Fiber({}).call(Fiber.Rethrow.no); +} + +unittest +{ + enum MSG = "Test message."; + + try + { + (new Fiber({ + throw new Exception( MSG ); + })).call(); + assert( false, "Expected rethrown exception." ); + } + catch ( Throwable t ) + { + assert( t.msg == MSG ); + } +} + +// Test exception chaining when switching contexts in finally blocks. +unittest +{ + static void throwAndYield(string msg) { + try { + throw new Exception(msg); + } finally { + Fiber.yield(); + } + } + + static void fiber(string name) { + try { + try { + throwAndYield(name ~ ".1"); + } finally { + throwAndYield(name ~ ".2"); + } + } catch (Exception e) { + assert(e.msg == name ~ ".1"); + assert(e.next); + assert(e.next.msg == name ~ ".2"); + assert(!e.next.next); + } + } + + auto first = new Fiber(() => fiber("first")); + auto second = new Fiber(() => fiber("second")); + first.call(); + second.call(); + first.call(); + second.call(); + first.call(); + second.call(); + assert(first.state == Fiber.State.TERM); + assert(second.state == Fiber.State.TERM); +} + +// Test Fiber resetting +unittest +{ + static string method; + + static void foo() + { + method = "foo"; + } + + void bar() + { + method = "bar"; + } + + static void expect(Fiber fib, string s) + { + assert(fib.state == Fiber.State.HOLD); + fib.call(); + assert(fib.state == Fiber.State.TERM); + assert(method == s); method = null; + } + auto fib = new Fiber(&foo); + expect(fib, "foo"); + + fib.reset(); + expect(fib, "foo"); + + fib.reset(&foo); + expect(fib, "foo"); + + fib.reset(&bar); + expect(fib, "bar"); + + fib.reset(function void(){method = "function";}); + expect(fib, "function"); + + fib.reset(delegate void(){method = "delegate";}); + expect(fib, "delegate"); +} + +// Test unsafe reset in hold state +unittest +{ + auto fib = new Fiber(function {ubyte[2048] buf = void; Fiber.yield();}, 4096); + foreach (_; 0 .. 10) + { + fib.call(); + assert(fib.state == Fiber.State.HOLD); + fib.reset(); + } +} + +// stress testing GC stack scanning +unittest +{ + import core.memory; + import core.time : dur; + + static void unreferencedThreadObject() + { + static void sleep() { Thread.sleep(dur!"msecs"(100)); } + auto thread = new Thread(&sleep).start(); + } + unreferencedThreadObject(); + GC.collect(); + + static class Foo + { + this(int value) + { + _value = value; + } + + int bar() + { + return _value; + } + + int _value; + } + + static void collect() + { + auto foo = new Foo(2); + assert(foo.bar() == 2); + GC.collect(); + Fiber.yield(); + GC.collect(); + assert(foo.bar() == 2); + } + + auto fiber = new Fiber(&collect); + + fiber.call(); + GC.collect(); + fiber.call(); + + // thread reference + auto foo = new Foo(2); + + void collect2() + { + assert(foo.bar() == 2); + GC.collect(); + Fiber.yield(); + GC.collect(); + assert(foo.bar() == 2); + } + + fiber = new Fiber(&collect2); + + fiber.call(); + GC.collect(); + fiber.call(); + + static void recurse(size_t cnt) + { + --cnt; + Fiber.yield(); + if (cnt) + { + auto fib = new Fiber(() { recurse(cnt); }); + fib.call(); + GC.collect(); + fib.call(); + } + } + fiber = new Fiber(() { recurse(20); }); + fiber.call(); +} + + +version (AsmX86_64_Windows) +{ + // Test Windows x64 calling convention + unittest + { + void testNonvolatileRegister(alias REG)() + { + auto zeroRegister = new Fiber(() { + mixin("asm pure nothrow @nogc { naked; xor "~REG~", "~REG~"; ret; }"); + }); + long after; + + mixin("asm pure nothrow @nogc { mov "~REG~", 0xFFFFFFFFFFFFFFFF; }"); + zeroRegister.call(); + mixin("asm pure nothrow @nogc { mov after, "~REG~"; }"); + + assert(after == -1); + } + + void testNonvolatileRegisterSSE(alias REG)() + { + auto zeroRegister = new Fiber(() { + mixin("asm pure nothrow @nogc { naked; xorpd "~REG~", "~REG~"; ret; }"); + }); + long[2] before = [0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF], after; + + mixin("asm pure nothrow @nogc { movdqu "~REG~", before; }"); + zeroRegister.call(); + mixin("asm pure nothrow @nogc { movdqu after, "~REG~"; }"); + + assert(before == after); + } + + testNonvolatileRegister!("R12")(); + testNonvolatileRegister!("R13")(); + testNonvolatileRegister!("R14")(); + testNonvolatileRegister!("R15")(); + testNonvolatileRegister!("RDI")(); + testNonvolatileRegister!("RSI")(); + testNonvolatileRegister!("RBX")(); + + testNonvolatileRegisterSSE!("XMM6")(); + testNonvolatileRegisterSSE!("XMM7")(); + testNonvolatileRegisterSSE!("XMM8")(); + testNonvolatileRegisterSSE!("XMM9")(); + testNonvolatileRegisterSSE!("XMM10")(); + testNonvolatileRegisterSSE!("XMM11")(); + testNonvolatileRegisterSSE!("XMM12")(); + testNonvolatileRegisterSSE!("XMM13")(); + testNonvolatileRegisterSSE!("XMM14")(); + testNonvolatileRegisterSSE!("XMM15")(); + } +} + + +version (D_InlineAsm_X86_64) +{ + unittest + { + void testStackAlignment() + { + void* pRSP; + asm pure nothrow @nogc + { + mov pRSP, RSP; + } + assert((cast(size_t)pRSP & 0xF) == 0); + } + + auto fib = new Fiber(&testStackAlignment); + fib.call(); + } +} diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d new file mode 100644 index 00000000000..d81e0aa0607 --- /dev/null +++ b/libphobos/libdruntime/core/thread/osthread.d @@ -0,0 +1,2811 @@ +/** + * The osthread module provides low-level, OS-dependent code + * for thread creation and management. + * + * Copyright: Copyright Sean Kelly 2005 - 2012. + * License: Distributed under the + * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). + * (See accompanying file LICENSE) + * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak + * Source: $(DRUNTIMESRC core/thread/osthread.d) + */ + +/* NOTE: This file has been patched from the original DMD distribution to + * work with the GDC compiler. + */ +module core.thread.osthread; + +import core.thread.threadbase; +import core.thread.context; +import core.thread.types; +import core.atomic; +import core.memory : GC; +import core.time; +import core.exception : onOutOfMemoryError; +import core.internal.traits : externDFunc; + + +/////////////////////////////////////////////////////////////////////////////// +// Platform Detection and Memory Allocation +/////////////////////////////////////////////////////////////////////////////// + +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + +version (Shared) + version (GNU) + version = GNUShared; + +version (D_InlineAsm_X86) +{ + version (Windows) + version = AsmX86_Windows; + else version (Posix) + version = AsmX86_Posix; +} +else version (D_InlineAsm_X86_64) +{ + version (Windows) + { + version = AsmX86_64_Windows; + } + else version (Posix) + { + version = AsmX86_64_Posix; + } +} +else version (X86) +{ + version (CET) {} else + { + version = AsmExternal; + } +} +else version (X86_64) +{ + version (CET) {} else + version (D_X32) {} else + { + version = AsmExternal; + } +} +else version (PPC) +{ + version (Posix) + { + version = AsmExternal; + } +} +else version (MIPS_O32) +{ + version (Posix) + { + version = AsmExternal; + } +} +else version (AArch64) +{ + version (Posix) + { + version = AsmExternal; + } +} +else version (ARM) +{ + version (Posix) + { + version = AsmExternal; + } +} + +version (Posix) +{ + version (AsmX86_Windows) {} else + version (AsmX86_Posix) {} else + version (AsmX86_64_Windows) {} else + version (AsmX86_64_Posix) {} else + version (AsmExternal) {} else + { + // NOTE: The ucontext implementation requires architecture specific + // data definitions to operate so testing for it must be done + // by checking for the existence of ucontext_t rather than by + // a version identifier. Please note that this is considered + // an obsolescent feature according to the POSIX spec, so a + // custom solution is still preferred. + import core.sys.posix.ucontext; + } +} + +version (Windows) +{ + import core.stdc.stdint : uintptr_t; // for _beginthreadex decl below + import core.stdc.stdlib; // for malloc, atexit + import core.sys.windows.basetsd /+: HANDLE+/; + import core.sys.windows.threadaux /+: getThreadStackBottom, impersonate_thread, OpenThreadHandle+/; + import core.sys.windows.winbase /+: CloseHandle, CREATE_SUSPENDED, DuplicateHandle, GetCurrentThread, + GetCurrentThreadId, GetCurrentProcess, GetExitCodeThread, GetSystemInfo, GetThreadContext, + GetThreadPriority, INFINITE, ResumeThread, SetThreadPriority, Sleep, STILL_ACTIVE, + SuspendThread, SwitchToThread, SYSTEM_INFO, THREAD_PRIORITY_IDLE, THREAD_PRIORITY_NORMAL, + THREAD_PRIORITY_TIME_CRITICAL, WAIT_OBJECT_0, WaitForSingleObject+/; + import core.sys.windows.windef /+: TRUE+/; + import core.sys.windows.winnt /+: CONTEXT, CONTEXT_CONTROL, CONTEXT_INTEGER+/; + + private extern (Windows) alias btex_fptr = uint function(void*); + private extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*) nothrow @nogc; +} +else version (Posix) +{ + import core.stdc.errno; + import core.sys.posix.semaphore; + import core.sys.posix.stdlib; // for malloc, valloc, free, atexit + import core.sys.posix.pthread; + import core.sys.posix.signal; + import core.sys.posix.time; + + version (Darwin) + { + import core.sys.darwin.mach.thread_act; + import core.sys.darwin.pthread : pthread_mach_thread_np; + } +} + +version (Solaris) +{ + import core.sys.solaris.sys.priocntl; + import core.sys.solaris.sys.types; + import core.sys.posix.sys.wait : idtype_t; +} + +version (GNU) +{ + import gcc.builtins; +} + +/** + * Hook for whatever EH implementation is used to save/restore some data + * per stack. + * + * Params: + * newContext = The return value of the prior call to this function + * where the stack was last swapped out, or null when a fiber stack + * is switched in for the first time. + */ +private extern(C) void* _d_eh_swapContext(void* newContext) nothrow @nogc; + +version (DigitalMars) +{ + version (Windows) + { + extern(D) void* swapContext(void* newContext) nothrow @nogc + { + return _d_eh_swapContext(newContext); + } + } + else + { + extern(C) void* _d_eh_swapContextDwarf(void* newContext) nothrow @nogc; + + extern(D) void* swapContext(void* newContext) nothrow @nogc + { + /* Detect at runtime which scheme is being used. + * Eventually, determine it statically. + */ + static int which = 0; + final switch (which) + { + case 0: + { + assert(newContext == null); + auto p = _d_eh_swapContext(newContext); + auto pdwarf = _d_eh_swapContextDwarf(newContext); + if (p) + { + which = 1; + return p; + } + else if (pdwarf) + { + which = 2; + return pdwarf; + } + return null; + } + case 1: + return _d_eh_swapContext(newContext); + case 2: + return _d_eh_swapContextDwarf(newContext); + } + } + } +} +else +{ + extern(D) void* swapContext(void* newContext) nothrow @nogc + { + return _d_eh_swapContext(newContext); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Thread +/////////////////////////////////////////////////////////////////////////////// + +/** + * This class encapsulates all threading functionality for the D + * programming language. As thread manipulation is a required facility + * for garbage collection, all user threads should derive from this + * class, and instances of this class should never be explicitly deleted. + * A new thread may be created using either derivation or composition, as + * in the following example. + */ +class Thread : ThreadBase +{ + // + // Main process thread + // + version (FreeBSD) + { + // set when suspend failed and should be retried, see Issue 13416 + private shared bool m_suspendagain; + } + + // + // Standard thread data + // + version (Windows) + { + private HANDLE m_hndl; + } + + version (Posix) + { + private shared bool m_isRunning; + } + + version (Darwin) + { + private mach_port_t m_tmach; + } + + version (Solaris) + { + private __gshared bool m_isRTClass; + } + + // + // Standard types + // + version (Windows) + { + alias TLSKey = uint; + } + else version (Posix) + { + alias TLSKey = pthread_key_t; + } + + /////////////////////////////////////////////////////////////////////////// + // Initialization + /////////////////////////////////////////////////////////////////////////// + + + /** + * Initializes a thread object which is associated with a static + * D function. + * + * Params: + * fn = The thread function. + * sz = The stack size for this thread. + * + * In: + * fn must not be null. + */ + this( void function() fn, size_t sz = 0 ) @safe pure nothrow @nogc + { + super(fn, sz); + } + + + /** + * Initializes a thread object which is associated with a dynamic + * D function. + * + * Params: + * dg = The thread function. + * sz = The stack size for this thread. + * + * In: + * dg must not be null. + */ + this( void delegate() dg, size_t sz = 0 ) @safe pure nothrow @nogc + { + super(dg, sz); + } + + package this( size_t sz = 0 ) @safe pure nothrow @nogc + { + super(sz); + } + + /** + * Cleans up any remaining resources used by this object. + */ + ~this() nothrow @nogc + { + if (super.destructBeforeDtor()) + return; + + version (Windows) + { + m_addr = m_addr.init; + CloseHandle( m_hndl ); + m_hndl = m_hndl.init; + } + else version (Posix) + { + pthread_detach( m_addr ); + m_addr = m_addr.init; + } + version (Darwin) + { + m_tmach = m_tmach.init; + } + } + + // + // Thread entry point. Invokes the function or delegate passed on + // construction (if any). + // + private final void run() + { + super.run(); + } + + /** + * Provides a reference to the calling thread. + * + * Returns: + * The thread object representing the calling thread. The result of + * deleting this object is undefined. If the current thread is not + * attached to the runtime, a null reference is returned. + */ + static Thread getThis() @safe nothrow @nogc + { + return ThreadBase.getThis().toThread; + } + + /////////////////////////////////////////////////////////////////////////// + // Thread Context and GC Scanning Support + /////////////////////////////////////////////////////////////////////////// + + + version (Windows) + { + version (X86) + { + uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax + } + else version (X86_64) + { + ulong[16] m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax + // r8,r9,r10,r11,r12,r13,r14,r15 + } + else + { + static assert(false, "Architecture not supported." ); + } + } + else version (Darwin) + { + version (X86) + { + uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax + } + else version (X86_64) + { + ulong[16] m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax + // r8,r9,r10,r11,r12,r13,r14,r15 + } + else version (AArch64) + { + ulong[33] m_reg; // x0-x31, pc + } + else version (ARM) + { + uint[16] m_reg; // r0-r15 + } + else + { + static assert(false, "Architecture not supported." ); + } + } + + + /////////////////////////////////////////////////////////////////////////// + // General Actions + /////////////////////////////////////////////////////////////////////////// + + + /** + * Starts the thread and invokes the function or delegate passed upon + * construction. + * + * In: + * This routine may only be called once per thread instance. + * + * Throws: + * ThreadException if the thread fails to start. + */ + final Thread start() nothrow + in + { + assert( !next && !prev ); + } + do + { + auto wasThreaded = multiThreadedFlag; + multiThreadedFlag = true; + scope( failure ) + { + if ( !wasThreaded ) + multiThreadedFlag = false; + } + + version (Windows) {} else + version (Posix) + { + size_t stksz = adjustStackSize( m_sz ); + + pthread_attr_t attr; + + if ( pthread_attr_init( &attr ) ) + onThreadError( "Error initializing thread attributes" ); + if ( stksz && pthread_attr_setstacksize( &attr, stksz ) ) + onThreadError( "Error initializing thread stack size" ); + } + + version (Windows) + { + // NOTE: If a thread is just executing DllMain() + // while another thread is started here, it holds an OS internal + // lock that serializes DllMain with CreateThread. As the code + // might request a synchronization on slock (e.g. in thread_findByAddr()), + // we cannot hold that lock while creating the thread without + // creating a deadlock + // + // Solution: Create the thread in suspended state and then + // add and resume it with slock acquired + assert(m_sz <= uint.max, "m_sz must be less than or equal to uint.max"); + m_hndl = cast(HANDLE) _beginthreadex( null, cast(uint) m_sz, &thread_entryPoint, cast(void*) this, CREATE_SUSPENDED, &m_addr ); + if ( cast(size_t) m_hndl == 0 ) + onThreadError( "Error creating thread" ); + } + + slock.lock_nothrow(); + scope(exit) slock.unlock_nothrow(); + { + ++nAboutToStart; + pAboutToStart = cast(ThreadBase*)realloc(pAboutToStart, Thread.sizeof * nAboutToStart); + pAboutToStart[nAboutToStart - 1] = this; + version (Windows) + { + if ( ResumeThread( m_hndl ) == -1 ) + onThreadError( "Error resuming thread" ); + } + else version (Posix) + { + // NOTE: This is also set to true by thread_entryPoint, but set it + // here as well so the calling thread will see the isRunning + // state immediately. + atomicStore!(MemoryOrder.raw)(m_isRunning, true); + scope( failure ) atomicStore!(MemoryOrder.raw)(m_isRunning, false); + + version (Shared) + { + version (GNU) + { + auto libs = externDFunc!("gcc.sections.elf_shared.pinLoadedLibraries", + void* function() @nogc nothrow)(); + } + else + { + auto libs = externDFunc!("rt.sections_elf_shared.pinLoadedLibraries", + void* function() @nogc nothrow)(); + } + + auto ps = cast(void**).malloc(2 * size_t.sizeof); + if (ps is null) onOutOfMemoryError(); + ps[0] = cast(void*)this; + ps[1] = cast(void*)libs; + if ( pthread_create( &m_addr, &attr, &thread_entryPoint, ps ) != 0 ) + { + version (GNU) + { + externDFunc!("gcc.sections.elf_shared.unpinLoadedLibraries", + void function(void*) @nogc nothrow)(libs); + } + else + { + externDFunc!("rt.sections_elf_shared.unpinLoadedLibraries", + void function(void*) @nogc nothrow)(libs); + } + .free(ps); + onThreadError( "Error creating thread" ); + } + } + else + { + if ( pthread_create( &m_addr, &attr, &thread_entryPoint, cast(void*) this ) != 0 ) + onThreadError( "Error creating thread" ); + } + if ( pthread_attr_destroy( &attr ) != 0 ) + onThreadError( "Error destroying thread attributes" ); + } + version (Darwin) + { + m_tmach = pthread_mach_thread_np( m_addr ); + if ( m_tmach == m_tmach.init ) + onThreadError( "Error creating thread" ); + } + + return this; + } + } + + /** + * Waits for this thread to complete. If the thread terminated as the + * result of an unhandled exception, this exception will be rethrown. + * + * Params: + * rethrow = Rethrow any unhandled exception which may have caused this + * thread to terminate. + * + * Throws: + * ThreadException if the operation fails. + * Any exception not handled by the joined thread. + * + * Returns: + * Any exception not handled by this thread if rethrow = false, null + * otherwise. + */ + override final Throwable join( bool rethrow = true ) + { + version (Windows) + { + if ( WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 ) + throw new ThreadException( "Unable to join thread" ); + // NOTE: m_addr must be cleared before m_hndl is closed to avoid + // a race condition with isRunning. The operation is done + // with atomicStore to prevent compiler reordering. + atomicStore!(MemoryOrder.raw)(*cast(shared)&m_addr, m_addr.init); + CloseHandle( m_hndl ); + m_hndl = m_hndl.init; + } + else version (Posix) + { + if ( pthread_join( m_addr, null ) != 0 ) + throw new ThreadException( "Unable to join thread" ); + // NOTE: pthread_join acts as a substitute for pthread_detach, + // which is normally called by the dtor. Setting m_addr + // to zero ensures that pthread_detach will not be called + // on object destruction. + m_addr = m_addr.init; + } + if ( m_unhandled ) + { + if ( rethrow ) + throw m_unhandled; + return m_unhandled; + } + return null; + } + + + /////////////////////////////////////////////////////////////////////////// + // Thread Priority Actions + /////////////////////////////////////////////////////////////////////////// + + version (Windows) + { + @property static int PRIORITY_MIN() @nogc nothrow pure @safe + { + return THREAD_PRIORITY_IDLE; + } + + @property static const(int) PRIORITY_MAX() @nogc nothrow pure @safe + { + return THREAD_PRIORITY_TIME_CRITICAL; + } + + @property static int PRIORITY_DEFAULT() @nogc nothrow pure @safe + { + return THREAD_PRIORITY_NORMAL; + } + } + else + { + private struct Priority + { + int PRIORITY_MIN = int.min; + int PRIORITY_DEFAULT = int.min; + int PRIORITY_MAX = int.min; + } + + /* + Lazily loads one of the members stored in a hidden global variable of + type `Priority`. Upon the first access of either member, the entire + `Priority` structure is initialized. Multiple initializations from + different threads calling this function are tolerated. + + `which` must be one of `PRIORITY_MIN`, `PRIORITY_DEFAULT`, + `PRIORITY_MAX`. + */ + private static shared Priority cache; + private static int loadGlobal(string which)() + { + auto local = atomicLoad(mixin("cache." ~ which)); + if (local != local.min) return local; + // There will be benign races + cache = loadPriorities; + return atomicLoad(mixin("cache." ~ which)); + } + + /* + Loads all priorities and returns them as a `Priority` structure. This + function is thread-neutral. + */ + private static Priority loadPriorities() @nogc nothrow @trusted + { + Priority result; + version (Solaris) + { + pcparms_t pcParms; + pcinfo_t pcInfo; + + pcParms.pc_cid = PC_CLNULL; + if (priocntl(idtype_t.P_PID, P_MYID, PC_GETPARMS, &pcParms) == -1) + assert( 0, "Unable to get scheduling class" ); + + pcInfo.pc_cid = pcParms.pc_cid; + // PC_GETCLINFO ignores the first two args, use dummy values + if (priocntl(idtype_t.P_PID, 0, PC_GETCLINFO, &pcInfo) == -1) + assert( 0, "Unable to get scheduling class info" ); + + pri_t* clparms = cast(pri_t*)&pcParms.pc_clparms; + pri_t* clinfo = cast(pri_t*)&pcInfo.pc_clinfo; + + result.PRIORITY_MAX = clparms[0]; + + if (pcInfo.pc_clname == "RT") + { + m_isRTClass = true; + + // For RT class, just assume it can't be changed + result.PRIORITY_MIN = clparms[0]; + result.PRIORITY_DEFAULT = clparms[0]; + } + else + { + m_isRTClass = false; + + // For all other scheduling classes, there are + // two key values -- uprilim and maxupri. + // maxupri is the maximum possible priority defined + // for the scheduling class, and valid priorities + // range are in [-maxupri, maxupri]. + // + // However, uprilim is an upper limit that the + // current thread can set for the current scheduling + // class, which can be less than maxupri. As such, + // use this value for priorityMax since this is + // the effective maximum. + + // maxupri + result.PRIORITY_MIN = -clinfo[0]; + // by definition + result.PRIORITY_DEFAULT = 0; + } + } + else version (Posix) + { + int policy; + sched_param param; + pthread_getschedparam( pthread_self(), &policy, ¶m ) == 0 + || assert(0, "Internal error in pthread_getschedparam"); + + result.PRIORITY_MIN = sched_get_priority_min( policy ); + result.PRIORITY_MIN != -1 + || assert(0, "Internal error in sched_get_priority_min"); + result.PRIORITY_DEFAULT = param.sched_priority; + result.PRIORITY_MAX = sched_get_priority_max( policy ); + result.PRIORITY_MAX != -1 || + assert(0, "Internal error in sched_get_priority_max"); + } + else + { + static assert(0, "Your code here."); + } + return result; + } + + /** + * The minimum scheduling priority that may be set for a thread. On + * systems where multiple scheduling policies are defined, this value + * represents the minimum valid priority for the scheduling policy of + * the process. + */ + @property static int PRIORITY_MIN() @nogc nothrow pure @trusted + { + return (cast(int function() @nogc nothrow pure @safe) + &loadGlobal!"PRIORITY_MIN")(); + } + + /** + * The maximum scheduling priority that may be set for a thread. On + * systems where multiple scheduling policies are defined, this value + * represents the maximum valid priority for the scheduling policy of + * the process. + */ + @property static const(int) PRIORITY_MAX() @nogc nothrow pure @trusted + { + return (cast(int function() @nogc nothrow pure @safe) + &loadGlobal!"PRIORITY_MAX")(); + } + + /** + * The default scheduling priority that is set for a thread. On + * systems where multiple scheduling policies are defined, this value + * represents the default priority for the scheduling policy of + * the process. + */ + @property static int PRIORITY_DEFAULT() @nogc nothrow pure @trusted + { + return (cast(int function() @nogc nothrow pure @safe) + &loadGlobal!"PRIORITY_DEFAULT")(); + } + } + + version (NetBSD) + { + //NetBSD does not support priority for default policy + // and it is not possible change policy without root access + int fakePriority = int.max; + } + + /** + * Gets the scheduling priority for the associated thread. + * + * Note: Getting the priority of a thread that already terminated + * might return the default priority. + * + * Returns: + * The scheduling priority of this thread. + */ + final @property int priority() + { + version (Windows) + { + return GetThreadPriority( m_hndl ); + } + else version (NetBSD) + { + return fakePriority==int.max? PRIORITY_DEFAULT : fakePriority; + } + else version (Posix) + { + int policy; + sched_param param; + + if (auto err = pthread_getschedparam(m_addr, &policy, ¶m)) + { + // ignore error if thread is not running => Bugzilla 8960 + if (!atomicLoad(m_isRunning)) return PRIORITY_DEFAULT; + throw new ThreadException("Unable to get thread priority"); + } + return param.sched_priority; + } + } + + + /** + * Sets the scheduling priority for the associated thread. + * + * Note: Setting the priority of a thread that already terminated + * might have no effect. + * + * Params: + * val = The new scheduling priority of this thread. + */ + final @property void priority( int val ) + in + { + assert(val >= PRIORITY_MIN); + assert(val <= PRIORITY_MAX); + } + do + { + version (Windows) + { + if ( !SetThreadPriority( m_hndl, val ) ) + throw new ThreadException( "Unable to set thread priority" ); + } + else version (Solaris) + { + // the pthread_setschedprio(3c) and pthread_setschedparam functions + // are broken for the default (TS / time sharing) scheduling class. + // instead, we use priocntl(2) which gives us the desired behavior. + + // We hardcode the min and max priorities to the current value + // so this is a no-op for RT threads. + if (m_isRTClass) + return; + + pcparms_t pcparm; + + pcparm.pc_cid = PC_CLNULL; + if (priocntl(idtype_t.P_LWPID, P_MYID, PC_GETPARMS, &pcparm) == -1) + throw new ThreadException( "Unable to get scheduling class" ); + + pri_t* clparms = cast(pri_t*)&pcparm.pc_clparms; + + // clparms is filled in by the PC_GETPARMS call, only necessary + // to adjust the element that contains the thread priority + clparms[1] = cast(pri_t) val; + + if (priocntl(idtype_t.P_LWPID, P_MYID, PC_SETPARMS, &pcparm) == -1) + throw new ThreadException( "Unable to set scheduling class" ); + } + else version (NetBSD) + { + fakePriority = val; + } + else version (Posix) + { + static if (__traits(compiles, pthread_setschedprio)) + { + if (auto err = pthread_setschedprio(m_addr, val)) + { + // ignore error if thread is not running => Bugzilla 8960 + if (!atomicLoad(m_isRunning)) return; + throw new ThreadException("Unable to set thread priority"); + } + } + else + { + // NOTE: pthread_setschedprio is not implemented on Darwin, FreeBSD, OpenBSD, + // or DragonFlyBSD, so use the more complicated get/set sequence below. + int policy; + sched_param param; + + if (auto err = pthread_getschedparam(m_addr, &policy, ¶m)) + { + // ignore error if thread is not running => Bugzilla 8960 + if (!atomicLoad(m_isRunning)) return; + throw new ThreadException("Unable to set thread priority"); + } + param.sched_priority = val; + if (auto err = pthread_setschedparam(m_addr, policy, ¶m)) + { + // ignore error if thread is not running => Bugzilla 8960 + if (!atomicLoad(m_isRunning)) return; + throw new ThreadException("Unable to set thread priority"); + } + } + } + } + + + unittest + { + auto thr = Thread.getThis(); + immutable prio = thr.priority; + scope (exit) thr.priority = prio; + + assert(prio == PRIORITY_DEFAULT); + assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX); + thr.priority = PRIORITY_MIN; + assert(thr.priority == PRIORITY_MIN); + thr.priority = PRIORITY_MAX; + assert(thr.priority == PRIORITY_MAX); + } + + unittest // Bugzilla 8960 + { + import core.sync.semaphore; + + auto thr = new Thread({}); + thr.start(); + Thread.sleep(1.msecs); // wait a little so the thread likely has finished + thr.priority = PRIORITY_MAX; // setting priority doesn't cause error + auto prio = thr.priority; // getting priority doesn't cause error + assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX); + } + + /** + * Tests whether this thread is running. + * + * Returns: + * true if the thread is running, false if not. + */ + override final @property bool isRunning() nothrow @nogc + { + if (!super.isRunning()) + return false; + + version (Windows) + { + uint ecode = 0; + GetExitCodeThread( m_hndl, &ecode ); + return ecode == STILL_ACTIVE; + } + else version (Posix) + { + return atomicLoad(m_isRunning); + } + } + + + /////////////////////////////////////////////////////////////////////////// + // Actions on Calling Thread + /////////////////////////////////////////////////////////////////////////// + + + /** + * Suspends the calling thread for at least the supplied period. This may + * result in multiple OS calls if period is greater than the maximum sleep + * duration supported by the operating system. + * + * Params: + * val = The minimum duration the calling thread should be suspended. + * + * In: + * period must be non-negative. + * + * Example: + * ------------------------------------------------------------------------ + * + * Thread.sleep( dur!("msecs")( 50 ) ); // sleep for 50 milliseconds + * Thread.sleep( dur!("seconds")( 5 ) ); // sleep for 5 seconds + * + * ------------------------------------------------------------------------ + */ + static void sleep( Duration val ) @nogc nothrow + in + { + assert( !val.isNegative ); + } + do + { + version (Windows) + { + auto maxSleepMillis = dur!("msecs")( uint.max - 1 ); + + // avoid a non-zero time to be round down to 0 + if ( val > dur!"msecs"( 0 ) && val < dur!"msecs"( 1 ) ) + val = dur!"msecs"( 1 ); + + // NOTE: In instances where all other threads in the process have a + // lower priority than the current thread, the current thread + // will not yield with a sleep time of zero. However, unlike + // yield(), the user is not asking for a yield to occur but + // only for execution to suspend for the requested interval. + // Therefore, expected performance may not be met if a yield + // is forced upon the user. + while ( val > maxSleepMillis ) + { + Sleep( cast(uint) + maxSleepMillis.total!"msecs" ); + val -= maxSleepMillis; + } + Sleep( cast(uint) val.total!"msecs" ); + } + else version (Posix) + { + timespec tin = void; + timespec tout = void; + + val.split!("seconds", "nsecs")(tin.tv_sec, tin.tv_nsec); + if ( val.total!"seconds" > tin.tv_sec.max ) + tin.tv_sec = tin.tv_sec.max; + while ( true ) + { + if ( !nanosleep( &tin, &tout ) ) + return; + if ( errno != EINTR ) + assert(0, "Unable to sleep for the specified duration"); + tin = tout; + } + } + } + + + /** + * Forces a context switch to occur away from the calling thread. + */ + static void yield() @nogc nothrow + { + version (Windows) + SwitchToThread(); + else version (Posix) + sched_yield(); + } +} + +private Thread toThread(ThreadBase t) @trusted nothrow @nogc pure +{ + return cast(Thread) cast(void*) t; +} + +private extern(D) static void thread_yield() @nogc nothrow +{ + Thread.yield(); +} + +/// +unittest +{ + class DerivedThread : Thread + { + this() + { + super(&run); + } + + private: + void run() + { + // Derived thread running. + } + } + + void threadFunc() + { + // Composed thread running. + } + + // create and start instances of each type + auto derived = new DerivedThread().start(); + auto composed = new Thread(&threadFunc).start(); + new Thread({ + // Codes to run in the newly created thread. + }).start(); +} + +unittest +{ + int x = 0; + + new Thread( + { + x++; + }).start().join(); + assert( x == 1 ); +} + + +unittest +{ + enum MSG = "Test message."; + string caughtMsg; + + try + { + new Thread( + { + throw new Exception( MSG ); + }).start().join(); + assert( false, "Expected rethrown exception." ); + } + catch ( Throwable t ) + { + assert( t.msg == MSG ); + } +} + + +unittest +{ + // use >PAGESIZE to avoid stack overflow (e.g. in an syscall) + auto thr = new Thread(function{}, 4096 + 1).start(); + thr.join(); +} + + +unittest +{ + import core.memory : GC; + + auto t1 = new Thread({ + foreach (_; 0 .. 20) + ThreadBase.getAll; + }).start; + auto t2 = new Thread({ + foreach (_; 0 .. 20) + GC.collect; + }).start; + t1.join(); + t2.join(); +} + +unittest +{ + import core.sync.semaphore; + auto sem = new Semaphore(); + + auto t = new Thread( + { + sem.notify(); + Thread.sleep(100.msecs); + }).start(); + + sem.wait(); // thread cannot be detached while being started + thread_detachInstance(t); + foreach (t2; Thread) + assert(t !is t2); + t.join(); +} + +unittest +{ + // NOTE: This entire test is based on the assumption that no + // memory is allocated after the child thread is + // started. If an allocation happens, a collection could + // trigger, which would cause the synchronization below + // to cause a deadlock. + // NOTE: DO NOT USE LOCKS IN CRITICAL REGIONS IN NORMAL CODE. + + import core.sync.semaphore; + + auto sema = new Semaphore(), + semb = new Semaphore(); + + auto thr = new Thread( + { + thread_enterCriticalRegion(); + assert(thread_inCriticalRegion()); + sema.notify(); + + semb.wait(); + assert(thread_inCriticalRegion()); + + thread_exitCriticalRegion(); + assert(!thread_inCriticalRegion()); + sema.notify(); + + semb.wait(); + assert(!thread_inCriticalRegion()); + }); + + thr.start(); + + sema.wait(); + synchronized (ThreadBase.criticalRegionLock) + assert(thr.m_isInCriticalRegion); + semb.notify(); + + sema.wait(); + synchronized (ThreadBase.criticalRegionLock) + assert(!thr.m_isInCriticalRegion); + semb.notify(); + + thr.join(); +} + +unittest +{ + import core.sync.semaphore; + + shared bool inCriticalRegion; + auto sema = new Semaphore(), + semb = new Semaphore(); + + auto thr = new Thread( + { + thread_enterCriticalRegion(); + inCriticalRegion = true; + sema.notify(); + semb.wait(); + + Thread.sleep(dur!"msecs"(1)); + inCriticalRegion = false; + thread_exitCriticalRegion(); + }); + thr.start(); + + sema.wait(); + assert(inCriticalRegion); + semb.notify(); + + thread_suspendAll(); + assert(!inCriticalRegion); + thread_resumeAll(); +} + +/////////////////////////////////////////////////////////////////////////////// +// GC Support Routines +/////////////////////////////////////////////////////////////////////////////// + +version (CoreDdoc) +{ + /** + * Instruct the thread module, when initialized, to use a different set of + * signals besides SIGUSR1 and SIGUSR2 for suspension and resumption of threads. + * This function should be called at most once, prior to thread_init(). + * This function is Posix-only. + */ + extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc + { + } +} +else version (Posix) +{ + extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc + in + { + assert(suspendSignalNo != 0); + assert(resumeSignalNo != 0); + } + out + { + assert(suspendSignalNumber != 0); + assert(resumeSignalNumber != 0); + } + do + { + suspendSignalNumber = suspendSignalNo; + resumeSignalNumber = resumeSignalNo; + } +} + +version (Posix) +{ + private __gshared int suspendSignalNumber = SIGUSR1; + private __gshared int resumeSignalNumber = SIGUSR2; +} + +private extern (D) ThreadBase attachThread(ThreadBase _thisThread) @nogc nothrow +{ + Thread thisThread = _thisThread.toThread(); + + StackContext* thisContext = &thisThread.m_main; + assert( thisContext == thisThread.m_curr ); + + version (Windows) + { + thisThread.m_addr = GetCurrentThreadId(); + thisThread.m_hndl = GetCurrentThreadHandle(); + thisContext.bstack = getStackBottom(); + thisContext.tstack = thisContext.bstack; + } + else version (Posix) + { + thisThread.m_addr = pthread_self(); + thisContext.bstack = getStackBottom(); + thisContext.tstack = thisContext.bstack; + + atomicStore!(MemoryOrder.raw)(thisThread.toThread.m_isRunning, true); + } + thisThread.m_isDaemon = true; + thisThread.tlsGCdataInit(); + Thread.setThis( thisThread ); + + version (Darwin) + { + thisThread.m_tmach = pthread_mach_thread_np( thisThread.m_addr ); + assert( thisThread.m_tmach != thisThread.m_tmach.init ); + } + + Thread.add( thisThread, false ); + Thread.add( thisContext ); + if ( Thread.sm_main !is null ) + multiThreadedFlag = true; + return thisThread; +} + +/** + * Registers the calling thread for use with the D Runtime. If this routine + * is called for a thread which is already registered, no action is performed. + * + * NOTE: This routine does not run thread-local static constructors when called. + * If full functionality as a D thread is desired, the following function + * must be called after thread_attachThis: + * + * extern (C) void rt_moduleTlsCtor(); + */ +extern(C) Thread thread_attachThis() +{ + return thread_attachThis_tpl!Thread(); +} + + +version (Windows) +{ + // NOTE: These calls are not safe on Posix systems that use signals to + // perform garbage collection. The suspendHandler uses getThis() + // to get the thread handle so getThis() must be a simple call. + // Mutexes can't safely be acquired inside signal handlers, and + // even if they could, the mutex needed (Thread.slock) is held by + // thread_suspendAll(). So in short, these routines will remain + // Windows-specific. If they are truly needed elsewhere, the + // suspendHandler will need a way to call a version of getThis() + // that only does the TLS lookup without the fancy fallback stuff. + + /// ditto + extern (C) Thread thread_attachByAddr( ThreadID addr ) + { + return thread_attachByAddrB( addr, getThreadStackBottom( addr ) ); + } + + + /// ditto + extern (C) Thread thread_attachByAddrB( ThreadID addr, void* bstack ) + { + GC.disable(); scope(exit) GC.enable(); + + if (auto t = thread_findByAddr(addr).toThread) + return t; + + Thread thisThread = new Thread(); + StackContext* thisContext = &thisThread.m_main; + assert( thisContext == thisThread.m_curr ); + + thisThread.m_addr = addr; + thisContext.bstack = bstack; + thisContext.tstack = thisContext.bstack; + + thisThread.m_isDaemon = true; + + if ( addr == GetCurrentThreadId() ) + { + thisThread.m_hndl = GetCurrentThreadHandle(); + thisThread.tlsGCdataInit(); + Thread.setThis( thisThread ); + } + else + { + thisThread.m_hndl = OpenThreadHandle( addr ); + impersonate_thread(addr, + { + thisThread.tlsGCdataInit(); + Thread.setThis( thisThread ); + }); + } + + Thread.add( thisThread, false ); + Thread.add( thisContext ); + if ( Thread.sm_main !is null ) + multiThreadedFlag = true; + return thisThread; + } +} + + +// Calls the given delegate, passing the current thread's stack pointer to it. +package extern(D) void callWithStackShell(scope callWithStackShellDg fn) nothrow +in (fn) +{ + // The purpose of the 'shell' is to ensure all the registers get + // put on the stack so they'll be scanned. We only need to push + // the callee-save registers. + void *sp = void; + version (GNU) + { + __builtin_unwind_init(); + sp = &sp; + } + else version (AsmX86_Posix) + { + size_t[3] regs = void; + asm pure nothrow @nogc + { + mov [regs + 0 * 4], EBX; + mov [regs + 1 * 4], ESI; + mov [regs + 2 * 4], EDI; + + mov sp[EBP], ESP; + } + } + else version (AsmX86_Windows) + { + size_t[3] regs = void; + asm pure nothrow @nogc + { + mov [regs + 0 * 4], EBX; + mov [regs + 1 * 4], ESI; + mov [regs + 2 * 4], EDI; + + mov sp[EBP], ESP; + } + } + else version (AsmX86_64_Posix) + { + size_t[5] regs = void; + asm pure nothrow @nogc + { + mov [regs + 0 * 8], RBX; + mov [regs + 1 * 8], R12; + mov [regs + 2 * 8], R13; + mov [regs + 3 * 8], R14; + mov [regs + 4 * 8], R15; + + mov sp[RBP], RSP; + } + } + else version (AsmX86_64_Windows) + { + size_t[7] regs = void; + asm pure nothrow @nogc + { + mov [regs + 0 * 8], RBX; + mov [regs + 1 * 8], RSI; + mov [regs + 2 * 8], RDI; + mov [regs + 3 * 8], R12; + mov [regs + 4 * 8], R13; + mov [regs + 5 * 8], R14; + mov [regs + 6 * 8], R15; + + mov sp[RBP], RSP; + } + } + else + { + static assert(false, "Architecture not supported."); + } + + fn(sp); +} + +version (Solaris) +{ + import core.sys.solaris.sys.priocntl; + import core.sys.solaris.sys.types; + import core.sys.posix.sys.wait : idtype_t; +} + + +version (Windows) +private extern (D) void scanWindowsOnly(scope ScanAllThreadsTypeFn scan, ThreadBase _t) nothrow +{ + auto t = _t.toThread; + + scan( ScanType.stack, t.m_reg.ptr, t.m_reg.ptr + t.m_reg.length ); +} + + +/** + * Returns the process ID of the calling process, which is guaranteed to be + * unique on the system. This call is always successful. + * + * Example: + * --- + * writefln("Current process id: %s", getpid()); + * --- + */ +version (Posix) +{ + import core.sys.posix.unistd; + + alias getpid = core.sys.posix.unistd.getpid; +} +else version (Windows) +{ + alias getpid = core.sys.windows.winbase.GetCurrentProcessId; +} + +extern (C) @nogc nothrow +{ + version (CRuntime_Glibc) version = PThread_Getattr_NP; + version (CRuntime_Bionic) version = PThread_Getattr_NP; + version (CRuntime_Musl) version = PThread_Getattr_NP; + version (CRuntime_UClibc) version = PThread_Getattr_NP; + + version (FreeBSD) version = PThread_Attr_Get_NP; + version (NetBSD) version = PThread_Attr_Get_NP; + version (DragonFlyBSD) version = PThread_Attr_Get_NP; + + version (PThread_Getattr_NP) int pthread_getattr_np(pthread_t thread, pthread_attr_t* attr); + version (PThread_Attr_Get_NP) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr); + version (Solaris) int thr_stksegment(stack_t* stk); + version (OpenBSD) int pthread_stackseg_np(pthread_t thread, stack_t* sinfo); +} + + +package extern(D) void* getStackTop() nothrow @nogc +{ + version (D_InlineAsm_X86) + asm pure nothrow @nogc { naked; mov EAX, ESP; ret; } + else version (D_InlineAsm_X86_64) + asm pure nothrow @nogc { naked; mov RAX, RSP; ret; } + else version (GNU) + return __builtin_frame_address(0); + else + static assert(false, "Architecture not supported."); +} + + +package extern(D) void* getStackBottom() nothrow @nogc +{ + version (Windows) + { + version (D_InlineAsm_X86) + asm pure nothrow @nogc { naked; mov EAX, FS:4; ret; } + else version (D_InlineAsm_X86_64) + asm pure nothrow @nogc + { naked; + mov RAX, 8; + mov RAX, GS:[RAX]; + ret; + } + else version (GNU_InlineAsm) + { + void *bottom; + + version (X86) + asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; } + else version (X86_64) + asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; } + else + static assert(false, "Platform not supported."); + + return bottom; + } + else + static assert(false, "Architecture not supported."); + } + else version (Darwin) + { + import core.sys.darwin.pthread; + return pthread_get_stackaddr_np(pthread_self()); + } + else version (PThread_Getattr_NP) + { + pthread_attr_t attr; + void* addr; size_t size; + + pthread_attr_init(&attr); + pthread_getattr_np(pthread_self(), &attr); + pthread_attr_getstack(&attr, &addr, &size); + pthread_attr_destroy(&attr); + static if (isStackGrowingDown) + addr += size; + return addr; + } + else version (PThread_Attr_Get_NP) + { + pthread_attr_t attr; + void* addr; size_t size; + + pthread_attr_init(&attr); + pthread_attr_get_np(pthread_self(), &attr); + pthread_attr_getstack(&attr, &addr, &size); + pthread_attr_destroy(&attr); + static if (isStackGrowingDown) + addr += size; + return addr; + } + else version (OpenBSD) + { + stack_t stk; + + pthread_stackseg_np(pthread_self(), &stk); + return stk.ss_sp; + } + else version (Solaris) + { + stack_t stk; + + thr_stksegment(&stk); + return stk.ss_sp; + } + else + static assert(false, "Platform not supported."); +} + +/** + * Suspend the specified thread and load stack and register information for + * use by thread_scanAll. If the supplied thread is the calling thread, + * stack and register information will be loaded but the thread will not + * be suspended. If the suspend operation fails and the thread is not + * running then it will be removed from the global thread list, otherwise + * an exception will be thrown. + * + * Params: + * t = The thread to suspend. + * + * Throws: + * ThreadError if the suspend operation fails for a running thread. + * Returns: + * Whether the thread is now suspended (true) or terminated (false). + */ +private extern (D) bool suspend( Thread t ) nothrow @nogc +{ + Duration waittime = dur!"usecs"(10); + Lagain: + if (!t.isRunning) + { + Thread.remove(t); + return false; + } + else if (t.m_isInCriticalRegion) + { + Thread.criticalRegionLock.unlock_nothrow(); + Thread.sleep(waittime); + if (waittime < dur!"msecs"(10)) waittime *= 2; + Thread.criticalRegionLock.lock_nothrow(); + goto Lagain; + } + + version (Windows) + { + if ( t.m_addr != GetCurrentThreadId() && SuspendThread( t.m_hndl ) == 0xFFFFFFFF ) + { + if ( !t.isRunning ) + { + Thread.remove( t ); + return false; + } + onThreadError( "Unable to suspend thread" ); + } + + CONTEXT context = void; + context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL; + + if ( !GetThreadContext( t.m_hndl, &context ) ) + onThreadError( "Unable to load thread context" ); + version (X86) + { + if ( !t.m_lock ) + t.m_curr.tstack = cast(void*) context.Esp; + // eax,ebx,ecx,edx,edi,esi,ebp,esp + t.m_reg[0] = context.Eax; + t.m_reg[1] = context.Ebx; + t.m_reg[2] = context.Ecx; + t.m_reg[3] = context.Edx; + t.m_reg[4] = context.Edi; + t.m_reg[5] = context.Esi; + t.m_reg[6] = context.Ebp; + t.m_reg[7] = context.Esp; + } + else version (X86_64) + { + if ( !t.m_lock ) + t.m_curr.tstack = cast(void*) context.Rsp; + // rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp + t.m_reg[0] = context.Rax; + t.m_reg[1] = context.Rbx; + t.m_reg[2] = context.Rcx; + t.m_reg[3] = context.Rdx; + t.m_reg[4] = context.Rdi; + t.m_reg[5] = context.Rsi; + t.m_reg[6] = context.Rbp; + t.m_reg[7] = context.Rsp; + // r8,r9,r10,r11,r12,r13,r14,r15 + t.m_reg[8] = context.R8; + t.m_reg[9] = context.R9; + t.m_reg[10] = context.R10; + t.m_reg[11] = context.R11; + t.m_reg[12] = context.R12; + t.m_reg[13] = context.R13; + t.m_reg[14] = context.R14; + t.m_reg[15] = context.R15; + } + else + { + static assert(false, "Architecture not supported." ); + } + } + else version (Darwin) + { + if ( t.m_addr != pthread_self() && thread_suspend( t.m_tmach ) != KERN_SUCCESS ) + { + if ( !t.isRunning ) + { + Thread.remove( t ); + return false; + } + onThreadError( "Unable to suspend thread" ); + } + + version (X86) + { + x86_thread_state32_t state = void; + mach_msg_type_number_t count = x86_THREAD_STATE32_COUNT; + + if ( thread_get_state( t.m_tmach, x86_THREAD_STATE32, &state, &count ) != KERN_SUCCESS ) + onThreadError( "Unable to load thread state" ); + if ( !t.m_lock ) + t.m_curr.tstack = cast(void*) state.esp; + // eax,ebx,ecx,edx,edi,esi,ebp,esp + t.m_reg[0] = state.eax; + t.m_reg[1] = state.ebx; + t.m_reg[2] = state.ecx; + t.m_reg[3] = state.edx; + t.m_reg[4] = state.edi; + t.m_reg[5] = state.esi; + t.m_reg[6] = state.ebp; + t.m_reg[7] = state.esp; + } + else version (X86_64) + { + x86_thread_state64_t state = void; + mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; + + if ( thread_get_state( t.m_tmach, x86_THREAD_STATE64, &state, &count ) != KERN_SUCCESS ) + onThreadError( "Unable to load thread state" ); + if ( !t.m_lock ) + t.m_curr.tstack = cast(void*) state.rsp; + // rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp + t.m_reg[0] = state.rax; + t.m_reg[1] = state.rbx; + t.m_reg[2] = state.rcx; + t.m_reg[3] = state.rdx; + t.m_reg[4] = state.rdi; + t.m_reg[5] = state.rsi; + t.m_reg[6] = state.rbp; + t.m_reg[7] = state.rsp; + // r8,r9,r10,r11,r12,r13,r14,r15 + t.m_reg[8] = state.r8; + t.m_reg[9] = state.r9; + t.m_reg[10] = state.r10; + t.m_reg[11] = state.r11; + t.m_reg[12] = state.r12; + t.m_reg[13] = state.r13; + t.m_reg[14] = state.r14; + t.m_reg[15] = state.r15; + } + else version (AArch64) + { + arm_thread_state64_t state = void; + mach_msg_type_number_t count = ARM_THREAD_STATE64_COUNT; + + if (thread_get_state(t.m_tmach, ARM_THREAD_STATE64, &state, &count) != KERN_SUCCESS) + onThreadError("Unable to load thread state"); + // TODO: ThreadException here recurses forever! Does it + //still using onThreadError? + //printf("state count %d (expect %d)\n", count ,ARM_THREAD_STATE64_COUNT); + if (!t.m_lock) + t.m_curr.tstack = cast(void*) state.sp; + + t.m_reg[0..29] = state.x; // x0-x28 + t.m_reg[29] = state.fp; // x29 + t.m_reg[30] = state.lr; // x30 + t.m_reg[31] = state.sp; // x31 + t.m_reg[32] = state.pc; + } + else version (ARM) + { + arm_thread_state32_t state = void; + mach_msg_type_number_t count = ARM_THREAD_STATE32_COUNT; + + // Thought this would be ARM_THREAD_STATE32, but that fails. + // Mystery + if (thread_get_state(t.m_tmach, ARM_THREAD_STATE, &state, &count) != KERN_SUCCESS) + onThreadError("Unable to load thread state"); + // TODO: in past, ThreadException here recurses forever! Does it + //still using onThreadError? + //printf("state count %d (expect %d)\n", count ,ARM_THREAD_STATE32_COUNT); + if (!t.m_lock) + t.m_curr.tstack = cast(void*) state.sp; + + t.m_reg[0..13] = state.r; // r0 - r13 + t.m_reg[13] = state.sp; + t.m_reg[14] = state.lr; + t.m_reg[15] = state.pc; + } + else + { + static assert(false, "Architecture not supported." ); + } + } + else version (Posix) + { + if ( t.m_addr != pthread_self() ) + { + if ( pthread_kill( t.m_addr, suspendSignalNumber ) != 0 ) + { + if ( !t.isRunning ) + { + Thread.remove( t ); + return false; + } + onThreadError( "Unable to suspend thread" ); + } + } + else if ( !t.m_lock ) + { + t.m_curr.tstack = getStackTop(); + } + } + return true; +} + +/** + * Suspend all threads but the calling thread for "stop the world" garbage + * collection runs. This function may be called multiple times, and must + * be followed by a matching number of calls to thread_resumeAll before + * processing is resumed. + * + * Throws: + * ThreadError if the suspend operation fails for a running thread. + */ +extern (C) void thread_suspendAll() nothrow +{ + // NOTE: We've got an odd chicken & egg problem here, because while the GC + // is required to call thread_init before calling any other thread + // routines, thread_init may allocate memory which could in turn + // trigger a collection. Thus, thread_suspendAll, thread_scanAll, + // and thread_resumeAll must be callable before thread_init + // completes, with the assumption that no other GC memory has yet + // been allocated by the system, and thus there is no risk of losing + // data if the global thread list is empty. The check of + // Thread.sm_tbeg below is done to ensure thread_init has completed, + // and therefore that calling Thread.getThis will not result in an + // error. For the short time when Thread.sm_tbeg is null, there is + // no reason not to simply call the multithreaded code below, with + // the expectation that the foreach loop will never be entered. + if ( !multiThreadedFlag && Thread.sm_tbeg ) + { + if ( ++suspendDepth == 1 ) + suspend( Thread.getThis() ); + + return; + } + + Thread.slock.lock_nothrow(); + { + if ( ++suspendDepth > 1 ) + return; + + Thread.criticalRegionLock.lock_nothrow(); + scope (exit) Thread.criticalRegionLock.unlock_nothrow(); + size_t cnt; + Thread t = ThreadBase.sm_tbeg.toThread; + while (t) + { + auto tn = t.next.toThread; + if (suspend(t)) + ++cnt; + t = tn; + } + + version (Darwin) + {} + else version (Posix) + { + // subtract own thread + assert(cnt >= 1); + --cnt; + Lagain: + // wait for semaphore notifications + for (; cnt; --cnt) + { + while (sem_wait(&suspendCount) != 0) + { + if (errno != EINTR) + onThreadError("Unable to wait for semaphore"); + errno = 0; + } + } + version (FreeBSD) + { + // avoid deadlocks, see Issue 13416 + t = ThreadBase.sm_tbeg.toThread; + while (t) + { + auto tn = t.next; + if (t.m_suspendagain && suspend(t)) + ++cnt; + t = tn.toThread; + } + if (cnt) + goto Lagain; + } + } + } +} + +/** + * Resume the specified thread and unload stack and register information. + * If the supplied thread is the calling thread, stack and register + * information will be unloaded but the thread will not be resumed. If + * the resume operation fails and the thread is not running then it will + * be removed from the global thread list, otherwise an exception will be + * thrown. + * + * Params: + * t = The thread to resume. + * + * Throws: + * ThreadError if the resume fails for a running thread. + */ +private extern (D) void resume(ThreadBase _t) nothrow @nogc +{ + Thread t = _t.toThread; + + version (Windows) + { + if ( t.m_addr != GetCurrentThreadId() && ResumeThread( t.m_hndl ) == 0xFFFFFFFF ) + { + if ( !t.isRunning ) + { + Thread.remove( t ); + return; + } + onThreadError( "Unable to resume thread" ); + } + + if ( !t.m_lock ) + t.m_curr.tstack = t.m_curr.bstack; + t.m_reg[0 .. $] = 0; + } + else version (Darwin) + { + if ( t.m_addr != pthread_self() && thread_resume( t.m_tmach ) != KERN_SUCCESS ) + { + if ( !t.isRunning ) + { + Thread.remove( t ); + return; + } + onThreadError( "Unable to resume thread" ); + } + + if ( !t.m_lock ) + t.m_curr.tstack = t.m_curr.bstack; + t.m_reg[0 .. $] = 0; + } + else version (Posix) + { + if ( t.m_addr != pthread_self() ) + { + if ( pthread_kill( t.m_addr, resumeSignalNumber ) != 0 ) + { + if ( !t.isRunning ) + { + Thread.remove( t ); + return; + } + onThreadError( "Unable to resume thread" ); + } + } + else if ( !t.m_lock ) + { + t.m_curr.tstack = t.m_curr.bstack; + } + } +} + + +/** + * Initializes the thread module. This function must be called by the + * garbage collector on startup and before any other thread routines + * are called. + */ +extern (C) void thread_init() @nogc +{ + // NOTE: If thread_init itself performs any allocations then the thread + // routines reserved for garbage collector use may be called while + // thread_init is being processed. However, since no memory should + // exist to be scanned at this point, it is sufficient for these + // functions to detect the condition and return immediately. + + initLowlevelThreads(); + Thread.initLocks(); + + // The Android VM runtime intercepts SIGUSR1 and apparently doesn't allow + // its signal handler to run, so swap the two signals on Android, since + // thread_resumeHandler does nothing. + version (Android) thread_setGCSignals(SIGUSR2, SIGUSR1); + + version (Darwin) + { + // thread id different in forked child process + static extern(C) void initChildAfterFork() + { + auto thisThread = Thread.getThis(); + thisThread.m_addr = pthread_self(); + assert( thisThread.m_addr != thisThread.m_addr.init ); + thisThread.m_tmach = pthread_mach_thread_np( thisThread.m_addr ); + assert( thisThread.m_tmach != thisThread.m_tmach.init ); + } + pthread_atfork(null, null, &initChildAfterFork); + } + else version (Posix) + { + int status; + sigaction_t suspend = void; + sigaction_t resume = void; + + // This is a quick way to zero-initialize the structs without using + // memset or creating a link dependency on their static initializer. + (cast(byte*) &suspend)[0 .. sigaction_t.sizeof] = 0; + (cast(byte*) &resume)[0 .. sigaction_t.sizeof] = 0; + + // NOTE: SA_RESTART indicates that system calls should restart if they + // are interrupted by a signal, but this is not available on all + // Posix systems, even those that support multithreading. + static if ( __traits( compiles, SA_RESTART ) ) + suspend.sa_flags = SA_RESTART; + + suspend.sa_handler = &thread_suspendHandler; + // NOTE: We want to ignore all signals while in this handler, so fill + // sa_mask to indicate this. + status = sigfillset( &suspend.sa_mask ); + assert( status == 0 ); + + // NOTE: Since resumeSignalNumber should only be issued for threads within the + // suspend handler, we don't want this signal to trigger a + // restart. + resume.sa_flags = 0; + resume.sa_handler = &thread_resumeHandler; + // NOTE: We want to ignore all signals while in this handler, so fill + // sa_mask to indicate this. + status = sigfillset( &resume.sa_mask ); + assert( status == 0 ); + + status = sigaction( suspendSignalNumber, &suspend, null ); + assert( status == 0 ); + + status = sigaction( resumeSignalNumber, &resume, null ); + assert( status == 0 ); + + status = sem_init( &suspendCount, 0, 0 ); + assert( status == 0 ); + } + if (typeid(Thread).initializer.ptr) + _mainThreadStore[] = typeid(Thread).initializer[]; + Thread.sm_main = attachThread((cast(Thread)_mainThreadStore.ptr).__ctor()); +} + +private alias MainThreadStore = void[__traits(classInstanceSize, Thread)]; +package __gshared align(Thread.alignof) MainThreadStore _mainThreadStore; + +/** + * Terminates the thread module. No other thread routine may be called + * afterwards. + */ +extern (C) void thread_term() @nogc +{ + thread_term_tpl!(Thread)(_mainThreadStore); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Thread Entry Point and Signal Handlers +/////////////////////////////////////////////////////////////////////////////// + + +version (Windows) +{ + private + { + // + // Entry point for Windows threads + // + extern (Windows) uint thread_entryPoint( void* arg ) nothrow + { + Thread obj = cast(Thread) arg; + assert( obj ); + + obj.initDataStorage(); + + Thread.setThis(obj); + Thread.add(obj); + scope (exit) + { + Thread.remove(obj); + obj.destroyDataStorage(); + } + Thread.add(&obj.m_main); + + // NOTE: No GC allocations may occur until the stack pointers have + // been set and Thread.getThis returns a valid reference to + // this thread object (this latter condition is not strictly + // necessary on Windows but it should be followed for the + // sake of consistency). + + // TODO: Consider putting an auto exception object here (using + // alloca) forOutOfMemoryError plus something to track + // whether an exception is in-flight? + + void append( Throwable t ) + { + if ( obj.m_unhandled is null ) + obj.m_unhandled = t; + else + { + Throwable last = obj.m_unhandled; + while ( last.next !is null ) + last = last.next; + last.next = t; + } + } + + version (D_InlineAsm_X86) + { + asm nothrow @nogc { fninit; } + } + + try + { + rt_moduleTlsCtor(); + try + { + obj.run(); + } + catch ( Throwable t ) + { + append( t ); + } + rt_moduleTlsDtor(); + } + catch ( Throwable t ) + { + append( t ); + } + return 0; + } + + + HANDLE GetCurrentThreadHandle() nothrow @nogc + { + const uint DUPLICATE_SAME_ACCESS = 0x00000002; + + HANDLE curr = GetCurrentThread(), + proc = GetCurrentProcess(), + hndl; + + DuplicateHandle( proc, curr, proc, &hndl, 0, TRUE, DUPLICATE_SAME_ACCESS ); + return hndl; + } + } +} +else version (Posix) +{ + private + { + import core.stdc.errno; + import core.sys.posix.semaphore; + import core.sys.posix.stdlib; // for malloc, valloc, free, atexit + import core.sys.posix.pthread; + import core.sys.posix.signal; + import core.sys.posix.time; + + version (Darwin) + { + import core.sys.darwin.mach.thread_act; + import core.sys.darwin.pthread : pthread_mach_thread_np; + } + + // + // Entry point for POSIX threads + // + extern (C) void* thread_entryPoint( void* arg ) nothrow + { + version (Shared) + { + Thread obj = cast(Thread)(cast(void**)arg)[0]; + auto loadedLibraries = (cast(void**)arg)[1]; + .free(arg); + } + else + { + Thread obj = cast(Thread)arg; + } + assert( obj ); + + // loadedLibraries need to be inherited from parent thread + // before initilizing GC for TLS (rt_tlsgc_init) + version (GNUShared) + { + externDFunc!("gcc.sections.elf_shared.inheritLoadedLibraries", + void function(void*) @nogc nothrow)(loadedLibraries); + } + else version (Shared) + { + externDFunc!("rt.sections_elf_shared.inheritLoadedLibraries", + void function(void*) @nogc nothrow)(loadedLibraries); + } + + obj.initDataStorage(); + + atomicStore!(MemoryOrder.raw)(obj.m_isRunning, true); + Thread.setThis(obj); // allocates lazy TLS (see Issue 11981) + Thread.add(obj); // can only receive signals from here on + scope (exit) + { + Thread.remove(obj); + atomicStore!(MemoryOrder.raw)(obj.m_isRunning, false); + obj.destroyDataStorage(); + } + Thread.add(&obj.m_main); + + static extern (C) void thread_cleanupHandler( void* arg ) nothrow @nogc + { + Thread obj = cast(Thread) arg; + assert( obj ); + + // NOTE: If the thread terminated abnormally, just set it as + // not running and let thread_suspendAll remove it from + // the thread list. This is safer and is consistent + // with the Windows thread code. + atomicStore!(MemoryOrder.raw)(obj.m_isRunning,false); + } + + // NOTE: Using void to skip the initialization here relies on + // knowledge of how pthread_cleanup is implemented. It may + // not be appropriate for all platforms. However, it does + // avoid the need to link the pthread module. If any + // implementation actually requires default initialization + // then pthread_cleanup should be restructured to maintain + // the current lack of a link dependency. + static if ( __traits( compiles, pthread_cleanup ) ) + { + pthread_cleanup cleanup = void; + cleanup.push( &thread_cleanupHandler, cast(void*) obj ); + } + else static if ( __traits( compiles, pthread_cleanup_push ) ) + { + pthread_cleanup_push( &thread_cleanupHandler, cast(void*) obj ); + } + else + { + static assert( false, "Platform not supported." ); + } + + // NOTE: No GC allocations may occur until the stack pointers have + // been set and Thread.getThis returns a valid reference to + // this thread object (this latter condition is not strictly + // necessary on Windows but it should be followed for the + // sake of consistency). + + // TODO: Consider putting an auto exception object here (using + // alloca) forOutOfMemoryError plus something to track + // whether an exception is in-flight? + + void append( Throwable t ) + { + if ( obj.m_unhandled is null ) + obj.m_unhandled = t; + else + { + Throwable last = obj.m_unhandled; + while ( last.next !is null ) + last = last.next; + last.next = t; + } + } + try + { + rt_moduleTlsCtor(); + try + { + obj.run(); + } + catch ( Throwable t ) + { + append( t ); + } + rt_moduleTlsDtor(); + version (GNUShared) + { + externDFunc!("gcc.sections.elf_shared.cleanupLoadedLibraries", + void function() @nogc nothrow)(); + } + else version (Shared) + { + externDFunc!("rt.sections_elf_shared.cleanupLoadedLibraries", + void function() @nogc nothrow)(); + } + } + catch ( Throwable t ) + { + append( t ); + } + + // NOTE: Normal cleanup is handled by scope(exit). + + static if ( __traits( compiles, pthread_cleanup ) ) + { + cleanup.pop( 0 ); + } + else static if ( __traits( compiles, pthread_cleanup_push ) ) + { + pthread_cleanup_pop( 0 ); + } + + return null; + } + + + // + // Used to track the number of suspended threads + // + __gshared sem_t suspendCount; + + + extern (C) void thread_suspendHandler( int sig ) nothrow + in + { + assert( sig == suspendSignalNumber ); + } + do + { + void op(void* sp) nothrow + { + // NOTE: Since registers are being pushed and popped from the + // stack, any other stack data used by this function should + // be gone before the stack cleanup code is called below. + Thread obj = Thread.getThis(); + assert(obj !is null); + + if ( !obj.m_lock ) + { + obj.m_curr.tstack = getStackTop(); + } + + sigset_t sigres = void; + int status; + + status = sigfillset( &sigres ); + assert( status == 0 ); + + status = sigdelset( &sigres, resumeSignalNumber ); + assert( status == 0 ); + + version (FreeBSD) obj.m_suspendagain = false; + status = sem_post( &suspendCount ); + assert( status == 0 ); + + sigsuspend( &sigres ); + + if ( !obj.m_lock ) + { + obj.m_curr.tstack = obj.m_curr.bstack; + } + } + + // avoid deadlocks on FreeBSD, see Issue 13416 + version (FreeBSD) + { + auto obj = Thread.getThis(); + if (THR_IN_CRITICAL(obj.m_addr)) + { + obj.m_suspendagain = true; + if (sem_post(&suspendCount)) assert(0); + return; + } + } + + callWithStackShell(&op); + } + + + extern (C) void thread_resumeHandler( int sig ) nothrow + in + { + assert( sig == resumeSignalNumber ); + } + do + { + + } + + // HACK libthr internal (thr_private.h) macro, used to + // avoid deadlocks in signal handler, see Issue 13416 + version (FreeBSD) bool THR_IN_CRITICAL(pthread_t p) nothrow @nogc + { + import core.sys.posix.config : c_long; + import core.sys.posix.sys.types : lwpid_t; + + // If the begin of pthread would be changed in libthr (unlikely) + // we'll run into undefined behavior, compare with thr_private.h. + static struct pthread + { + c_long tid; + static struct umutex { lwpid_t owner; uint flags; uint[2] ceilings; uint[4] spare; } + umutex lock; + uint cycle; + int locklevel; + int critical_count; + // ... + } + auto priv = cast(pthread*)p; + return priv.locklevel > 0 || priv.critical_count > 0; + } + } +} +else +{ + // NOTE: This is the only place threading versions are checked. If a new + // version is added, the module code will need to be searched for + // places where version-specific code may be required. This can be + // easily accomlished by searching for 'Windows' or 'Posix'. + static assert( false, "Unknown threading implementation." ); +} + +// +// exposed by compiler runtime +// +extern (C) void rt_moduleTlsCtor(); +extern (C) void rt_moduleTlsDtor(); + + +// regression test for Issue 13416 +version (FreeBSD) unittest +{ + static void loop() + { + pthread_attr_t attr; + pthread_attr_init(&attr); + auto thr = pthread_self(); + foreach (i; 0 .. 50) + pthread_attr_get_np(thr, &attr); + pthread_attr_destroy(&attr); + } + + auto thr = new Thread(&loop).start(); + foreach (i; 0 .. 50) + { + thread_suspendAll(); + thread_resumeAll(); + } + thr.join(); +} + +version (DragonFlyBSD) unittest +{ + static void loop() + { + pthread_attr_t attr; + pthread_attr_init(&attr); + auto thr = pthread_self(); + foreach (i; 0 .. 50) + pthread_attr_get_np(thr, &attr); + pthread_attr_destroy(&attr); + } + + auto thr = new Thread(&loop).start(); + foreach (i; 0 .. 50) + { + thread_suspendAll(); + thread_resumeAll(); + } + thr.join(); +} + + +/////////////////////////////////////////////////////////////////////////////// +// lowlovel threading support +/////////////////////////////////////////////////////////////////////////////// + +private +{ + version (Windows): + // If the runtime is dynamically loaded as a DLL, there is a problem with + // threads still running when the DLL is supposed to be unloaded: + // + // - with the VC runtime starting with VS2015 (i.e. using the Universal CRT) + // a thread created with _beginthreadex increments the DLL reference count + // and decrements it when done, so that the DLL is no longer unloaded unless + // all the threads have terminated. With the DLL reference count held up + // by a thread that is only stopped by a signal from a static destructor or + // the termination of the runtime will cause the DLL to never be unloaded. + // + // - with the DigitalMars runtime and VC runtime up to VS2013, the thread + // continues to run, but crashes once the DLL is unloaded from memory as + // the code memory is no longer accessible. Stopping the threads is not possible + // from within the runtime termination as it is invoked from + // DllMain(DLL_PROCESS_DETACH) holding a lock that prevents threads from + // terminating. + // + // Solution: start a watchdog thread that keeps the DLL reference count above 0 and + // checks it periodically. If it is equal to 1 (plus the number of started threads), no + // external references to the DLL exist anymore, threads can be stopped + // and runtime termination and DLL unload can be invoked via FreeLibraryAndExitThread. + // Note: runtime termination is then performed by a different thread than at startup. + // + // Note: if the DLL is never unloaded, process termination kills all threads + // and signals their handles before unconditionally calling DllMain(DLL_PROCESS_DETACH). + + import core.sys.windows.winbase : FreeLibraryAndExitThread, GetModuleHandleExW, + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT; + import core.sys.windows.windef : HMODULE; + import core.sys.windows.dll : dll_getRefCount; + + version (CRuntime_Microsoft) + extern(C) extern __gshared ubyte msvcUsesUCRT; // from rt/msvc.d + + /// set during termination of a DLL on Windows, i.e. while executing DllMain(DLL_PROCESS_DETACH) + public __gshared bool thread_DLLProcessDetaching; + + __gshared HMODULE ll_dllModule; + __gshared ThreadID ll_dllMonitorThread; + + int ll_countLowLevelThreadsWithDLLUnloadCallback() nothrow + { + lowlevelLock.lock_nothrow(); + scope(exit) lowlevelLock.unlock_nothrow(); + + int cnt = 0; + foreach (i; 0 .. ll_nThreads) + if (ll_pThreads[i].cbDllUnload) + cnt++; + return cnt; + } + + bool ll_dllHasExternalReferences() nothrow + { + version (CRuntime_DigitalMars) + enum internalReferences = 1; // only the watchdog thread + else + int internalReferences = msvcUsesUCRT ? 1 + ll_countLowLevelThreadsWithDLLUnloadCallback() : 1; + + int refcnt = dll_getRefCount(ll_dllModule); + return refcnt > internalReferences; + } + + private void monitorDLLRefCnt() nothrow + { + // this thread keeps the DLL alive until all external references are gone + while (ll_dllHasExternalReferences()) + { + Thread.sleep(100.msecs); + } + + // the current thread will be terminated below + ll_removeThread(GetCurrentThreadId()); + + for (;;) + { + ThreadID tid; + void delegate() nothrow cbDllUnload; + { + lowlevelLock.lock_nothrow(); + scope(exit) lowlevelLock.unlock_nothrow(); + + foreach (i; 0 .. ll_nThreads) + if (ll_pThreads[i].cbDllUnload) + { + cbDllUnload = ll_pThreads[i].cbDllUnload; + tid = ll_pThreads[0].tid; + } + } + if (!cbDllUnload) + break; + cbDllUnload(); + assert(!findLowLevelThread(tid)); + } + + FreeLibraryAndExitThread(ll_dllModule, 0); + } + + int ll_getDLLRefCount() nothrow @nogc + { + if (!ll_dllModule && + !GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + cast(const(wchar)*) &ll_getDLLRefCount, &ll_dllModule)) + return -1; + return dll_getRefCount(ll_dllModule); + } + + bool ll_startDLLUnloadThread() nothrow @nogc + { + int refcnt = ll_getDLLRefCount(); + if (refcnt < 0) + return false; // not a dynamically loaded DLL + + if (ll_dllMonitorThread !is ThreadID.init) + return true; + + // if a thread is created from a DLL, the MS runtime (starting with VC2015) increments the DLL reference count + // to avoid the DLL being unloaded while the thread is still running. Mimick this behavior here for all + // runtimes not doing this + version (CRuntime_DigitalMars) + enum needRef = true; + else + bool needRef = !msvcUsesUCRT; + + if (needRef) + { + HMODULE hmod; + GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, cast(const(wchar)*) &ll_getDLLRefCount, &hmod); + } + + ll_dllMonitorThread = createLowLevelThread(() { monitorDLLRefCnt(); }); + return ll_dllMonitorThread != ThreadID.init; + } +} + +/** + * Create a thread not under control of the runtime, i.e. TLS module constructors are + * not run and the GC does not suspend it during a collection. + * + * Params: + * dg = delegate to execute in the created thread. + * stacksize = size of the stack of the created thread. The default of 0 will select the + * platform-specific default size. + * cbDllUnload = Windows only: if running in a dynamically loaded DLL, this delegate will be called + * if the DLL is supposed to be unloaded, but the thread is still running. + * The thread must be terminated via `joinLowLevelThread` by the callback. + * + * Returns: the platform specific thread ID of the new thread. If an error occurs, `ThreadID.init` + * is returned. + */ +ThreadID createLowLevelThread(void delegate() nothrow dg, uint stacksize = 0, + void delegate() nothrow cbDllUnload = null) nothrow @nogc +{ + void delegate() nothrow* context = cast(void delegate() nothrow*)malloc(dg.sizeof); + *context = dg; + + ThreadID tid; + version (Windows) + { + // the thread won't start until after the DLL is unloaded + if (thread_DLLProcessDetaching) + return ThreadID.init; + + static extern (Windows) uint thread_lowlevelEntry(void* ctx) nothrow + { + auto dg = *cast(void delegate() nothrow*)ctx; + free(ctx); + + dg(); + ll_removeThread(GetCurrentThreadId()); + return 0; + } + + // see Thread.start() for why thread is created in suspended state + HANDLE hThread = cast(HANDLE) _beginthreadex(null, stacksize, &thread_lowlevelEntry, + context, CREATE_SUSPENDED, &tid); + if (!hThread) + return ThreadID.init; + } + + lowlevelLock.lock_nothrow(); + scope(exit) lowlevelLock.unlock_nothrow(); + + ll_nThreads++; + ll_pThreads = cast(ll_ThreadData*)realloc(ll_pThreads, ll_ThreadData.sizeof * ll_nThreads); + + version (Windows) + { + ll_pThreads[ll_nThreads - 1].tid = tid; + ll_pThreads[ll_nThreads - 1].cbDllUnload = cbDllUnload; + if (ResumeThread(hThread) == -1) + onThreadError("Error resuming thread"); + CloseHandle(hThread); + + if (cbDllUnload) + ll_startDLLUnloadThread(); + } + else version (Posix) + { + static extern (C) void* thread_lowlevelEntry(void* ctx) nothrow + { + auto dg = *cast(void delegate() nothrow*)ctx; + free(ctx); + + dg(); + ll_removeThread(pthread_self()); + return null; + } + + size_t stksz = adjustStackSize(stacksize); + + pthread_attr_t attr; + + int rc; + if ((rc = pthread_attr_init(&attr)) != 0) + return ThreadID.init; + if (stksz && (rc = pthread_attr_setstacksize(&attr, stksz)) != 0) + return ThreadID.init; + if ((rc = pthread_create(&tid, &attr, &thread_lowlevelEntry, context)) != 0) + return ThreadID.init; + if ((rc = pthread_attr_destroy(&attr)) != 0) + return ThreadID.init; + + ll_pThreads[ll_nThreads - 1].tid = tid; + } + return tid; +} + +/** + * Wait for a thread created with `createLowLevelThread` to terminate. + * + * Note: In a Windows DLL, if this function is called via DllMain with + * argument DLL_PROCESS_DETACH, the thread is terminated forcefully + * without proper cleanup as a deadlock would happen otherwise. + * + * Params: + * tid = the thread ID returned by `createLowLevelThread`. + */ +void joinLowLevelThread(ThreadID tid) nothrow @nogc +{ + version (Windows) + { + HANDLE handle = OpenThreadHandle(tid); + if (!handle) + return; + + if (thread_DLLProcessDetaching) + { + // When being called from DllMain/DLL_DETACH_PROCESS, threads cannot stop + // due to the loader lock being held by the current thread. + // On the other hand, the thread must not continue to run as it will crash + // if the DLL is unloaded. The best guess is to terminate it immediately. + TerminateThread(handle, 1); + WaitForSingleObject(handle, 10); // give it some time to terminate, but don't wait indefinitely + } + else + WaitForSingleObject(handle, INFINITE); + CloseHandle(handle); + } + else version (Posix) + { + if (pthread_join(tid, null) != 0) + onThreadError("Unable to join thread"); + } +} + +nothrow @nogc unittest +{ + struct TaskWithContect + { + shared int n = 0; + void run() nothrow + { + n.atomicOp!"+="(1); + } + } + TaskWithContect task; + + ThreadID[8] tids; + for (int i = 0; i < tids.length; i++) + { + tids[i] = createLowLevelThread(&task.run); + assert(tids[i] != ThreadID.init); + } + + for (int i = 0; i < tids.length; i++) + joinLowLevelThread(tids[i]); + + assert(task.n == tids.length); +} + +version (Posix) +private size_t adjustStackSize(size_t sz) nothrow @nogc +{ + if (sz == 0) + return 0; + + // stack size must be at least PTHREAD_STACK_MIN for most platforms. + if (PTHREAD_STACK_MIN > sz) + sz = PTHREAD_STACK_MIN; + + version (CRuntime_Glibc) + { + // On glibc, TLS uses the top of the stack, so add its size to the requested size + version (GNU) + { + sz += externDFunc!("gcc.sections.elf_shared.sizeOfTLS", + size_t function() @nogc nothrow)(); + } + else + { + sz += externDFunc!("rt.sections_elf_shared.sizeOfTLS", + size_t function() @nogc nothrow)(); + } + } + + // stack size must be a multiple of PAGESIZE + sz = ((sz + PAGESIZE - 1) & ~(PAGESIZE - 1)); + + return sz; +} diff --git a/libphobos/libdruntime/core/thread/package.d b/libphobos/libdruntime/core/thread/package.d new file mode 100644 index 00000000000..71b0237c114 --- /dev/null +++ b/libphobos/libdruntime/core/thread/package.d @@ -0,0 +1,20 @@ +/** + * The thread module provides support for thread creation and management. + * + * Copyright: Copyright Sean Kelly 2005 - 2012. + * License: Distributed under the + * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). + * (See accompanying file LICENSE) + * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak + * Source: $(DRUNTIMESRC core/thread/package.d) + */ + +module core.thread; + +public import core.time; +public import core.thread.fiber; +public import core.thread.osthread; +public import core.thread.threadbase; +public import core.thread.threadgroup; +public import core.thread.types; +public import core.thread.context; diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d new file mode 100644 index 00000000000..c2c2333efe9 --- /dev/null +++ b/libphobos/libdruntime/core/thread/threadbase.d @@ -0,0 +1,1382 @@ +/** + * The threadbase module provides OS-independent code + * for thread storage and management. + * + * Copyright: Copyright Sean Kelly 2005 - 2012. + * License: Distributed under the + * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). + * (See accompanying file LICENSE) + * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak + * Source: $(DRUNTIMESRC core/thread/osthread.d) + */ + +module core.thread.threadbase; + +import core.thread.context; +import core.thread.types; +import core.time; +import core.sync.mutex; +import core.stdc.stdlib : free, realloc; + +private +{ + import core.internal.traits : externDFunc; + + // interface to rt.tlsgc + alias rt_tlsgc_init = externDFunc!("rt.tlsgc.init", void* function() nothrow @nogc); + alias rt_tlsgc_destroy = externDFunc!("rt.tlsgc.destroy", void function(void*) nothrow @nogc); + + alias ScanDg = void delegate(void* pstart, void* pend) nothrow; + alias rt_tlsgc_scan = + externDFunc!("rt.tlsgc.scan", void function(void*, scope ScanDg) nothrow); + + alias rt_tlsgc_processGCMarks = + externDFunc!("rt.tlsgc.processGCMarks", void function(void*, scope IsMarkedDg) nothrow); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Thread and Fiber Exceptions +/////////////////////////////////////////////////////////////////////////////// + + +/** + * Base class for thread exceptions. + */ +class ThreadException : Exception +{ + @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) + { + super(msg, file, line, next); + } + + @nogc @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) + { + super(msg, file, line, next); + } +} + + +/** +* Base class for thread errors to be used for function inside GC when allocations are unavailable. +*/ +class ThreadError : Error +{ + @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) + { + super(msg, file, line, next); + } + + @nogc @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) + { + super(msg, file, line, next); + } +} + +private +{ + // Handling unaligned mutexes are not supported on all platforms, so we must + // ensure that the address of all shared data are appropriately aligned. + import core.internal.traits : classInstanceAlignment; + + enum mutexAlign = classInstanceAlignment!Mutex; + enum mutexClassInstanceSize = __traits(classInstanceSize, Mutex); + + alias swapContext = externDFunc!("core.thread.osthread.swapContext", void* function(void*) nothrow @nogc); + + alias getStackBottom = externDFunc!("core.thread.osthread.getStackBottom", void* function() nothrow @nogc); + alias getStackTop = externDFunc!("core.thread.osthread.getStackTop", void* function() nothrow @nogc); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Thread +/////////////////////////////////////////////////////////////////////////////// + + +class ThreadBase +{ + /////////////////////////////////////////////////////////////////////////// + // Initialization + /////////////////////////////////////////////////////////////////////////// + + this(void function() fn, size_t sz = 0) @safe pure nothrow @nogc + in(fn) + { + this(sz); + m_call = fn; + } + + this(void delegate() dg, size_t sz = 0) @safe pure nothrow @nogc + in(dg) + { + this(sz); + m_call = dg; + } + + /** + * Cleans up any remaining resources used by this object. + */ + package bool destructBeforeDtor() nothrow @nogc + { + destroyDataStorageIfAvail(); + + bool no_context = m_addr == m_addr.init; + bool not_registered = !next && !prev && (sm_tbeg !is this); + + return (no_context || not_registered); + } + + package void tlsGCdataInit() nothrow @nogc + { + m_tlsgcdata = rt_tlsgc_init(); + } + + package void initDataStorage() nothrow + { + assert(m_curr is &m_main); + + m_main.bstack = getStackBottom(); + m_main.tstack = m_main.bstack; + tlsGCdataInit(); + } + + package void destroyDataStorage() nothrow @nogc + { + rt_tlsgc_destroy(m_tlsgcdata); + m_tlsgcdata = null; + } + + package void destroyDataStorageIfAvail() nothrow @nogc + { + if (m_tlsgcdata) + destroyDataStorage(); + } + + + /////////////////////////////////////////////////////////////////////////// + // General Actions + /////////////////////////////////////////////////////////////////////////// + + + /** + * Waits for this thread to complete. If the thread terminated as the + * result of an unhandled exception, this exception will be rethrown. + * + * Params: + * rethrow = Rethrow any unhandled exception which may have caused this + * thread to terminate. + * + * Throws: + * ThreadException if the operation fails. + * Any exception not handled by the joined thread. + * + * Returns: + * Any exception not handled by this thread if rethrow = false, null + * otherwise. + */ + abstract Throwable join(bool rethrow = true); + + + /////////////////////////////////////////////////////////////////////////// + // General Properties + /////////////////////////////////////////////////////////////////////////// + + + /** + * Gets the OS identifier for this thread. + * + * Returns: + * If the thread hasn't been started yet, returns $(LREF ThreadID)$(D.init). + * Otherwise, returns the result of $(D GetCurrentThreadId) on Windows, + * and $(D pthread_self) on POSIX. + * + * The value is unique for the current process. + */ + final @property ThreadID id() @safe @nogc + { + synchronized(this) + { + return m_addr; + } + } + + + /** + * Gets the user-readable label for this thread. + * + * Returns: + * The name of this thread. + */ + final @property string name() @safe @nogc + { + synchronized(this) + { + return m_name; + } + } + + + /** + * Sets the user-readable label for this thread. + * + * Params: + * val = The new name of this thread. + */ + final @property void name(string val) @safe @nogc + { + synchronized(this) + { + m_name = val; + } + } + + + /** + * Gets the daemon status for this thread. While the runtime will wait for + * all normal threads to complete before tearing down the process, daemon + * threads are effectively ignored and thus will not prevent the process + * from terminating. In effect, daemon threads will be terminated + * automatically by the OS when the process exits. + * + * Returns: + * true if this is a daemon thread. + */ + final @property bool isDaemon() @safe @nogc + { + synchronized(this) + { + return m_isDaemon; + } + } + + + /** + * Sets the daemon status for this thread. While the runtime will wait for + * all normal threads to complete before tearing down the process, daemon + * threads are effectively ignored and thus will not prevent the process + * from terminating. In effect, daemon threads will be terminated + * automatically by the OS when the process exits. + * + * Params: + * val = The new daemon status for this thread. + */ + final @property void isDaemon(bool val) @safe @nogc + { + synchronized(this) + { + m_isDaemon = val; + } + } + + /** + * Tests whether this thread is the main thread, i.e. the thread + * that initialized the runtime + * + * Returns: + * true if the thread is the main thread + */ + final @property bool isMainThread() nothrow @nogc + { + return this is sm_main; + } + + /** + * Tests whether this thread is running. + * + * Returns: + * true if the thread is running, false if not. + */ + @property bool isRunning() nothrow @nogc + { + if (m_addr == m_addr.init) + return false; + + return true; + } + + + /////////////////////////////////////////////////////////////////////////// + // Thread Accessors + /////////////////////////////////////////////////////////////////////////// + + /** + * Provides a reference to the calling thread. + * + * Returns: + * The thread object representing the calling thread. The result of + * deleting this object is undefined. If the current thread is not + * attached to the runtime, a null reference is returned. + */ + static ThreadBase getThis() @safe nothrow @nogc + { + // NOTE: This function may not be called until thread_init has + // completed. See thread_suspendAll for more information + // on why this might occur. + return sm_this; + } + + + /** + * Provides a list of all threads currently being tracked by the system. + * Note that threads in the returned array might no longer run (see + * $(D ThreadBase.)$(LREF isRunning)). + * + * Returns: + * An array containing references to all threads currently being + * tracked by the system. The result of deleting any contained + * objects is undefined. + */ + static ThreadBase[] getAll() + { + static void resize(ref ThreadBase[] buf, size_t nlen) + { + buf.length = nlen; + } + return getAllImpl!resize(); + } + + + /** + * Operates on all threads currently being tracked by the system. The + * result of deleting any Thread object is undefined. + * Note that threads passed to the callback might no longer run (see + * $(D ThreadBase.)$(LREF isRunning)). + * + * Params: + * dg = The supplied code as a delegate. + * + * Returns: + * Zero if all elemented are visited, nonzero if not. + */ + static int opApply(scope int delegate(ref ThreadBase) dg) + { + static void resize(ref ThreadBase[] buf, size_t nlen) + { + import core.exception: onOutOfMemoryError; + + auto newBuf = cast(ThreadBase*)realloc(buf.ptr, nlen * size_t.sizeof); + if (newBuf is null) onOutOfMemoryError(); + buf = newBuf[0 .. nlen]; + } + auto buf = getAllImpl!resize; + scope(exit) if (buf.ptr) free(buf.ptr); + + foreach (t; buf) + { + if (auto res = dg(t)) + return res; + } + return 0; + } + + private static ThreadBase[] getAllImpl(alias resize)() + { + import core.atomic; + + ThreadBase[] buf; + while (true) + { + immutable len = atomicLoad!(MemoryOrder.raw)(*cast(shared)&sm_tlen); + resize(buf, len); + assert(buf.length == len); + synchronized (slock) + { + if (len == sm_tlen) + { + size_t pos; + for (ThreadBase t = sm_tbeg; t; t = t.next) + buf[pos++] = t; + return buf; + } + } + } + } + + /////////////////////////////////////////////////////////////////////////// + // Actions on Calling Thread + /////////////////////////////////////////////////////////////////////////// + + /** + * Forces a context switch to occur away from the calling thread. + */ + private static void yield() @nogc nothrow + { + thread_yield(); + } + + /////////////////////////////////////////////////////////////////////////// + // Stuff That Should Go Away + /////////////////////////////////////////////////////////////////////////// + + + // + // Initializes a thread object which has no associated executable function. + // This is used for the main thread initialized in thread_init(). + // + package this(size_t sz = 0) @safe pure nothrow @nogc + { + m_sz = sz; + m_curr = &m_main; + } + + // + // Thread entry point. Invokes the function or delegate passed on + // construction (if any). + // + package final void run() + { + m_call(); + } + +package: + + // + // Local storage + // + static ThreadBase sm_this; + + + // + // Main process thread + // + __gshared ThreadBase sm_main; + + + // + // Standard thread data + // + ThreadID m_addr; + Callable m_call; + string m_name; + size_t m_sz; + bool m_isDaemon; + bool m_isInCriticalRegion; + Throwable m_unhandled; + + /////////////////////////////////////////////////////////////////////////// + // Storage of Active Thread + /////////////////////////////////////////////////////////////////////////// + + + // + // Sets a thread-local reference to the current thread object. + // + package static void setThis(ThreadBase t) nothrow @nogc + { + sm_this = t; + } + +package(core.thread): + + StackContext m_main; + StackContext* m_curr; + bool m_lock; + private void* m_tlsgcdata; + + /////////////////////////////////////////////////////////////////////////// + // Thread Context and GC Scanning Support + /////////////////////////////////////////////////////////////////////////// + + + final void pushContext(StackContext* c) nothrow @nogc + in + { + assert(!c.within); + } + do + { + m_curr.ehContext = swapContext(c.ehContext); + c.within = m_curr; + m_curr = c; + } + + + final void popContext() nothrow @nogc + in + { + assert(m_curr && m_curr.within); + } + do + { + StackContext* c = m_curr; + m_curr = c.within; + c.ehContext = swapContext(m_curr.ehContext); + c.within = null; + } + + private final StackContext* topContext() nothrow @nogc + in(m_curr) + { + return m_curr; + } + + +package(core.thread): + /////////////////////////////////////////////////////////////////////////// + // GC Scanning Support + /////////////////////////////////////////////////////////////////////////// + + + // NOTE: The GC scanning process works like so: + // + // 1. Suspend all threads. + // 2. Scan the stacks of all suspended threads for roots. + // 3. Resume all threads. + // + // Step 1 and 3 require a list of all threads in the system, while + // step 2 requires a list of all thread stacks (each represented by + // a Context struct). Traditionally, there was one stack per thread + // and the Context structs were not necessary. However, Fibers have + // changed things so that each thread has its own 'main' stack plus + // an arbitrary number of nested stacks (normally referenced via + // m_curr). Also, there may be 'free-floating' stacks in the system, + // which are Fibers that are not currently executing on any specific + // thread but are still being processed and still contain valid + // roots. + // + // To support all of this, the Context struct has been created to + // represent a stack range, and a global list of Context structs has + // been added to enable scanning of these stack ranges. The lifetime + // (and presence in the Context list) of a thread's 'main' stack will + // be equivalent to the thread's lifetime. So the Ccontext will be + // added to the list on thread entry, and removed from the list on + // thread exit (which is essentially the same as the presence of a + // Thread object in its own global list). The lifetime of a Fiber's + // context, however, will be tied to the lifetime of the Fiber object + // itself, and Fibers are expected to add/remove their Context struct + // on construction/deletion. + + + // + // All use of the global thread lists/array should synchronize on this lock. + // + // Careful as the GC acquires this lock after the GC lock to suspend all + // threads any GC usage with slock held can result in a deadlock through + // lock order inversion. + @property static Mutex slock() nothrow @nogc + { + return cast(Mutex)_slock.ptr; + } + + @property static Mutex criticalRegionLock() nothrow @nogc + { + return cast(Mutex)_criticalRegionLock.ptr; + } + + __gshared align(mutexAlign) void[mutexClassInstanceSize] _slock; + __gshared align(mutexAlign) void[mutexClassInstanceSize] _criticalRegionLock; + + static void initLocks() @nogc + { + _slock[] = typeid(Mutex).initializer[]; + (cast(Mutex)_slock.ptr).__ctor(); + + _criticalRegionLock[] = typeid(Mutex).initializer[]; + (cast(Mutex)_criticalRegionLock.ptr).__ctor(); + } + + static void termLocks() @nogc + { + (cast(Mutex)_slock.ptr).__dtor(); + (cast(Mutex)_criticalRegionLock.ptr).__dtor(); + } + + __gshared StackContext* sm_cbeg; + + __gshared ThreadBase sm_tbeg; + __gshared size_t sm_tlen; + + // can't use core.internal.util.array in public code + __gshared ThreadBase* pAboutToStart; + __gshared size_t nAboutToStart; + + // + // Used for ordering threads in the global thread list. + // + ThreadBase prev; + ThreadBase next; + + + /////////////////////////////////////////////////////////////////////////// + // Global Context List Operations + /////////////////////////////////////////////////////////////////////////// + + + // + // Add a context to the global context list. + // + static void add(StackContext* c) nothrow @nogc + in + { + assert(c); + assert(!c.next && !c.prev); + } + do + { + slock.lock_nothrow(); + scope(exit) slock.unlock_nothrow(); + assert(!suspendDepth); // must be 0 b/c it's only set with slock held + + if (sm_cbeg) + { + c.next = sm_cbeg; + sm_cbeg.prev = c; + } + sm_cbeg = c; + } + + // + // Remove a context from the global context list. + // + // This assumes slock being acquired. This isn't done here to + // avoid double locking when called from remove(Thread) + static void remove(StackContext* c) nothrow @nogc + in + { + assert(c); + assert(c.next || c.prev); + } + do + { + if (c.prev) + c.prev.next = c.next; + if (c.next) + c.next.prev = c.prev; + if (sm_cbeg == c) + sm_cbeg = c.next; + // NOTE: Don't null out c.next or c.prev because opApply currently + // follows c.next after removing a node. This could be easily + // addressed by simply returning the next node from this + // function, however, a context should never be re-added to the + // list anyway and having next and prev be non-null is a good way + // to ensure that. + } + + + /////////////////////////////////////////////////////////////////////////// + // Global Thread List Operations + /////////////////////////////////////////////////////////////////////////// + + + // + // Add a thread to the global thread list. + // + static void add(ThreadBase t, bool rmAboutToStart = true) nothrow @nogc + in + { + assert(t); + assert(!t.next && !t.prev); + } + do + { + slock.lock_nothrow(); + scope(exit) slock.unlock_nothrow(); + assert(t.isRunning); // check this with slock to ensure pthread_create already returned + assert(!suspendDepth); // must be 0 b/c it's only set with slock held + + if (rmAboutToStart) + { + size_t idx = -1; + foreach (i, thr; pAboutToStart[0 .. nAboutToStart]) + { + if (thr is t) + { + idx = i; + break; + } + } + assert(idx != -1); + import core.stdc.string : memmove; + memmove(pAboutToStart + idx, pAboutToStart + idx + 1, size_t.sizeof * (nAboutToStart - idx - 1)); + pAboutToStart = + cast(ThreadBase*)realloc(pAboutToStart, size_t.sizeof * --nAboutToStart); + } + + if (sm_tbeg) + { + t.next = sm_tbeg; + sm_tbeg.prev = t; + } + sm_tbeg = t; + ++sm_tlen; + } + + + // + // Remove a thread from the global thread list. + // + static void remove(ThreadBase t) nothrow @nogc + in + { + assert(t); + } + do + { + // Thread was already removed earlier, might happen b/c of thread_detachInstance + if (!t.next && !t.prev && (sm_tbeg !is t)) + return; + + slock.lock_nothrow(); + { + // NOTE: When a thread is removed from the global thread list its + // main context is invalid and should be removed as well. + // It is possible that t.m_curr could reference more + // than just the main context if the thread exited abnormally + // (if it was terminated), but we must assume that the user + // retains a reference to them and that they may be re-used + // elsewhere. Therefore, it is the responsibility of any + // object that creates contexts to clean them up properly + // when it is done with them. + remove(&t.m_main); + + if (t.prev) + t.prev.next = t.next; + if (t.next) + t.next.prev = t.prev; + if (sm_tbeg is t) + sm_tbeg = t.next; + t.prev = t.next = null; + --sm_tlen; + } + // NOTE: Don't null out t.next or t.prev because opApply currently + // follows t.next after removing a node. This could be easily + // addressed by simply returning the next node from this + // function, however, a thread should never be re-added to the + // list anyway and having next and prev be non-null is a good way + // to ensure that. + slock.unlock_nothrow(); + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// GC Support Routines +/////////////////////////////////////////////////////////////////////////////// + +private alias attachThread = externDFunc!("core.thread.osthread.attachThread", ThreadBase function(ThreadBase) @nogc nothrow); + +extern (C) void _d_monitordelete_nogc(Object h) @nogc; + +/** + * Terminates the thread module. No other thread routine may be called + * afterwards. + */ +package void thread_term_tpl(ThreadT, MainThreadStore)(ref MainThreadStore _mainThreadStore) @nogc +{ + assert(_mainThreadStore.ptr is cast(void*) ThreadBase.sm_main); + + // destruct manually as object.destroy is not @nogc + (cast(ThreadT) cast(void*) ThreadBase.sm_main).__dtor(); + _d_monitordelete_nogc(ThreadBase.sm_main); + if (typeid(ThreadT).initializer.ptr) + _mainThreadStore[] = typeid(ThreadT).initializer[]; + else + (cast(ubyte[])_mainThreadStore)[] = 0; + ThreadBase.sm_main = null; + + assert(ThreadBase.sm_tbeg && ThreadBase.sm_tlen == 1); + assert(!ThreadBase.nAboutToStart); + if (ThreadBase.pAboutToStart) // in case realloc(p, 0) doesn't return null + { + free(ThreadBase.pAboutToStart); + ThreadBase.pAboutToStart = null; + } + ThreadBase.termLocks(); + termLowlevelThreads(); +} + + +/** + * + */ +extern (C) bool thread_isMainThread() nothrow @nogc +{ + return ThreadBase.getThis() is ThreadBase.sm_main; +} + + +/** + * Registers the calling thread for use with the D Runtime. If this routine + * is called for a thread which is already registered, no action is performed. + * + * NOTE: This routine does not run thread-local static constructors when called. + * If full functionality as a D thread is desired, the following function + * must be called after thread_attachThis: + * + * extern (C) void rt_moduleTlsCtor(); + */ +package ThreadT thread_attachThis_tpl(ThreadT)() +{ + if (auto t = ThreadT.getThis()) + return t; + + return cast(ThreadT) attachThread(new ThreadT()); +} + + +/** + * Deregisters the calling thread from use with the runtime. If this routine + * is called for a thread which is not registered, the result is undefined. + * + * NOTE: This routine does not run thread-local static destructors when called. + * If full functionality as a D thread is desired, the following function + * must be called after thread_detachThis, particularly if the thread is + * being detached at some indeterminate time before program termination: + * + * $(D extern(C) void rt_moduleTlsDtor();) + */ +extern (C) void thread_detachThis() nothrow @nogc +{ + if (auto t = ThreadBase.getThis()) + ThreadBase.remove(t); +} + + +/** + * Deregisters the given thread from use with the runtime. If this routine + * is called for a thread which is not registered, the result is undefined. + * + * NOTE: This routine does not run thread-local static destructors when called. + * If full functionality as a D thread is desired, the following function + * must be called by the detached thread, particularly if the thread is + * being detached at some indeterminate time before program termination: + * + * $(D extern(C) void rt_moduleTlsDtor();) + */ +extern (C) void thread_detachByAddr(ThreadID addr) +{ + if (auto t = thread_findByAddr(addr)) + ThreadBase.remove(t); +} + + +/// ditto +extern (C) void thread_detachInstance(ThreadBase t) nothrow @nogc +{ + ThreadBase.remove(t); +} + + +/** + * Search the list of all threads for a thread with the given thread identifier. + * + * Params: + * addr = The thread identifier to search for. + * Returns: + * The thread object associated with the thread identifier, null if not found. + */ +static ThreadBase thread_findByAddr(ThreadID addr) +{ + ThreadBase.slock.lock_nothrow(); + scope(exit) ThreadBase.slock.unlock_nothrow(); + + // also return just spawned thread so that + // DLL_THREAD_ATTACH knows it's a D thread + foreach (t; ThreadBase.pAboutToStart[0 .. ThreadBase.nAboutToStart]) + if (t.m_addr == addr) + return t; + + foreach (t; ThreadBase) + if (t.m_addr == addr) + return t; + + return null; +} + + +/** + * Sets the current thread to a specific reference. Only to be used + * when dealing with externally-created threads (in e.g. C code). + * The primary use of this function is when ThreadBase.getThis() must + * return a sensible value in, for example, TLS destructors. In + * other words, don't touch this unless you know what you're doing. + * + * Params: + * t = A reference to the current thread. May be null. + */ +extern (C) void thread_setThis(ThreadBase t) nothrow @nogc +{ + ThreadBase.setThis(t); +} + + +/** + * Joins all non-daemon threads that are currently running. This is done by + * performing successive scans through the thread list until a scan consists + * of only daemon threads. + */ +extern (C) void thread_joinAll() +{ + Lagain: + ThreadBase.slock.lock_nothrow(); + // wait for just spawned threads + if (ThreadBase.nAboutToStart) + { + ThreadBase.slock.unlock_nothrow(); + ThreadBase.yield(); + goto Lagain; + } + + // join all non-daemon threads, the main thread is also a daemon + auto t = ThreadBase.sm_tbeg; + while (t) + { + if (!t.isRunning) + { + auto tn = t.next; + ThreadBase.remove(t); + t = tn; + } + else if (t.isDaemon) + { + t = t.next; + } + else + { + ThreadBase.slock.unlock_nothrow(); + t.join(); // might rethrow + goto Lagain; // must restart iteration b/c of unlock + } + } + ThreadBase.slock.unlock_nothrow(); +} + + +/** + * Performs intermediate shutdown of the thread module. + */ +shared static ~this() +{ + // NOTE: The functionality related to garbage collection must be minimally + // operable after this dtor completes. Therefore, only minimal + // cleanup may occur. + auto t = ThreadBase.sm_tbeg; + while (t) + { + auto tn = t.next; + if (!t.isRunning) + ThreadBase.remove(t); + t = tn; + } +} + +// Used for needLock below. +package __gshared bool multiThreadedFlag = false; + +// Used for suspendAll/resumeAll below. +package __gshared uint suspendDepth = 0; + +private alias resume = externDFunc!("core.thread.osthread.resume", void function(ThreadBase) nothrow @nogc); + +/** + * Resume all threads but the calling thread for "stop the world" garbage + * collection runs. This function must be called once for each preceding + * call to thread_suspendAll before the threads are actually resumed. + * + * In: + * This routine must be preceded by a call to thread_suspendAll. + * + * Throws: + * ThreadError if the resume operation fails for a running thread. + */ +extern (C) void thread_resumeAll() nothrow +in +{ + assert(suspendDepth > 0); +} +do +{ + // NOTE: See thread_suspendAll for the logic behind this. + if (!multiThreadedFlag && ThreadBase.sm_tbeg) + { + if (--suspendDepth == 0) + resume(ThreadBase.getThis()); + return; + } + + scope(exit) ThreadBase.slock.unlock_nothrow(); + { + if (--suspendDepth > 0) + return; + + for (ThreadBase t = ThreadBase.sm_tbeg; t; t = t.next) + { + // NOTE: We do not need to care about critical regions at all + // here. thread_suspendAll takes care of everything. + resume(t); + } + } +} + +/** + * Indicates the kind of scan being performed by $(D thread_scanAllType). + */ +enum ScanType +{ + stack, /// The stack and/or registers are being scanned. + tls, /// TLS data is being scanned. +} + +alias ScanAllThreadsFn = void delegate(void*, void*) nothrow; /// The scanning function. +alias ScanAllThreadsTypeFn = void delegate(ScanType, void*, void*) nothrow; /// ditto + +/** + * The main entry point for garbage collection. The supplied delegate + * will be passed ranges representing both stack and register values. + * + * Params: + * scan = The scanner function. It should scan from p1 through p2 - 1. + * + * In: + * This routine must be preceded by a call to thread_suspendAll. + */ +extern (C) void thread_scanAllType(scope ScanAllThreadsTypeFn scan) nothrow +in +{ + assert(suspendDepth > 0); +} +do +{ + callWithStackShell(sp => scanAllTypeImpl(scan, sp)); +} + +package alias callWithStackShellDg = void delegate(void* sp) nothrow; +private alias callWithStackShell = externDFunc!("core.thread.osthread.callWithStackShell", void function(scope callWithStackShellDg) nothrow); + +private void scanAllTypeImpl(scope ScanAllThreadsTypeFn scan, void* curStackTop) nothrow +{ + ThreadBase thisThread = null; + void* oldStackTop = null; + + if (ThreadBase.sm_tbeg) + { + thisThread = ThreadBase.getThis(); + if (!thisThread.m_lock) + { + oldStackTop = thisThread.m_curr.tstack; + thisThread.m_curr.tstack = curStackTop; + } + } + + scope(exit) + { + if (ThreadBase.sm_tbeg) + { + if (!thisThread.m_lock) + { + thisThread.m_curr.tstack = oldStackTop; + } + } + } + + // NOTE: Synchronizing on ThreadBase.slock is not needed because this + // function may only be called after all other threads have + // been suspended from within the same lock. + if (ThreadBase.nAboutToStart) + scan(ScanType.stack, ThreadBase.pAboutToStart, ThreadBase.pAboutToStart + ThreadBase.nAboutToStart); + + for (StackContext* c = ThreadBase.sm_cbeg; c; c = c.next) + { + static if (isStackGrowingDown) + { + assert(c.tstack <= c.bstack, "stack bottom can't be less than top"); + + // NOTE: We can't index past the bottom of the stack + // so don't do the "+1" if isStackGrowingDown. + if (c.tstack && c.tstack < c.bstack) + scan(ScanType.stack, c.tstack, c.bstack); + } + else + { + assert(c.bstack <= c.tstack, "stack top can't be less than bottom"); + + if (c.bstack && c.bstack < c.tstack) + scan(ScanType.stack, c.bstack, c.tstack + 1); + } + } + + for (ThreadBase t = ThreadBase.sm_tbeg; t; t = t.next) + { + version (Windows) + { + // Ideally, we'd pass ScanType.regs or something like that, but this + // would make portability annoying because it only makes sense on Windows. + scanWindowsOnly(scan, t); + } + + if (t.m_tlsgcdata !is null) + rt_tlsgc_scan(t.m_tlsgcdata, (p1, p2) => scan(ScanType.tls, p1, p2)); + } +} + +version (Windows) +{ + // Currently scanWindowsOnly can't be handled properly by externDFunc + // https://github.com/dlang/druntime/pull/3135#issuecomment-643673218 + pragma(mangle, "_D4core6thread8osthread15scanWindowsOnlyFNbMDFNbEQBvQBt10threadbase8ScanTypePvQcZvCQDdQDbQBi10ThreadBaseZv") + private extern (D) void scanWindowsOnly(scope ScanAllThreadsTypeFn scan, ThreadBase) nothrow; +} + +/** + * The main entry point for garbage collection. The supplied delegate + * will be passed ranges representing both stack and register values. + * + * Params: + * scan = The scanner function. It should scan from p1 through p2 - 1. + * + * In: + * This routine must be preceded by a call to thread_suspendAll. + */ +extern (C) void thread_scanAll(scope ScanAllThreadsFn scan) nothrow +{ + thread_scanAllType((type, p1, p2) => scan(p1, p2)); +} + +private alias thread_yield = externDFunc!("core.thread.osthread.thread_yield", void function() @nogc nothrow); + +/** + * Signals that the code following this call is a critical region. Any code in + * this region must finish running before the calling thread can be suspended + * by a call to thread_suspendAll. + * + * This function is, in particular, meant to help maintain garbage collector + * invariants when a lock is not used. + * + * A critical region is exited with thread_exitCriticalRegion. + * + * $(RED Warning): + * Using critical regions is extremely error-prone. For instance, using locks + * inside a critical region can easily result in a deadlock when another thread + * holding the lock already got suspended. + * + * The term and concept of a 'critical region' comes from + * $(LINK2 https://github.com/mono/mono/blob/521f4a198e442573c400835ef19bbb36b60b0ebb/mono/metadata/sgen-gc.h#L925, Mono's SGen garbage collector). + * + * In: + * The calling thread must be attached to the runtime. + */ +extern (C) void thread_enterCriticalRegion() @nogc +in +{ + assert(ThreadBase.getThis()); +} +do +{ + synchronized (ThreadBase.criticalRegionLock) + ThreadBase.getThis().m_isInCriticalRegion = true; +} + + +/** + * Signals that the calling thread is no longer in a critical region. Following + * a call to this function, the thread can once again be suspended. + * + * In: + * The calling thread must be attached to the runtime. + */ +extern (C) void thread_exitCriticalRegion() @nogc +in +{ + assert(ThreadBase.getThis()); +} +do +{ + synchronized (ThreadBase.criticalRegionLock) + ThreadBase.getThis().m_isInCriticalRegion = false; +} + + +/** + * Returns true if the current thread is in a critical region; otherwise, false. + * + * In: + * The calling thread must be attached to the runtime. + */ +extern (C) bool thread_inCriticalRegion() @nogc +in +{ + assert(ThreadBase.getThis()); +} +do +{ + synchronized (ThreadBase.criticalRegionLock) + return ThreadBase.getThis().m_isInCriticalRegion; +} + + +/** +* A callback for thread errors in D during collections. Since an allocation is not possible +* a preallocated ThreadError will be used as the Error instance +* +* Returns: +* never returns +* Throws: +* ThreadError. +*/ +package void onThreadError(string msg) nothrow @nogc +{ + __gshared ThreadError error = new ThreadError(null); + error.msg = msg; + error.next = null; + import core.exception : SuppressTraceInfo; + error.info = SuppressTraceInfo.instance; + throw error; +} + +unittest +{ + assert(!thread_inCriticalRegion()); + + { + thread_enterCriticalRegion(); + + scope (exit) + thread_exitCriticalRegion(); + + assert(thread_inCriticalRegion()); + } + + assert(!thread_inCriticalRegion()); +} + + +/** + * Indicates whether an address has been marked by the GC. + */ +enum IsMarked : int +{ + no, /// Address is not marked. + yes, /// Address is marked. + unknown, /// Address is not managed by the GC. +} + +alias IsMarkedDg = int delegate(void* addr) nothrow; /// The isMarked callback function. + +/** + * This routine allows the runtime to process any special per-thread handling + * for the GC. This is needed for taking into account any memory that is + * referenced by non-scanned pointers but is about to be freed. That currently + * means the array append cache. + * + * Params: + * isMarked = The function used to check if $(D addr) is marked. + * + * In: + * This routine must be called just prior to resuming all threads. + */ +extern(C) void thread_processGCMarks(scope IsMarkedDg isMarked) nothrow +{ + for (ThreadBase t = ThreadBase.sm_tbeg; t; t = t.next) + { + /* Can be null if collection was triggered between adding a + * thread and calling rt_tlsgc_init. + */ + if (t.m_tlsgcdata !is null) + rt_tlsgc_processGCMarks(t.m_tlsgcdata, isMarked); + } +} + + +/** + * Returns the stack top of the currently active stack within the calling + * thread. + * + * In: + * The calling thread must be attached to the runtime. + * + * Returns: + * The address of the stack top. + */ +extern (C) void* thread_stackTop() nothrow @nogc +in +{ + // Not strictly required, but it gives us more flexibility. + assert(ThreadBase.getThis()); +} +do +{ + return getStackTop(); +} + + +/** + * Returns the stack bottom of the currently active stack within the calling + * thread. + * + * In: + * The calling thread must be attached to the runtime. + * + * Returns: + * The address of the stack bottom. + */ +extern (C) void* thread_stackBottom() nothrow @nogc +in (ThreadBase.getThis()) +{ + return ThreadBase.getThis().topContext().bstack; +} + + +/////////////////////////////////////////////////////////////////////////////// +// lowlovel threading support +/////////////////////////////////////////////////////////////////////////////// +package +{ + __gshared size_t ll_nThreads; + __gshared ll_ThreadData* ll_pThreads; + + __gshared align(mutexAlign) void[mutexClassInstanceSize] ll_lock; + + @property Mutex lowlevelLock() nothrow @nogc + { + return cast(Mutex)ll_lock.ptr; + } + + void initLowlevelThreads() @nogc + { + ll_lock[] = typeid(Mutex).initializer[]; + lowlevelLock.__ctor(); + } + + void termLowlevelThreads() @nogc + { + lowlevelLock.__dtor(); + } + + void ll_removeThread(ThreadID tid) nothrow @nogc + { + lowlevelLock.lock_nothrow(); + scope(exit) lowlevelLock.unlock_nothrow(); + + foreach (i; 0 .. ll_nThreads) + { + if (tid is ll_pThreads[i].tid) + { + import core.stdc.string : memmove; + memmove(ll_pThreads + i, ll_pThreads + i + 1, ll_ThreadData.sizeof * (ll_nThreads - i - 1)); + --ll_nThreads; + // no need to minimize, next add will do + break; + } + } + } +} + +/** + * Check whether a thread was created by `createLowLevelThread`. + * + * Params: + * tid = the platform specific thread ID. + * + * Returns: `true` if the thread was created by `createLowLevelThread` and is still running. + */ +bool findLowLevelThread(ThreadID tid) nothrow @nogc +{ + lowlevelLock.lock_nothrow(); + scope(exit) lowlevelLock.unlock_nothrow(); + + foreach (i; 0 .. ll_nThreads) + if (tid is ll_pThreads[i].tid) + return true; + return false; +} diff --git a/libphobos/libdruntime/core/thread/threadgroup.d b/libphobos/libdruntime/core/thread/threadgroup.d new file mode 100644 index 00000000000..d00ce05854d --- /dev/null +++ b/libphobos/libdruntime/core/thread/threadgroup.d @@ -0,0 +1,162 @@ +/** + * The osthread module provides types used in threads modules. + * + * Copyright: Copyright Sean Kelly 2005 - 2012. + * License: Distributed under the + * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). + * (See accompanying file LICENSE) + * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak + * Source: $(DRUNTIMESRC core/thread/osthread.d) + */ + +module core.thread.threadgroup; + +import core.thread.osthread; + + +/** + * This class is intended to simplify certain common programming techniques. + */ +class ThreadGroup +{ + /** + * Creates and starts a new Thread object that executes fn and adds it to + * the list of tracked threads. + * + * Params: + * fn = The thread function. + * + * Returns: + * A reference to the newly created thread. + */ + final Thread create(void function() fn) + { + Thread t = new Thread(fn).start(); + + synchronized(this) + { + m_all[t] = t; + } + return t; + } + + + /** + * Creates and starts a new Thread object that executes dg and adds it to + * the list of tracked threads. + * + * Params: + * dg = The thread function. + * + * Returns: + * A reference to the newly created thread. + */ + final Thread create(void delegate() dg) + { + Thread t = new Thread(dg).start(); + + synchronized(this) + { + m_all[t] = t; + } + return t; + } + + + /** + * Add t to the list of tracked threads if it is not already being tracked. + * + * Params: + * t = The thread to add. + * + * In: + * t must not be null. + */ + final void add(Thread t) + in + { + assert(t); + } + do + { + synchronized(this) + { + m_all[t] = t; + } + } + + + /** + * Removes t from the list of tracked threads. No operation will be + * performed if t is not currently being tracked by this object. + * + * Params: + * t = The thread to remove. + * + * In: + * t must not be null. + */ + final void remove(Thread t) + in + { + assert(t); + } + do + { + synchronized(this) + { + m_all.remove(t); + } + } + + + /** + * Operates on all threads currently tracked by this object. + */ + final int opApply(scope int delegate(ref Thread) dg) + { + synchronized(this) + { + int ret = 0; + + // NOTE: This loop relies on the knowledge that m_all uses the + // Thread object for both the key and the mapped value. + foreach (Thread t; m_all.keys) + { + ret = dg(t); + if (ret) + break; + } + return ret; + } + } + + + /** + * Iteratively joins all tracked threads. This function will block add, + * remove, and opApply until it completes. + * + * Params: + * rethrow = Rethrow any unhandled exception which may have caused the + * current thread to terminate. + * + * Throws: + * Any exception not handled by the joined threads. + */ + final void joinAll(bool rethrow = true) + { + synchronized(this) + { + // NOTE: This loop relies on the knowledge that m_all uses the + // Thread object for both the key and the mapped value. + foreach (Thread t; m_all.keys) + { + t.join(rethrow); + } + } + } + + +private: + Thread[Thread] m_all; +} diff --git a/libphobos/libdruntime/core/thread/types.d b/libphobos/libdruntime/core/thread/types.d new file mode 100644 index 00000000000..e50399a59d9 --- /dev/null +++ b/libphobos/libdruntime/core/thread/types.d @@ -0,0 +1,77 @@ +/** + * This module provides types and constants used in thread package. + * + * Copyright: Copyright Sean Kelly 2005 - 2012. + * License: Distributed under the + * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). + * (See accompanying file LICENSE) + * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak + * Source: $(DRUNTIMESRC core/thread/osthread.d) + */ + +module core.thread.types; + +/** + * Represents the ID of a thread, as returned by $(D Thread.)$(LREF id). + * The exact type varies from platform to platform. + */ +version (Windows) + alias ThreadID = uint; +else +version (Posix) +{ + import core.sys.posix.pthread; + + alias ThreadID = pthread_t; +} + +struct ll_ThreadData +{ + ThreadID tid; + version (Windows) + void delegate() nothrow cbDllUnload; +} + +version (GNU) +{ + version (GNU_StackGrowsDown) + enum isStackGrowingDown = true; + else + enum isStackGrowingDown = false; +} +else +{ + // this should be true for most architectures + enum isStackGrowingDown = true; +} + +package +{ + static immutable size_t PAGESIZE; + version (Posix) static immutable size_t PTHREAD_STACK_MIN; +} + +shared static this() +{ + version (Windows) + { + import core.sys.windows.winbase; + + SYSTEM_INFO info; + GetSystemInfo(&info); + + PAGESIZE = info.dwPageSize; + assert(PAGESIZE < int.max); + } + else version (Posix) + { + import core.sys.posix.unistd; + + PAGESIZE = cast(size_t)sysconf(_SC_PAGESIZE); + PTHREAD_STACK_MIN = cast(size_t)sysconf(_SC_THREAD_STACK_MIN); + } + else + { + static assert(0, "unimplemented"); + } +} diff --git a/libphobos/libdruntime/gcc/sections/elf_shared.d b/libphobos/libdruntime/gcc/sections/elf_shared.d index 427759a4f94..5b0fad9543b 100644 --- a/libphobos/libdruntime/gcc/sections/elf_shared.d +++ b/libphobos/libdruntime/gcc/sections/elf_shared.d @@ -238,6 +238,15 @@ version (Shared) } } + size_t sizeOfTLS() nothrow @nogc + { + auto tdsos = initTLSRanges(); + size_t sum; + foreach (ref tdso; *tdsos) + sum += tdso._tlsRange.length; + return sum; + } + // interface for core.thread to inherit loaded libraries void* pinLoadedLibraries() nothrow @nogc { @@ -339,6 +348,15 @@ else dg(rng.ptr, rng.ptr + rng.length); } } + + size_t sizeOfTLS() nothrow @nogc + { + auto rngs = initTLSRanges(); + size_t sum; + foreach (rng; *rngs) + sum += rng.length; + return sum; + } } private: diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index d7588dccbed..04d54575a5b 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -16,22 +16,8 @@ private extern (C) void rt_finalize(void *data, bool det=true); } -// NOTE: For some reason, this declaration method doesn't work -// in this particular file (and this file only). It must -// be a DMD thing. -//alias typeof(int.sizeof) size_t; -//alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t; - -version (D_LP64) -{ - alias size_t = ulong; - alias ptrdiff_t = long; -} -else -{ - alias size_t = uint; - alias ptrdiff_t = int; -} +alias size_t = typeof(int.sizeof); +alias ptrdiff_t = typeof(cast(void*)0 - cast(void*)0); alias sizediff_t = ptrdiff_t; //For backwards compatibility only. @@ -44,6 +30,27 @@ alias dstring = immutable(dchar)[]; version (D_ObjectiveC) public import core.attribute : selector; +// Some ABIs use a complex varargs implementation requiring TypeInfo.argTypes(). +version (GNU) +{ + // No TypeInfo-based core.vararg.va_arg(). +} +else version (X86_64) +{ + version (DigitalMars) version = WithArgTypes; + else version (Windows) { /* no need for Win64 ABI */ } + else version = WithArgTypes; +} +version (AArch64) +{ + // Apple uses a trivial varargs implementation + version (OSX) {} + else version (iOS) {} + else version (TVOS) {} + else version (WatchOS) {} + else version = WithArgTypes; +} + /** * All D class objects inherit from Object. */ @@ -311,7 +318,7 @@ class TypeInfo /** Return internal info on arguments fitting into 8byte. * See X86-64 ABI 3.2.3 */ - version (X86_64) int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow + version (WithArgTypes) int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow { arg1 = this; return 0; @@ -319,7 +326,7 @@ class TypeInfo /** Return info used by the garbage collector to do precise collection. */ - @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return null; } + @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return rtinfoHasPointers; } // better safe than sorry } class TypeInfo_Enum : TypeInfo @@ -351,7 +358,7 @@ class TypeInfo_Enum : TypeInfo override @property size_t talign() nothrow pure const { return base.talign; } - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) { return base.argTypes(arg1, arg2); } @@ -509,12 +516,14 @@ class TypeInfo_Array : TypeInfo return (void[]).alignof; } - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) { arg1 = typeid(size_t); arg2 = typeid(void*); return 0; } + + override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(void[]); } } class TypeInfo_StaticArray : TypeInfo @@ -636,11 +645,14 @@ class TypeInfo_StaticArray : TypeInfo return value.talign; } - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) { arg1 = typeid(void*); return 0; } + + // just return the rtInfo of the element, we have no generic type T to run RTInfo!T on + override @property immutable(void)* rtInfo() nothrow pure const @safe { return value.rtInfo(); } } class TypeInfo_AssociativeArray : TypeInfo @@ -692,7 +704,7 @@ class TypeInfo_AssociativeArray : TypeInfo return (char[int]).alignof; } - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) { arg1 = typeid(void*); return 0; @@ -727,7 +739,7 @@ class TypeInfo_Vector : TypeInfo override @property size_t talign() nothrow pure const { return 16; } - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) { return base.argTypes(arg1, arg2); } @@ -767,6 +779,8 @@ class TypeInfo_Function : TypeInfo return null; } + override @property immutable(void)* rtInfo() nothrow pure const @safe { return rtinfoNoPointers; } + TypeInfo next; /** @@ -852,12 +866,14 @@ class TypeInfo_Delegate : TypeInfo return dg.alignof; } - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) { arg1 = typeid(void*); arg2 = typeid(void*); return 0; } + + override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(int delegate()); } } /** @@ -1228,9 +1244,9 @@ class TypeInfo_Struct : TypeInfo uint m_align; - override @property immutable(void)* rtInfo() const { return m_RTInfo; } + override @property immutable(void)* rtInfo() nothrow pure const @safe { return m_RTInfo; } - version (X86_64) + version (WithArgTypes) { override int argTypes(out TypeInfo arg1, out TypeInfo arg2) { @@ -1337,7 +1353,7 @@ class TypeInfo_Tuple : TypeInfo assert(0); } - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) { assert(0); } @@ -1379,7 +1395,7 @@ class TypeInfo_Const : TypeInfo override @property size_t talign() nothrow pure const { return base.talign; } - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) { return base.argTypes(arg1, arg2); } @@ -3165,11 +3181,32 @@ void __ctfeWrite(const string s) @nogc @safe pure nothrow {} * Create RTInfo for type T */ +template RTInfoImpl(size_t[] pointerBitmap) +{ + immutable size_t[pointerBitmap.length] RTInfoImpl = pointerBitmap[]; +} + +template NoPointersBitmapPayload(size_t N) +{ + enum size_t[N] NoPointersBitmapPayload = 0; +} + template RTInfo(T) { - enum RTInfo = null; + enum pointerBitmap = __traits(getPointerBitmap, T); + static if (pointerBitmap[1 .. $] == NoPointersBitmapPayload!(pointerBitmap.length - 1)) + enum RTInfo = rtinfoNoPointers; + else + enum RTInfo = RTInfoImpl!(pointerBitmap).ptr; } +/** +* shortcuts for the precise GC, also generated by the compiler +* used instead of the actual pointer bitmap +*/ +enum immutable(void)* rtinfoNoPointers = null; +enum immutable(void)* rtinfoHasPointers = cast(void*)1; + // lhs == rhs lowers to __equals(lhs, rhs) for dynamic arrays bool __equals(T1, T2)(T1[] lhs, T2[] rhs) { diff --git a/libphobos/libdruntime/rt/aaA.d b/libphobos/libdruntime/rt/aaA.d index 631847e4c2b..0ccf90204c6 100644 --- a/libphobos/libdruntime/rt/aaA.d +++ b/libphobos/libdruntime/rt/aaA.d @@ -271,7 +271,7 @@ TypeInfo_Struct fakeEntryTI(const TypeInfo keyti, const TypeInfo valti) // we don't expect the Entry objects to be used outside of this module, so we have control // over the non-usage of the callback methods and other entries and can keep these null // xtoHash, xopEquals, xopCmp, xtoString and xpostblit - ti.m_RTInfo = null; + ti.m_RTInfo = rtinfoNoPointers; immutable entrySize = talign(kti.tsize, vti.talign) + vti.tsize; ti.m_init = (cast(ubyte*) null)[0 .. entrySize]; // init length, but not ptr diff --git a/libphobos/libdruntime/rt/critical_.d b/libphobos/libdruntime/rt/critical_.d index 15c460aac6f..9404261131a 100644 --- a/libphobos/libdruntime/rt/critical_.d +++ b/libphobos/libdruntime/rt/critical_.d @@ -25,7 +25,10 @@ extern (C) void _d_critical_init() extern (C) void _d_critical_term() { - for (auto p = head; p; p = p.next) + // This function is only ever called by the runtime shutdown code + // and therefore is single threaded so the following cast is fine. + auto h = cast()head; + for (auto p = h; p; p = p.next) destroyMutex(cast(Mutex*)&p.mtx); } @@ -43,7 +46,7 @@ extern (C) void _d_criticalenter2(D_CRITICAL_SECTION** pcs) lockMutex(cast(Mutex*)&gcs.mtx); if (atomicLoad!(MemoryOrder.raw)(*cast(shared) pcs) is null) { - auto cs = new shared(D_CRITICAL_SECTION); + auto cs = new shared D_CRITICAL_SECTION; initMutex(cast(Mutex*)&cs.mtx); atomicStore!(MemoryOrder.rel)(*cast(shared) pcs, cs); } diff --git a/libphobos/libdruntime/rt/monitor_.d b/libphobos/libdruntime/rt/monitor_.d index e38b015f01e..8cb3c3a476e 100644 --- a/libphobos/libdruntime/rt/monitor_.d +++ b/libphobos/libdruntime/rt/monitor_.d @@ -28,15 +28,11 @@ in body { auto m = ensureMonitor(cast(Object) owner); - auto i = m.impl; - if (i is null) + if (m.impl is null) { atomicOp!("+=")(m.refs, cast(size_t) 1); - ownee.__monitor = owner.__monitor; - return; } - // If m.impl is set (ie. if this is a user-created monitor), assume - // the monitor is garbage collected and simply copy the reference. + // Assume the monitor is garbage collected and simply copy the reference. ownee.__monitor = owner.__monitor; } @@ -60,6 +56,26 @@ extern (C) void _d_monitordelete(Object h, bool det) } } +// does not call dispose events, for internal use only +extern (C) void _d_monitordelete_nogc(Object h) @nogc +{ + auto m = getMonitor(h); + if (m is null) + return; + + if (m.impl) + { + // let the GC collect the monitor + setMonitor(h, null); + } + else if (!atomicOp!("-=")(m.refs, cast(size_t) 1)) + { + // refcount == 0 means unshared => no synchronization required + deleteMonitor(cast(Monitor*) m); + setMonitor(h, null); + } +} + extern (C) void _d_monitorenter(Object h) in { diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Acdouble.d b/libphobos/libdruntime/rt/typeinfo/ti_Acdouble.d deleted file mode 100644 index 4eea4ad0936..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_Acdouble.d +++ /dev/null @@ -1,47 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_Acdouble; - -private import rt.util.typeinfo; - -// cdouble[] - -class TypeInfo_Ar : TypeInfo_Array -{ - alias F = cdouble; - - override bool opEquals(Object o) { return TypeInfo.opEquals(o); } - - override string toString() const { return (F[]).stringof; } - - override size_t getHash(scope const void* p) @trusted const - { - return Array!F.hashOf(*cast(F[]*)p); - } - - override bool equals(in void* p1, in void* p2) const - { - return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override int compare(in void* p1, in void* p2) const - { - return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(F); - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Acfloat.d b/libphobos/libdruntime/rt/typeinfo/ti_Acfloat.d deleted file mode 100644 index 126bfd80c8d..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_Acfloat.d +++ /dev/null @@ -1,47 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_Acfloat; - -private import rt.util.typeinfo; - -// cfloat[] - -class TypeInfo_Aq : TypeInfo_Array -{ - alias F = cfloat; - - override bool opEquals(Object o) { return TypeInfo.opEquals(o); } - - override string toString() const { return (F[]).stringof; } - - override size_t getHash(scope const void* p) @trusted const - { - return Array!F.hashOf(*cast(F[]*)p); - } - - override bool equals(in void* p1, in void* p2) const - { - return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override int compare(in void* p1, in void* p2) const - { - return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(F); - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Acreal.d b/libphobos/libdruntime/rt/typeinfo/ti_Acreal.d deleted file mode 100644 index 1d1421fa3e7..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_Acreal.d +++ /dev/null @@ -1,47 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_Acreal; - -private import rt.util.typeinfo; - -// creal[] - -class TypeInfo_Ac : TypeInfo_Array -{ - alias F = creal; - - override bool opEquals(Object o) { return TypeInfo.opEquals(o); } - - override string toString() const { return (F[]).stringof; } - - override size_t getHash(scope const void* p) @trusted const - { - return Array!F.hashOf(*cast(F[]*)p); - } - - override bool equals(in void* p1, in void* p2) const - { - return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override int compare(in void* p1, in void* p2) const - { - return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(F); - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Adouble.d b/libphobos/libdruntime/rt/typeinfo/ti_Adouble.d deleted file mode 100644 index 77904920419..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_Adouble.d +++ /dev/null @@ -1,61 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_Adouble; - -private import rt.util.typeinfo; - -// double[] - -class TypeInfo_Ad : TypeInfo_Array -{ - alias F = double; - - override bool opEquals(Object o) { return TypeInfo.opEquals(o); } - - override string toString() const { return (F[]).stringof; } - - override size_t getHash(scope const void* p) @trusted const - { - return Array!F.hashOf(*cast(F[]*)p); - } - - override bool equals(in void* p1, in void* p2) const - { - return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override int compare(in void* p1, in void* p2) const - { - return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(F); - } -} - -// idouble[] - -class TypeInfo_Ap : TypeInfo_Ad -{ - alias F = idouble; - - override string toString() const { return (F[]).stringof; } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(F); - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Afloat.d b/libphobos/libdruntime/rt/typeinfo/ti_Afloat.d deleted file mode 100644 index f6ae8271968..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_Afloat.d +++ /dev/null @@ -1,61 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_Afloat; - -private import rt.util.typeinfo; - -// float[] - -class TypeInfo_Af : TypeInfo_Array -{ - alias F = float; - - override bool opEquals(Object o) { return TypeInfo.opEquals(o); } - - override string toString() const { return (F[]).stringof; } - - override size_t getHash(scope const void* p) @trusted const - { - return Array!F.hashOf(*cast(F[]*)p); - } - - override bool equals(in void* p1, in void* p2) const - { - return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override int compare(in void* p1, in void* p2) const - { - return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(F); - } -} - -// ifloat[] - -class TypeInfo_Ao : TypeInfo_Af -{ - alias F = ifloat; - - override string toString() const { return (F[]).stringof; } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(F); - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Ag.d b/libphobos/libdruntime/rt/typeinfo/ti_Ag.d deleted file mode 100644 index f61bd34bbb5..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_Ag.d +++ /dev/null @@ -1,154 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_Ag; - -private import core.stdc.string; -private import core.internal.string; - -// byte[] - -class TypeInfo_Ag : TypeInfo_Array -{ - override bool opEquals(Object o) { return TypeInfo.opEquals(o); } - - override string toString() const { return "byte[]"; } - - override size_t getHash(scope const void* p) @trusted const - { - const s = *cast(const void[]*)p; - return hashOf(s); - } - - override bool equals(in void* p1, in void* p2) const - { - byte[] s1 = *cast(byte[]*)p1; - byte[] s2 = *cast(byte[]*)p2; - - return s1.length == s2.length && - memcmp(cast(byte *)s1, cast(byte *)s2, s1.length) == 0; - } - - override int compare(in void* p1, in void* p2) const - { - byte[] s1 = *cast(byte[]*)p1; - byte[] s2 = *cast(byte[]*)p2; - size_t len = s1.length; - - if (s2.length < len) - len = s2.length; - for (size_t u = 0; u < len; u++) - { - int result = s1[u] - s2[u]; - if (result) - return result; - } - if (s1.length < s2.length) - return -1; - else if (s1.length > s2.length) - return 1; - return 0; - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(byte); - } -} - - -// ubyte[] - -class TypeInfo_Ah : TypeInfo_Ag -{ - override string toString() const { return "ubyte[]"; } - - override int compare(in void* p1, in void* p2) const - { - char[] s1 = *cast(char[]*)p1; - char[] s2 = *cast(char[]*)p2; - - return dstrcmp(s1, s2); - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(ubyte); - } -} - -// void[] - -class TypeInfo_Av : TypeInfo_Ah -{ - override string toString() const { return "void[]"; } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(void); - } -} - -// bool[] - -class TypeInfo_Ab : TypeInfo_Ah -{ - override string toString() const { return "bool[]"; } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(bool); - } -} - -// char[] - -class TypeInfo_Aa : TypeInfo_Ah -{ - override string toString() const { return "char[]"; } - - override size_t getHash(scope const void* p) @trusted const - { - char[] s = *cast(char[]*)p; - return hashOf(s); - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(char); - } -} - -// string - -class TypeInfo_Aya : TypeInfo_Aa -{ - override string toString() const { return "immutable(char)[]"; } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(immutable(char)); - } -} - -// const(char)[] - -class TypeInfo_Axa : TypeInfo_Aa -{ - override string toString() const { return "const(char)[]"; } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(const(char)); - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Aint.d b/libphobos/libdruntime/rt/typeinfo/ti_Aint.d deleted file mode 100644 index 828fbc08ad9..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_Aint.d +++ /dev/null @@ -1,151 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_Aint; - -private import core.stdc.string; - -extern (C) void[] _adSort(void[] a, TypeInfo ti); - -// int[] - -class TypeInfo_Ai : TypeInfo_Array -{ - override bool opEquals(Object o) { return TypeInfo.opEquals(o); } - - override string toString() const { return "int[]"; } - - override size_t getHash(scope const void* p) @trusted const - { - // Hash as if unsigned. - const s = *cast(const uint[]*)p; - return hashOf(s); - } - - override bool equals(in void* p1, in void* p2) const - { - int[] s1 = *cast(int[]*)p1; - int[] s2 = *cast(int[]*)p2; - - return s1.length == s2.length && - memcmp(cast(void *)s1, cast(void *)s2, s1.length * int.sizeof) == 0; - } - - override int compare(in void* p1, in void* p2) const - { - int[] s1 = *cast(int[]*)p1; - int[] s2 = *cast(int[]*)p2; - size_t len = s1.length; - - if (s2.length < len) - len = s2.length; - for (size_t u = 0; u < len; u++) - { - if (s1[u] < s2[u]) - return -1; - else if (s1[u] > s2[u]) - return 1; - } - if (s1.length < s2.length) - return -1; - else if (s1.length > s2.length) - return 1; - return 0; - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(int); - } -} - -unittest -{ - int[][] a = [[5,3,8,7], [2,5,3,8,7]]; - _adSort(*cast(void[]*)&a, typeid(a[0])); - assert(a == [[2,5,3,8,7], [5,3,8,7]]); - - a = [[5,3,8,7], [5,3,8]]; - _adSort(*cast(void[]*)&a, typeid(a[0])); - assert(a == [[5,3,8], [5,3,8,7]]); -} - -unittest -{ - // Issue 13073: original code uses int subtraction which is susceptible to - // integer overflow, causing the following case to fail. - int[] a = [int.max, int.max]; - int[] b = [int.min, int.min]; - assert(a > b); - assert(b < a); -} - -// uint[] - -class TypeInfo_Ak : TypeInfo_Ai -{ - override string toString() const { return "uint[]"; } - - override int compare(in void* p1, in void* p2) const - { - uint[] s1 = *cast(uint[]*)p1; - uint[] s2 = *cast(uint[]*)p2; - size_t len = s1.length; - - if (s2.length < len) - len = s2.length; - for (size_t u = 0; u < len; u++) - { - if (s1[u] < s2[u]) - return -1; - else if (s1[u] > s2[u]) - return 1; - } - if (s1.length < s2.length) - return -1; - else if (s1.length > s2.length) - return 1; - return 0; - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(uint); - } -} - -unittest -{ - // Original test case from issue 13073 - uint x = 0x22_DF_FF_FF; - uint y = 0xA2_DF_FF_FF; - assert(!(x < y && y < x)); - uint[] a = [x]; - uint[] b = [y]; - assert(!(a < b && b < a)); // Original failing case - uint[1] a1 = [x]; - uint[1] b1 = [y]; - assert(!(a1 < b1 && b1 < a1)); // Original failing case -} - -// dchar[] - -class TypeInfo_Aw : TypeInfo_Ak -{ - override string toString() const { return "dchar[]"; } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(dchar); - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Along.d b/libphobos/libdruntime/rt/typeinfo/ti_Along.d deleted file mode 100644 index 51c741a3da2..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_Along.d +++ /dev/null @@ -1,103 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_Along; - -private import core.stdc.string; - -// long[] - -class TypeInfo_Al : TypeInfo_Array -{ - override bool opEquals(Object o) { return TypeInfo.opEquals(o); } - - override string toString() const { return "long[]"; } - - override size_t getHash(scope const void* p) @trusted const - { - // Hash as if unsigned. - const s = *cast(const ulong[]*)p; - return hashOf(s); - } - - override bool equals(in void* p1, in void* p2) const - { - long[] s1 = *cast(long[]*)p1; - long[] s2 = *cast(long[]*)p2; - - return s1.length == s2.length && - memcmp(cast(void *)s1, cast(void *)s2, s1.length * long.sizeof) == 0; - } - - override int compare(in void* p1, in void* p2) const - { - long[] s1 = *cast(long[]*)p1; - long[] s2 = *cast(long[]*)p2; - size_t len = s1.length; - - if (s2.length < len) - len = s2.length; - for (size_t u = 0; u < len; u++) - { - if (s1[u] < s2[u]) - return -1; - else if (s1[u] > s2[u]) - return 1; - } - if (s1.length < s2.length) - return -1; - else if (s1.length > s2.length) - return 1; - return 0; - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(long); - } -} - - -// ulong[] - -class TypeInfo_Am : TypeInfo_Al -{ - override string toString() const { return "ulong[]"; } - - override int compare(in void* p1, in void* p2) const - { - ulong[] s1 = *cast(ulong[]*)p1; - ulong[] s2 = *cast(ulong[]*)p2; - size_t len = s1.length; - - if (s2.length < len) - len = s2.length; - for (size_t u = 0; u < len; u++) - { - if (s1[u] < s2[u]) - return -1; - else if (s1[u] > s2[u]) - return 1; - } - if (s1.length < s2.length) - return -1; - else if (s1.length > s2.length) - return 1; - return 0; - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(ulong); - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Areal.d b/libphobos/libdruntime/rt/typeinfo/ti_Areal.d deleted file mode 100644 index f1dd458e2e6..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_Areal.d +++ /dev/null @@ -1,61 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_Areal; - -private import rt.util.typeinfo; - -// real[] - -class TypeInfo_Ae : TypeInfo_Array -{ - alias F = real; - - override bool opEquals(Object o) { return TypeInfo.opEquals(o); } - - override string toString() const { return (F[]).stringof; } - - override size_t getHash(scope const void* p) @trusted const - { - return Array!F.hashOf(*cast(F[]*)p); - } - - override bool equals(in void* p1, in void* p2) const - { - return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override int compare(in void* p1, in void* p2) const - { - return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2); - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(F); - } -} - -// ireal[] - -class TypeInfo_Aj : TypeInfo_Ae -{ - alias F = ireal; - - override string toString() const { return (F[]).stringof; } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(F); - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Ashort.d b/libphobos/libdruntime/rt/typeinfo/ti_Ashort.d deleted file mode 100644 index e4b47e247b7..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_Ashort.d +++ /dev/null @@ -1,113 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_Ashort; - -private import core.stdc.string; - -// short[] - -class TypeInfo_As : TypeInfo_Array -{ - override bool opEquals(Object o) { return TypeInfo.opEquals(o); } - - override string toString() const { return "short[]"; } - - override size_t getHash(scope const void* p) @trusted const - { - // Hash as if unsigned. - const s = *cast(const ushort[]*)p; - return hashOf(s); - } - - override bool equals(in void* p1, in void* p2) const - { - short[] s1 = *cast(short[]*)p1; - short[] s2 = *cast(short[]*)p2; - - return s1.length == s2.length && - memcmp(cast(void *)s1, cast(void *)s2, s1.length * short.sizeof) == 0; - } - - override int compare(in void* p1, in void* p2) const - { - short[] s1 = *cast(short[]*)p1; - short[] s2 = *cast(short[]*)p2; - size_t len = s1.length; - - if (s2.length < len) - len = s2.length; - for (size_t u = 0; u < len; u++) - { - int result = s1[u] - s2[u]; - if (result) - return result; - } - if (s1.length < s2.length) - return -1; - else if (s1.length > s2.length) - return 1; - return 0; - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(short); - } -} - - -// ushort[] - -class TypeInfo_At : TypeInfo_As -{ - override string toString() const { return "ushort[]"; } - - override int compare(in void* p1, in void* p2) const - { - ushort[] s1 = *cast(ushort[]*)p1; - ushort[] s2 = *cast(ushort[]*)p2; - size_t len = s1.length; - - if (s2.length < len) - len = s2.length; - for (size_t u = 0; u < len; u++) - { - int result = s1[u] - s2[u]; - if (result) - return result; - } - if (s1.length < s2.length) - return -1; - else if (s1.length > s2.length) - return 1; - return 0; - } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(ushort); - } -} - -// wchar[] - -class TypeInfo_Au : TypeInfo_At -{ - override string toString() const { return "wchar[]"; } - - override @property inout(TypeInfo) next() inout - { - return cast(inout)typeid(wchar); - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_C.d b/libphobos/libdruntime/rt/typeinfo/ti_C.d deleted file mode 100644 index df4987312a1..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_C.d +++ /dev/null @@ -1,75 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_C; - -// Object - -class TypeInfo_C : TypeInfo -{ - @trusted: - const: - //pure: - //nothrow: - - override size_t getHash(scope const void* p) - { - Object o = *cast(Object*)p; - return o ? o.toHash() : 0; - } - - override bool equals(in void* p1, in void* p2) - { - Object o1 = *cast(Object*)p1; - Object o2 = *cast(Object*)p2; - - return o1 == o2; - } - - override int compare(in void* p1, in void* p2) - { - Object o1 = *cast(Object*)p1; - Object o2 = *cast(Object*)p2; - int c = 0; - - // Regard null references as always being "less than" - if (!(o1 is o2)) - { - if (o1) - { - if (!o2) - c = 1; - else - c = o1.opCmp(o2); - } - else - c = -1; - } - return c; - } - - override @property size_t tsize() nothrow pure - { - return Object.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. Object.sizeof]; - } - - override @property uint flags() nothrow pure - { - return 1; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_byte.d b/libphobos/libdruntime/rt/typeinfo/ti_byte.d deleted file mode 100644 index 6a3efb144bf..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_byte.d +++ /dev/null @@ -1,60 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_byte; - -// byte - -class TypeInfo_g : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "byte"; } - - override size_t getHash(scope const void* p) - { - return *cast(const byte *)p; - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(byte *)p1 == *cast(byte *)p2; - } - - override int compare(in void* p1, in void* p2) - { - return *cast(byte *)p1 - *cast(byte *)p2; - } - - override @property size_t tsize() nothrow pure - { - return byte.sizeof; - } - - override const(void)[] initializer() @trusted - { - return (cast(void *)null)[0 .. byte.sizeof]; - } - - override void swap(void *p1, void *p2) - { - byte t; - - t = *cast(byte *)p1; - *cast(byte *)p1 = *cast(byte *)p2; - *cast(byte *)p2 = t; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_cdouble.d b/libphobos/libdruntime/rt/typeinfo/ti_cdouble.d deleted file mode 100644 index c396a17ce2c..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_cdouble.d +++ /dev/null @@ -1,74 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_cdouble; - -private import rt.util.typeinfo; - -// cdouble - -class TypeInfo_r : TypeInfo -{ - pure: - nothrow: - @safe: - - alias F = cdouble; - - override string toString() const { return F.stringof; } - - override size_t getHash(scope const void* p) const @trusted - { - return Floating!F.hashOf(*cast(F*)p); - } - - override bool equals(in void* p1, in void* p2) const @trusted - { - return Floating!F.equals(*cast(F*)p1, *cast(F*)p2); - } - - override int compare(in void* p1, in void* p2) const @trusted - { - return Floating!F.compare(*cast(F*)p1, *cast(F*)p2); - } - - override @property size_t tsize() const - { - return F.sizeof; - } - - override void swap(void *p1, void *p2) const @trusted - { - F t = *cast(F*)p1; - *cast(F*)p1 = *cast(F*)p2; - *cast(F*)p2 = t; - } - - override const(void)[] initializer() const @trusted - { - static immutable F r; - return (&r)[0 .. 1]; - } - - override @property size_t talign() const - { - return F.alignof; - } - - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) - { - arg1 = typeid(double); - arg2 = typeid(double); - return 0; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_cent.d b/libphobos/libdruntime/rt/typeinfo/ti_cent.d deleted file mode 100644 index a74f796d1c5..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_cent.d +++ /dev/null @@ -1,72 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2015. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2015. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_cent; - -static if (is(cent)): - -// cent - -class TypeInfo_zi : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "cent"; } - - override size_t getHash(scope const void* p) - { - // cent & ucent hash the same if ucent.sizeof >= size_t.sizeof. - return hashOf(*cast(const ucent*) p); - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(cent *)p1 == *cast(cent *)p2; - } - - override int compare(in void* p1, in void* p2) - { - if (*cast(cent *)p1 < *cast(cent *)p2) - return -1; - else if (*cast(cent *)p1 > *cast(cent *)p2) - return 1; - return 0; - } - - override @property size_t tsize() nothrow pure - { - return cent.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. cent.sizeof]; - } - - override void swap(void *p1, void *p2) - { - cent t; - - t = *cast(cent *)p1; - *cast(cent *)p1 = *cast(cent *)p2; - *cast(cent *)p2 = t; - } - - override @property size_t talign() nothrow pure - { - return cent.alignof; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_cfloat.d b/libphobos/libdruntime/rt/typeinfo/ti_cfloat.d deleted file mode 100644 index a3ad4ca9dbf..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_cfloat.d +++ /dev/null @@ -1,73 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_cfloat; - -private import rt.util.typeinfo; - -// cfloat - -class TypeInfo_q : TypeInfo -{ - pure: - nothrow: - @safe: - - alias F = cfloat; - - override string toString() const { return F.stringof; } - - override size_t getHash(scope const void* p) const @trusted - { - return Floating!F.hashOf(*cast(F*)p); - } - - override bool equals(in void* p1, in void* p2) const @trusted - { - return Floating!F.equals(*cast(F*)p1, *cast(F*)p2); - } - - override int compare(in void* p1, in void* p2) const @trusted - { - return Floating!F.compare(*cast(F*)p1, *cast(F*)p2); - } - - override @property size_t tsize() const - { - return F.sizeof; - } - - override void swap(void *p1, void *p2) const @trusted - { - F t = *cast(F*)p1; - *cast(F*)p1 = *cast(F*)p2; - *cast(F*)p2 = t; - } - - override const(void)[] initializer() const @trusted - { - static immutable F r; - return (&r)[0 .. 1]; - } - - override @property size_t talign() const - { - return F.alignof; - } - - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) - { - arg1 = typeid(double); - return 0; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_char.d b/libphobos/libdruntime/rt/typeinfo/ti_char.d deleted file mode 100644 index fbc5680335e..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_char.d +++ /dev/null @@ -1,62 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_char; - -// char - -class TypeInfo_a : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "char"; } - - override size_t getHash(scope const void* p) - { - return *cast(const char *)p; - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(char *)p1 == *cast(char *)p2; - } - - override int compare(in void* p1, in void* p2) - { - return *cast(char *)p1 - *cast(char *)p2; - } - - override @property size_t tsize() nothrow pure - { - return char.sizeof; - } - - override void swap(void *p1, void *p2) - { - char t; - - t = *cast(char *)p1; - *cast(char *)p1 = *cast(char *)p2; - *cast(char *)p2 = t; - } - - override const(void)[] initializer() const @trusted - { - static immutable char c; - - return (&c)[0 .. 1]; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_creal.d b/libphobos/libdruntime/rt/typeinfo/ti_creal.d deleted file mode 100644 index c064b7b872b..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_creal.d +++ /dev/null @@ -1,74 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_creal; - -private import rt.util.typeinfo; - -// creal - -class TypeInfo_c : TypeInfo -{ - pure: - nothrow: - @safe: - - alias F = creal; - - override string toString() const { return F.stringof; } - - override size_t getHash(scope const void* p) const @trusted - { - return Floating!F.hashOf(*cast(F*)p); - } - - override bool equals(in void* p1, in void* p2) const @trusted - { - return Floating!F.equals(*cast(F*)p1, *cast(F*)p2); - } - - override int compare(in void* p1, in void* p2) const @trusted - { - return Floating!F.compare(*cast(F*)p1, *cast(F*)p2); - } - - override @property size_t tsize() const - { - return F.sizeof; - } - - override void swap(void *p1, void *p2) const @trusted - { - F t = *cast(F*)p1; - *cast(F*)p1 = *cast(F*)p2; - *cast(F*)p2 = t; - } - - override const(void)[] initializer() const @trusted - { - static immutable F r; - return (&r)[0 .. 1]; - } - - override @property size_t talign() const - { - return F.alignof; - } - - version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2) - { - arg1 = typeid(real); - arg2 = typeid(real); - return 0; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_dchar.d b/libphobos/libdruntime/rt/typeinfo/ti_dchar.d deleted file mode 100644 index 5d6fea161d5..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_dchar.d +++ /dev/null @@ -1,62 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_dchar; - -// dchar - -class TypeInfo_w : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "dchar"; } - - override size_t getHash(scope const void* p) - { - return *cast(const dchar *)p; - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(dchar *)p1 == *cast(dchar *)p2; - } - - override int compare(in void* p1, in void* p2) - { - return *cast(dchar *)p1 - *cast(dchar *)p2; - } - - override @property size_t tsize() nothrow pure - { - return dchar.sizeof; - } - - override void swap(void *p1, void *p2) - { - dchar t; - - t = *cast(dchar *)p1; - *cast(dchar *)p1 = *cast(dchar *)p2; - *cast(dchar *)p2 = t; - } - - override const(void)[] initializer() const @trusted - { - static immutable dchar c; - - return (&c)[0 .. 1]; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_delegate.d b/libphobos/libdruntime/rt/typeinfo/ti_delegate.d deleted file mode 100644 index aaddd858159..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_delegate.d +++ /dev/null @@ -1,63 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_delegate; - - -// delegate - -alias void delegate(int) dg; - -class TypeInfo_D : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override size_t getHash(scope const void* p) - { - return hashOf(*cast(dg*)p); - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(dg *)p1 == *cast(dg *)p2; - } - - override @property size_t tsize() nothrow pure - { - return dg.sizeof; - } - - override void swap(void *p1, void *p2) - { - dg t; - - t = *cast(dg *)p1; - *cast(dg *)p1 = *cast(dg *)p2; - *cast(dg *)p2 = t; - } - - override const(void)[] initializer() const @trusted - { - static immutable dg d; - - return (cast(void *)null)[0 .. dg.sizeof]; - } - - override @property uint flags() nothrow pure - { - return 1; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_double.d b/libphobos/libdruntime/rt/typeinfo/ti_double.d deleted file mode 100644 index f5671cd032c..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_double.d +++ /dev/null @@ -1,76 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_double; - -private import rt.util.typeinfo; - -// double - -class TypeInfo_d : TypeInfo -{ - pure: - nothrow: - @safe: - - alias F = double; - - override string toString() const { return F.stringof; } - - override size_t getHash(scope const void* p) const @trusted - { - return Floating!F.hashOf(*cast(F*)p); - } - - override bool equals(in void* p1, in void* p2) const @trusted - { - return Floating!F.equals(*cast(F*)p1, *cast(F*)p2); - } - - override int compare(in void* p1, in void* p2) const @trusted - { - return Floating!F.compare(*cast(F*)p1, *cast(F*)p2); - } - - override @property size_t tsize() const - { - return F.sizeof; - } - - override void swap(void *p1, void *p2) const @trusted - { - F t = *cast(F*)p1; - *cast(F*)p1 = *cast(F*)p2; - *cast(F*)p2 = t; - } - - override const(void)[] initializer() const @trusted - { - static immutable F r; - return (&r)[0 .. 1]; - } - - override @property size_t talign() const - { - return F.alignof; - } - - version (Windows) - { - } - else version (X86_64) - { - // 2 means arg to function is passed in XMM registers - override @property uint flags() const { return 2; } - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_float.d b/libphobos/libdruntime/rt/typeinfo/ti_float.d deleted file mode 100644 index 4cd68c7cf26..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_float.d +++ /dev/null @@ -1,71 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_float; - -private import rt.util.typeinfo; - -// float - -class TypeInfo_f : TypeInfo -{ - pure: - nothrow: - @safe: - - alias F = float; - - override string toString() const { return F.stringof; } - - override size_t getHash(scope const void* p) const @trusted - { - return Floating!F.hashOf(*cast(F*)p); - } - - override bool equals(in void* p1, in void* p2) const @trusted - { - return Floating!F.equals(*cast(F*)p1, *cast(F*)p2); - } - - override int compare(in void* p1, in void* p2) const @trusted - { - return Floating!F.compare(*cast(F*)p1, *cast(F*)p2); - } - - override @property size_t tsize() const - { - return F.sizeof; - } - - override void swap(void *p1, void *p2) const @trusted - { - F t = *cast(F*)p1; - *cast(F*)p1 = *cast(F*)p2; - *cast(F*)p2 = t; - } - - override const(void)[] initializer() const @trusted - { - static immutable F r; - return (&r)[0 .. 1]; - } - - version (Windows) - { - } - else version (X86_64) - { - // 2 means arg to function is passed in XMM registers - override @property uint flags() const { return 2; } - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_idouble.d b/libphobos/libdruntime/rt/typeinfo/ti_idouble.d deleted file mode 100644 index f06854917da..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_idouble.d +++ /dev/null @@ -1,27 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_idouble; - -private import rt.typeinfo.ti_double; - -// idouble - -class TypeInfo_p : TypeInfo_d -{ - pure: - nothrow: - @safe: - - override string toString() const { return idouble.stringof; } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ifloat.d b/libphobos/libdruntime/rt/typeinfo/ti_ifloat.d deleted file mode 100644 index 062b3f466bd..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_ifloat.d +++ /dev/null @@ -1,27 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_ifloat; - -private import rt.typeinfo.ti_float; - -// ifloat - -class TypeInfo_o : TypeInfo_f -{ - pure: - nothrow: - @safe: - - override string toString() const { return ifloat.stringof; } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_int.d b/libphobos/libdruntime/rt/typeinfo/ti_int.d deleted file mode 100644 index 6e32c43afe9..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_int.d +++ /dev/null @@ -1,64 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_int; - -// int - -class TypeInfo_i : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "int"; } - - override size_t getHash(scope const void* p) - { - return *cast(const int *)p; - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(uint *)p1 == *cast(uint *)p2; - } - - override int compare(in void* p1, in void* p2) - { - if (*cast(int*) p1 < *cast(int*) p2) - return -1; - else if (*cast(int*) p1 > *cast(int*) p2) - return 1; - return 0; - } - - override @property size_t tsize() nothrow pure - { - return int.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. int.sizeof]; - } - - override void swap(void *p1, void *p2) - { - int t; - - t = *cast(int *)p1; - *cast(int *)p1 = *cast(int *)p2; - *cast(int *)p2 = t; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ireal.d b/libphobos/libdruntime/rt/typeinfo/ti_ireal.d deleted file mode 100644 index c1334f7a7c2..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_ireal.d +++ /dev/null @@ -1,27 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_ireal; - -private import rt.typeinfo.ti_real; - -// ireal - -class TypeInfo_j : TypeInfo_e -{ - pure: - nothrow: - @safe: - - override string toString() const { return ireal.stringof; } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_long.d b/libphobos/libdruntime/rt/typeinfo/ti_long.d deleted file mode 100644 index 78fea117634..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_long.d +++ /dev/null @@ -1,73 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_long; - -// long - -class TypeInfo_l : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "long"; } - - override size_t getHash(scope const void* p) - { - static if (ulong.sizeof <= size_t.sizeof) - return *cast(const long*)p; - else - // long & ulong hash the same if ulong.sizeof > size_t.sizeof. - return hashOf(*cast(const ulong*)p); - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(long *)p1 == *cast(long *)p2; - } - - override int compare(in void* p1, in void* p2) - { - if (*cast(long *)p1 < *cast(long *)p2) - return -1; - else if (*cast(long *)p1 > *cast(long *)p2) - return 1; - return 0; - } - - override @property size_t tsize() nothrow pure - { - return long.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. long.sizeof]; - } - - override void swap(void *p1, void *p2) - { - long t; - - t = *cast(long *)p1; - *cast(long *)p1 = *cast(long *)p2; - *cast(long *)p2 = t; - } - - override @property size_t talign() nothrow pure - { - return long.alignof; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_n.d b/libphobos/libdruntime/rt/typeinfo/ti_n.d deleted file mode 100644 index b6cea03218c..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_n.d +++ /dev/null @@ -1,58 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2016. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Kenji Hara - */ - -/* Copyright Digital Mars 2016. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_n; - -// typeof(null) - -class TypeInfo_n : TypeInfo -{ - override string toString() const @safe { return "typeof(null)"; } - - override size_t getHash(scope const void* p) const - { - return 0; - } - - override bool equals(in void* p1, in void* p2) const @trusted - { - //return *cast(typeof(null)*)p1 is *cast(typeof(null)*)p2; - return true; - } - - override int compare(in void* p1, in void* p2) const @trusted - { - //if (*cast(int*) p1 < *cast(int*) p2) - // return -1; - //else if (*cast(int*) p1 > *cast(int*) p2) - // return 1; - return 0; - } - - override @property size_t tsize() const - { - return typeof(null).sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void*)null)[0 .. typeof(null).sizeof]; - } - - override void swap(void *p1, void *p2) const @trusted - { - //auto t = *cast(typeof(null)*)p1; - //*cast(typeof(null)*)p1 = *cast(typeof(null)*)p2; - //*cast(typeof(null)*)p2 = t; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ptr.d b/libphobos/libdruntime/rt/typeinfo/ti_ptr.d deleted file mode 100644 index 8857ef90717..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_ptr.d +++ /dev/null @@ -1,65 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_ptr; - -// internal typeinfo for any pointer type -// please keep in sync with TypeInfo_Pointer - -class TypeInfo_P : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override size_t getHash(scope const void* p) - { - size_t addr = cast(size_t) *cast(const void**)p; - return addr ^ (addr >> 4); - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(void**)p1 == *cast(void**)p2; - } - - override int compare(in void* p1, in void* p2) - { - if (*cast(void**)p1 < *cast(void**)p2) - return -1; - else if (*cast(void**)p1 > *cast(void**)p2) - return 1; - else - return 0; - } - - override @property size_t tsize() nothrow pure - { - return (void*).sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. (void*).sizeof]; - } - - override void swap(void *p1, void *p2) - { - void* tmp = *cast(void**)p1; - *cast(void**)p1 = *cast(void**)p2; - *cast(void**)p2 = tmp; - } - - override @property uint flags() nothrow pure const { return 1; } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_real.d b/libphobos/libdruntime/rt/typeinfo/ti_real.d deleted file mode 100644 index fb20f1429ac..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_real.d +++ /dev/null @@ -1,67 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_real; - -private import rt.util.typeinfo; - -// real - -class TypeInfo_e : TypeInfo -{ - pure: - nothrow: - @safe: - - alias F = real; - - override string toString() const { return F.stringof; } - - override size_t getHash(scope const void* p) const @trusted - { - return Floating!F.hashOf(*cast(F*)p); - } - - override bool equals(in void* p1, in void* p2) const @trusted - { - return Floating!F.equals(*cast(F*)p1, *cast(F*)p2); - } - - override int compare(in void* p1, in void* p2) const @trusted - { - return Floating!F.compare(*cast(F*)p1, *cast(F*)p2); - } - - override @property size_t tsize() const - { - return F.sizeof; - } - - override void swap(void *p1, void *p2) const @trusted - { - F t = *cast(F*)p1; - *cast(F*)p1 = *cast(F*)p2; - *cast(F*)p2 = t; - } - - override const(void)[] initializer() const @trusted - { - static immutable F r; - return (&r)[0 .. 1]; - } - - override @property size_t talign() const - { - return F.alignof; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_short.d b/libphobos/libdruntime/rt/typeinfo/ti_short.d deleted file mode 100644 index bccbe63477a..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_short.d +++ /dev/null @@ -1,60 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_short; - -// short - -class TypeInfo_s : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "short"; } - - override size_t getHash(scope const void* p) - { - return *cast(const short *)p; - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(short *)p1 == *cast(short *)p2; - } - - override int compare(in void* p1, in void* p2) - { - return *cast(short *)p1 - *cast(short *)p2; - } - - override @property size_t tsize() nothrow pure - { - return short.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. short.sizeof]; - } - - override void swap(void *p1, void *p2) - { - short t; - - t = *cast(short *)p1; - *cast(short *)p1 = *cast(short *)p2; - *cast(short *)p2 = t; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ubyte.d b/libphobos/libdruntime/rt/typeinfo/ti_ubyte.d deleted file mode 100644 index 9643179be66..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_ubyte.d +++ /dev/null @@ -1,70 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_ubyte; - -// ubyte - -class TypeInfo_h : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "ubyte"; } - - override size_t getHash(scope const void* p) - { - return *cast(const ubyte *)p; - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(ubyte *)p1 == *cast(ubyte *)p2; - } - - override int compare(in void* p1, in void* p2) - { - return *cast(ubyte *)p1 - *cast(ubyte *)p2; - } - - override @property size_t tsize() nothrow pure - { - return ubyte.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. ubyte.sizeof]; - } - - override void swap(void *p1, void *p2) - { - ubyte t; - - t = *cast(ubyte *)p1; - *cast(ubyte *)p1 = *cast(ubyte *)p2; - *cast(ubyte *)p2 = t; - } -} - -class TypeInfo_b : TypeInfo_h -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "bool"; } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ucent.d b/libphobos/libdruntime/rt/typeinfo/ti_ucent.d deleted file mode 100644 index ffa67d8a624..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_ucent.d +++ /dev/null @@ -1,71 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2015. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2015. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_ucent; - -static if (is(ucent)): - -// ucent - -class TypeInfo_zk : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "ucent"; } - - override size_t getHash(scope const void* p) - { - return hashOf(*cast(const ucent*) p); - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(ucent *)p1 == *cast(ucent *)p2; - } - - override int compare(in void* p1, in void* p2) - { - if (*cast(ucent *)p1 < *cast(ucent *)p2) - return -1; - else if (*cast(ucent *)p1 > *cast(ucent *)p2) - return 1; - return 0; - } - - override @property size_t tsize() nothrow pure - { - return ucent.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. ucent.sizeof]; - } - - override void swap(void *p1, void *p2) - { - ucent t; - - t = *cast(ucent *)p1; - *cast(ucent *)p1 = *cast(ucent *)p2; - *cast(ucent *)p2 = t; - } - - override @property size_t talign() nothrow pure - { - return ucent.alignof; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_uint.d b/libphobos/libdruntime/rt/typeinfo/ti_uint.d deleted file mode 100644 index 09bff186b3f..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_uint.d +++ /dev/null @@ -1,64 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_uint; - -// uint - -class TypeInfo_k : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "uint"; } - - override size_t getHash(scope const void* p) - { - return *cast(const uint *)p; - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(uint *)p1 == *cast(uint *)p2; - } - - override int compare(in void* p1, in void* p2) - { - if (*cast(uint*) p1 < *cast(uint*) p2) - return -1; - else if (*cast(uint*) p1 > *cast(uint*) p2) - return 1; - return 0; - } - - override @property size_t tsize() nothrow pure - { - return uint.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. uint.sizeof]; - } - - override void swap(void *p1, void *p2) - { - int t; - - t = *cast(uint *)p1; - *cast(uint *)p1 = *cast(uint *)p2; - *cast(uint *)p2 = t; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ulong.d b/libphobos/libdruntime/rt/typeinfo/ti_ulong.d deleted file mode 100644 index 3fdaacd8ec9..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_ulong.d +++ /dev/null @@ -1,73 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_ulong; - - -// ulong - -class TypeInfo_m : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "ulong"; } - - override size_t getHash(scope const void* p) - { - static if (ulong.sizeof <= size_t.sizeof) - return *cast(const ulong*)p; - else - return hashOf(*cast(const ulong*)p); - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(ulong *)p1 == *cast(ulong *)p2; - } - - override int compare(in void* p1, in void* p2) - { - if (*cast(ulong *)p1 < *cast(ulong *)p2) - return -1; - else if (*cast(ulong *)p1 > *cast(ulong *)p2) - return 1; - return 0; - } - - override @property size_t tsize() nothrow pure - { - return ulong.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. ulong.sizeof]; - } - - override void swap(void *p1, void *p2) - { - ulong t; - - t = *cast(ulong *)p1; - *cast(ulong *)p1 = *cast(ulong *)p2; - *cast(ulong *)p2 = t; - } - - override @property size_t talign() nothrow pure - { - return ulong.alignof; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ushort.d b/libphobos/libdruntime/rt/typeinfo/ti_ushort.d deleted file mode 100644 index 90623f2d14c..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_ushort.d +++ /dev/null @@ -1,60 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_ushort; - -// ushort - -class TypeInfo_t : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "ushort"; } - - override size_t getHash(scope const void* p) - { - return *cast(const ushort *)p; - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(ushort *)p1 == *cast(ushort *)p2; - } - - override int compare(in void* p1, in void* p2) - { - return *cast(ushort *)p1 - *cast(ushort *)p2; - } - - override @property size_t tsize() nothrow pure - { - return ushort.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. ushort.sizeof]; - } - - override void swap(void *p1, void *p2) - { - ushort t; - - t = *cast(ushort *)p1; - *cast(ushort *)p1 = *cast(ushort *)p2; - *cast(ushort *)p2 = t; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_void.d b/libphobos/libdruntime/rt/typeinfo/ti_void.d deleted file mode 100644 index 1facb955597..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_void.d +++ /dev/null @@ -1,65 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_void; - -// void - -class TypeInfo_v : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() const pure nothrow @safe { return "void"; } - - override size_t getHash(scope const void* p) - { - assert(0); - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(byte *)p1 == *cast(byte *)p2; - } - - override int compare(in void* p1, in void* p2) - { - return *cast(byte *)p1 - *cast(byte *)p2; - } - - override @property size_t tsize() nothrow pure - { - return void.sizeof; - } - - override const(void)[] initializer() const @trusted - { - return (cast(void *)null)[0 .. void.sizeof]; - } - - override void swap(void *p1, void *p2) - { - byte t; - - t = *cast(byte *)p1; - *cast(byte *)p1 = *cast(byte *)p2; - *cast(byte *)p2 = t; - } - - override @property uint flags() nothrow pure - { - return 1; - } -} diff --git a/libphobos/libdruntime/rt/typeinfo/ti_wchar.d b/libphobos/libdruntime/rt/typeinfo/ti_wchar.d deleted file mode 100644 index dcf8256bf59..00000000000 --- a/libphobos/libdruntime/rt/typeinfo/ti_wchar.d +++ /dev/null @@ -1,62 +0,0 @@ -/** - * TypeInfo support code. - * - * Copyright: Copyright Digital Mars 2004 - 2009. - * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: Walter Bright - */ - -/* Copyright Digital Mars 2004 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module rt.typeinfo.ti_wchar; - -// wchar - -class TypeInfo_u : TypeInfo -{ - @trusted: - const: - pure: - nothrow: - - override string toString() { return "wchar"; } - - override size_t getHash(scope const void* p) - { - return *cast(const wchar *)p; - } - - override bool equals(in void* p1, in void* p2) - { - return *cast(wchar *)p1 == *cast(wchar *)p2; - } - - override int compare(in void* p1, in void* p2) - { - return *cast(wchar *)p1 - *cast(wchar *)p2; - } - - override @property size_t tsize() - { - return wchar.sizeof; - } - - override void swap(void *p1, void *p2) - { - wchar t; - - t = *cast(wchar *)p1; - *cast(wchar *)p1 = *cast(wchar *)p2; - *cast(wchar *)p2 = t; - } - - override const(void)[] initializer() const @trusted - { - static immutable wchar c; - - return (&c)[0 .. 1]; - } -} diff --git a/libphobos/libdruntime/rt/util/typeinfo.d b/libphobos/libdruntime/rt/util/typeinfo.d index 2cc1c236c10..31770a01946 100644 --- a/libphobos/libdruntime/rt/util/typeinfo.d +++ b/libphobos/libdruntime/rt/util/typeinfo.d @@ -266,3 +266,520 @@ unittest } }(); } + +// Reduces to `T` if `cond` is `true` or `U` otherwise. +private template Select(bool cond, T, U) +{ + static if (cond) alias Select = T; + else alias Select = U; +} + +/* +TypeInfo information for built-in types. + +A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and +equality comparison as type `T`. This saves on code size because parts of `Base` will be reused. Example: +`float` and `ifloat` or `char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap +the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect +during compilation whether they have different signedness and override appropriately. For initializer, we +detect if we need to override. The overriding initializer should be nonzero. +*/ +private class TypeInfoGeneric(T, Base = T) : Select!(is(T == Base), TypeInfo, TypeInfoGeneric!Base) +if (T.sizeof == Base.sizeof && T.alignof == Base.alignof) +{ + const: nothrow: pure: @trusted: + + // Returns the type name. + override string toString() const pure nothrow @safe { return T.stringof; } + + // `getHash` is the same for `Base` and `T`, introduce it just once. + static if (is(T == Base)) + override size_t getHash(scope const void* p) + { + static if (__traits(isFloating, T)) + return Floating!T.hashOf(*cast(T*)p); + else + return hashOf(*cast(const T *)p); + } + + // `equals` is the same for `Base` and `T`, introduce it just once. + static if (is(T == Base)) + override bool equals(in void* p1, in void* p2) + { + static if (__traits(isFloating, T)) + return Floating!T.equals(*cast(T*)p1, *cast(T*)p2); + else + return *cast(T *)p1 == *cast(T *)p2; + } + + // `T` and `Base` may have different signedness, so this function is introduced conditionally. + static if (is(T == Base) || (__traits(isIntegral, T) && T.max != Base.max)) + override int compare(in void* p1, in void* p2) + { + static if (__traits(isFloating, T)) + { + return Floating!T.compare(*cast(T*)p1, *cast(T*)p2); + } + else static if (T.sizeof < int.sizeof) + { + // Taking the difference will always fit in an int. + return int(*cast(T *) p1) - int(*cast(T *) p2); + } + else + { + auto lhs = *cast(T *) p1, rhs = *cast(T *) p2; + return (lhs > rhs) - (lhs < rhs); + } + } + + static if (is(T == Base)) + override @property size_t tsize() nothrow pure + { + return T.sizeof; + } + + static if (is(T == Base)) + override @property size_t talign() nothrow pure + { + return T.alignof; + } + + // Override initializer only if necessary. + static if (is(T == Base) || T.init != Base.init) + override const(void)[] initializer() @trusted + { + static if (__traits(isZeroInit, T)) + { + return (cast(void *)null)[0 .. T.sizeof]; + } + else + { + static immutable T[1] c; + return c; + } + } + + // `swap` is the same for `Base` and `T`, so introduce only once. + static if (is(T == Base)) + override void swap(void *p1, void *p2) + { + auto t = *cast(T *) p1; + *cast(T *)p1 = *cast(T *)p2; + *cast(T *)p2 = t; + } + + static if (is(T == Base) || RTInfo!T != RTInfo!Base) + override @property immutable(void)* rtInfo() nothrow pure const @safe + { + return RTInfo!T; + } + + static if (is(T == Base)) + static if (__traits(isFloating, T) && T.mant_dig != 64) + // FP types except 80-bit X87 are passed in SIMD register. + override @property uint flags() const { return 2; } +} + +unittest +{ + assert(typeid(int).toString == "int"); + + with (typeid(double)) + { + double a = 42, b = 43; + assert(equals(&a, &a)); + assert(!equals(&a, &b)); + assert(compare(&a, &a) == 0); + assert(compare(&a, &b) == -1); + assert(compare(&b, &a) == 1); + } + + with (typeid(short)) + { + short c = 42, d = 43; + assert(equals(&c, &c)); + assert(!equals(&c, &d)); + assert(compare(&c, &c) == 0); + assert(compare(&c, &d) == -1); + assert(compare(&d, &c) == 1); + assert(initializer.ptr is null); + assert(initializer.length == short.sizeof); + swap(&d, &c); + assert(c == 43 && d == 42); + } +} + +/* +TypeInfo information for arrays of built-in types. + +A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and +equality comparison as type `T`. This saves on code size because parts of `Base` will be reused. Example: +`float` and `ifloat` or `char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap +the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect +during compilation whether they have different signedness and override appropriately. For initializer, we +detect if we need to override. The overriding initializer should be nonzero. +*/ +private class TypeInfoArrayGeneric(T, Base = T) : Select!(is(T == Base), TypeInfo_Array, TypeInfoArrayGeneric!Base) +{ + static if (is(T == Base)) + override bool opEquals(Object o) { return TypeInfo.opEquals(o); } + + override string toString() const { return (T[]).stringof; } + + static if (is(T == Base)) + override size_t getHash(scope const void* p) @trusted const + { + static if (__traits(isFloating, T)) + return Array!T.hashOf(*cast(T[]*)p); + else + return hashOf(*cast(const T[]*) p); + } + + static if (is(T == Base)) + override bool equals(in void* p1, in void* p2) const + { + static if (__traits(isFloating, T)) + { + return Array!T.equals(*cast(T[]*)p1, *cast(T[]*)p2); + } + else + { + import core.stdc.string; + auto s1 = *cast(T[]*)p1; + auto s2 = *cast(T[]*)p2; + return s1.length == s2.length && + memcmp(s1.ptr, s2.ptr, s1.length) == 0; + } + } + + static if (is(T == Base) || (__traits(isIntegral, T) && T.max != Base.max)) + override int compare(in void* p1, in void* p2) const + { + static if (__traits(isFloating, T)) + { + return Array!T.compare(*cast(T[]*)p1, *cast(T[]*)p2); + } + else + { + auto s1 = *cast(T[]*)p1; + auto s2 = *cast(T[]*)p2; + auto len = s1.length; + + if (s2.length < len) + len = s2.length; + for (size_t u = 0; u < len; u++) + { + if (int result = (s1[u] > s2[u]) - (s1[u] < s2[u])) + return result; + } + return (s1.length > s2.length) - (s1.length < s2.length); + } + } + + override @property inout(TypeInfo) next() inout + { + return cast(inout) typeid(T); + } +} + +unittest +{ + assert(typeid(int[]) == typeid(int[])); + assert(typeid(int[]) != typeid(uint[])); + assert(typeid(int[]).toString == "int[]"); + + with (typeid(double[])) + { + double[] a = [ 1, 2, 3 ], b = [ 2, 3 ]; + assert(equals(&a, &a)); + assert(!equals(&a, &b)); + assert(compare(&a, &a) == 0); + assert(compare(&a, &b) == -1); + assert(compare(&b, &a) == 1); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Predefined TypeInfos +//////////////////////////////////////////////////////////////////////////////// + +// void +class TypeInfo_v : TypeInfoGeneric!ubyte +{ + const: nothrow: pure: @trusted: + + override string toString() const pure nothrow @safe { return "void"; } + + override size_t getHash(scope const void* p) + { + assert(0); + } + + override @property uint flags() nothrow pure + { + return 1; + } + + unittest + { + assert(typeid(void).toString == "void"); + assert(typeid(void).flags == 1); + } +} + +// All integrals. +class TypeInfo_h : TypeInfoGeneric!ubyte {} +class TypeInfo_b : TypeInfoGeneric!(bool, ubyte) {} +class TypeInfo_g : TypeInfoGeneric!(byte, ubyte) {} +class TypeInfo_a : TypeInfoGeneric!(char, ubyte) {} +class TypeInfo_t : TypeInfoGeneric!ushort {} +class TypeInfo_s : TypeInfoGeneric!(short, ushort) {} +class TypeInfo_u : TypeInfoGeneric!(wchar, ushort) {} +class TypeInfo_w : TypeInfoGeneric!(dchar, uint) {} +class TypeInfo_k : TypeInfoGeneric!uint {} +class TypeInfo_i : TypeInfoGeneric!(int, uint) {} +class TypeInfo_m : TypeInfoGeneric!ulong {} +class TypeInfo_l : TypeInfoGeneric!(long, ulong) {} +static if (is(cent)) class TypeInfo_zi : TypeInfoGeneric!cent {} +static if (is(ucent)) class TypeInfo_zk : TypeInfoGeneric!ucent {} + +// All simple floating-point types. +class TypeInfo_f : TypeInfoGeneric!float {} +class TypeInfo_o : TypeInfoGeneric!(ifloat, float) {} +class TypeInfo_d : TypeInfoGeneric!double {} +class TypeInfo_p : TypeInfoGeneric!(idouble, double) {} +class TypeInfo_e : TypeInfoGeneric!real {} +class TypeInfo_j : TypeInfoGeneric!(ireal, real) {} + +// All complex floating-point types. + +// cfloat +class TypeInfo_q : TypeInfoGeneric!cfloat +{ + const: nothrow: pure: @trusted: + static if (__traits(hasMember, TypeInfo, "argTypes")) + override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + { + arg1 = typeid(double); + return 0; + } +} + +// cdouble +class TypeInfo_r : TypeInfoGeneric!cdouble +{ + const: nothrow: pure: @trusted: + static if (__traits(hasMember, TypeInfo, "argTypes")) + override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + { + arg1 = typeid(double); + arg2 = typeid(double); + return 0; + } +} + +// creal +class TypeInfo_c : TypeInfoGeneric!creal +{ + const: nothrow: pure: @trusted: + static if (__traits(hasMember, TypeInfo, "argTypes")) + override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + { + arg1 = typeid(real); + arg2 = typeid(real); + return 0; + } +} + +static if (__traits(hasMember, TypeInfo, "argTypes")) + unittest + { + TypeInfo t1, t2; + assert(typeid(cfloat).argTypes(t1, t2) == 0 && t1 == typeid(double) && + t2 is null); + assert(typeid(cdouble).argTypes(t1, t2) == 0 && t1 == typeid(double) && + t2 == typeid(double)); + assert(typeid(creal).argTypes(t1, t2) == 0 && t1 == typeid(real) && + t2 == typeid(real)); + } + +// Arrays of all integrals. +class TypeInfo_Ah : TypeInfoArrayGeneric!ubyte {} +class TypeInfo_Ab : TypeInfoArrayGeneric!(bool, ubyte) {} +class TypeInfo_Ag : TypeInfoArrayGeneric!(byte, ubyte) {} +class TypeInfo_Aa : TypeInfoArrayGeneric!(char, ubyte) {} +class TypeInfo_Axa : TypeInfoArrayGeneric!(const char) {} +class TypeInfo_Aya : TypeInfoArrayGeneric!(immutable char) +{ + // Must override this, otherwise "string" is returned. + override string toString() const { return "immutable(char)[]"; } +} +class TypeInfo_At : TypeInfoArrayGeneric!ushort {} +class TypeInfo_As : TypeInfoArrayGeneric!(short, ushort) {} +class TypeInfo_Au : TypeInfoArrayGeneric!(wchar, ushort) {} +class TypeInfo_Ak : TypeInfoArrayGeneric!uint {} +class TypeInfo_Ai : TypeInfoArrayGeneric!(int, uint) {} +class TypeInfo_Aw : TypeInfoArrayGeneric!(dchar, uint) {} +class TypeInfo_Am : TypeInfoArrayGeneric!ulong {} +class TypeInfo_Al : TypeInfoArrayGeneric!(long, ulong) {} + +version (unittest) + private extern (C) void[] _adSort(void[] a, TypeInfo ti); + +unittest +{ + assert(typeid(string).toString() == "immutable(char)[]"); + int[][] a = [[5,3,8,7], [2,5,3,8,7]]; + _adSort(*cast(void[]*)&a, typeid(a[0])); + assert(a == [[2,5,3,8,7], [5,3,8,7]]); + + a = [[5,3,8,7], [5,3,8]]; + _adSort(*cast(void[]*)&a, typeid(a[0])); + assert(a == [[5,3,8], [5,3,8,7]]); +} + +unittest +{ + // https://issues.dlang.org/show_bug.cgi?id=13073: original code uses int subtraction which is susceptible to + // integer overflow, causing the following case to fail. + int[] a = [int.max, int.max]; + int[] b = [int.min, int.min]; + assert(a > b); + assert(b < a); +} + +unittest +{ + // Original test case from issue 13073 + uint x = 0x22_DF_FF_FF; + uint y = 0xA2_DF_FF_FF; + assert(!(x < y && y < x)); + uint[] a = [x]; + uint[] b = [y]; + assert(!(a < b && b < a)); // Original failing case + uint[1] a1 = [x]; + uint[1] b1 = [y]; + assert(!(a1 < b1 && b1 < a1)); // Original failing case +} + +// Arrays of all floating point types. +class TypeInfo_Af : TypeInfoArrayGeneric!float {} +class TypeInfo_Ao : TypeInfoArrayGeneric!(ifloat, float) {} +class TypeInfo_Ad : TypeInfoArrayGeneric!double {} +class TypeInfo_Ap : TypeInfoArrayGeneric!(idouble, double) {} +class TypeInfo_Ae : TypeInfoArrayGeneric!real {} +class TypeInfo_Aj : TypeInfoArrayGeneric!(ireal, real) {} +class TypeInfo_Aq : TypeInfoArrayGeneric!cfloat {} +class TypeInfo_Ar : TypeInfoArrayGeneric!cdouble {} +class TypeInfo_Ac : TypeInfoArrayGeneric!creal {} + +// void[] is a bit different, behaves like ubyte[] for comparison purposes. +class TypeInfo_Av : TypeInfo_Ah +{ + override string toString() const { return "void[]"; } + + override @property inout(TypeInfo) next() inout + { + return cast(inout) typeid(void); + } + + unittest + { + assert(typeid(void[]).toString == "void[]"); + assert(typeid(void[]).next == typeid(void)); + } +} + +// all delegates +unittest +{ + assert(typeid(void delegate(int)).flags == 1); +} + +// typeof(null) +class TypeInfo_n : TypeInfo +{ + override string toString() const @safe { return "typeof(null)"; } + + override size_t getHash(scope const void* p) const + { + return 0; + } + + override bool equals(in void* p1, in void* p2) const @trusted + { + return true; + } + + override int compare(in void* p1, in void* p2) const @trusted + { + return 0; + } + + override @property size_t tsize() const + { + return typeof(null).sizeof; + } + + override const(void)[] initializer() const @trusted + { + __gshared immutable void[typeof(null).sizeof] init; + return init; + } + + override void swap(void *p1, void *p2) const @trusted + { + } + + override @property immutable(void)* rtInfo() nothrow pure const @safe { return rtinfoNoPointers; } + + unittest + { + with (typeid(typeof(null))) + { + assert(toString == "typeof(null)"); + assert(getHash(null) == 0); + assert(equals(null, null)); + assert(compare(null, null) == 0); + assert(tsize == typeof(null).sizeof); + assert(initializer == new ubyte[(void*).sizeof]); + assert(rtInfo == rtinfoNoPointers); + } + } +} + +// Test typeinfo for classes. +unittest +{ + static class Bacon + { + int sizzle = 1; + override int opCmp(Object rhs) const + { + if (auto rhsb = cast(Bacon) rhs) + return (sizzle > rhsb.sizzle) - (sizzle < rhsb.sizzle); + return 0; + } + } + Object obj = new Bacon; + Bacon obj2 = new Bacon; + obj2.sizzle = 2; + auto dummy = new Object; + with (typeid(obj)) + { + assert(toString[$ - 6 .. $] == ".Bacon"); + assert(getHash(&obj) != 0); + assert(equals(&obj, &obj)); + assert(!equals(&obj, &obj2)); + assert(compare(&obj, &dummy) == 0); + assert(compare(&obj, &obj) == 0); + assert(compare(&obj, &obj2) == -1); + assert(compare(&obj2, &obj) == 1); + assert(tsize == Object.sizeof); + assert(rtInfo == RTInfo!Bacon); + assert(tsize == Object.sizeof); + assert(initializer.ptr !is null); + assert(initializer.length == __traits(classInstanceSize, Bacon)); + assert(flags == 1); + } +} diff --git a/libphobos/testsuite/libphobos.thread/fiber_guard_page.d b/libphobos/testsuite/libphobos.thread/fiber_guard_page.d index 61a616acd8e..9f754e155d2 100644 --- a/libphobos/testsuite/libphobos.thread/fiber_guard_page.d +++ b/libphobos/testsuite/libphobos.thread/fiber_guard_page.d @@ -23,18 +23,15 @@ void main() // allocate a page below (above) the fiber's stack to make stack overflows possible (w/o segfaulting) version (StackGrowsDown) { - static assert(__traits(identifier, test_fiber.tupleof[8]) == "m_pmem"); - auto stackBottom = test_fiber.tupleof[8]; + auto stackBottom = __traits(getMember, test_fiber, "m_pmem"); auto p = mmap(stackBottom - 8 * stackSize, 8 * stackSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); assert(p !is null, "failed to allocate page"); } else { - auto m_sz = test_fiber.tupleof[7]; - auto m_pmem = test_fiber.tupleof[8]; - static assert(__traits(identifier, test_fiber.tupleof[7]) == "m_size"); - static assert(__traits(identifier, test_fiber.tupleof[8]) == "m_pmem"); + auto m_sz = __traits(getMember, test_fiber, "m_sz"); + auto m_pmem = __traits(getMember, test_fiber, "m_pmem"); auto stackTop = m_pmem + m_sz; auto p = mmap(stackTop, 8 * stackSize,