summaryrefslogtreecommitdiffstats
path: root/libphobos
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-12-05 17:11:12 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2021-12-09 00:58:58 +0100
commit0fb57034770aa20adced4d176f34ca611c2945bf (patch)
tree1f5735c8b4f25aa4a290e5ae8124713c24f98359 /libphobos
parentlibstdc++: Fix undefined shift when _Atomic_word is 64-bit (diff)
downloadgcc-0fb57034770aa20adced4d176f34ca611c2945bf.tar.gz
gcc-0fb57034770aa20adced4d176f34ca611c2945bf.tar.bz2
gcc-0fb57034770aa20adced4d176f34ca611c2945bf.tar.xz
d: Merge upstream dmd 568496d5b, druntime 178c44ff, phobos 574bf883b.
D front-end changes: - Import dmd v2.098.0 - New ImportC module for compiling preprocessed C11 code into D. - New -ftransition=in switch. - Improved handling of new 'noreturn' type. Druntime changes: - Import druntime v2.098.0 - Fix broken import in core.sys.linux.perf_event module (PR103558). Phobos changes: - Import phobos v2.098.0 - All sources are now compiled with -fpreview=fieldwise. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 568496d5b. * Make-lang.in (D_FRONTEND_OBJS): Add d/common-file.o, d/common-outbuffer.o, d/common-string.o, d/file_manager.o, d/importc.o. Remove d/root-outbuffer.o. (d/common-%.o): New recipe. * d-builtins.cc (build_frontend_type): Update for new front-end interface. (d_build_d_type_nodes): Set noreturn_type_node. * d-codegen.cc (d_build_call): Don't call function if one of the arguments is type 'noreturn'. (build_vthis_function): Propagate TYPE_QUAL_VOLATILE from original function type. * d-frontend.cc (eval_builtin): Update signature. (getTypeInfoType): Likewise. (toObjFile): New function. * d-gimplify.cc (d_gimplify_call_expr): Always evaluate arguments from left to right. * d-lang.cc (d_handle_option): Handle OPT_ftransition_in. (d_parse_file): Don't generate D main if it is declared in user code. * d-tree.h (CALL_EXPR_ARGS_ORDERED): Remove. (enum d_tree_index): Add DTI_BOTTOM_TYPE. (noreturn_type_node): New. * decl.cc (apply_pragma_crt): Remove. (DeclVisitor::visit): Update for new front-end interface. (DeclVisitor::visit (PragmaDeclaration *)): Don't handle crt_constructor and crt_destructor pragmas. (DeclVisitor::visit (VarDeclaration *)): Don't generate declarations of type 'noreturn'. (DeclVisitor::visit (FuncDeclaration *)): Stop adding parameters when 'noreturn' type has been encountered. (get_symbol_decl): Set DECL_STATIC_CONSTRUCTOR and DECL_STATIC_DESTRUCTOR on decl node if requested. (aggregate_initializer_decl): Update for new front-end interface. * expr.cc (ExprVisitor::visit (CallExp *)): Always use the 'this' object as the result of calling any constructor function. (ExprVisitor::visit): Update for new front-end interface. * gdc.texi (Runtime Options): Document -fmain and -ftransition=in. * lang.opt (ftransition=in): New option. * modules.cc (get_internal_fn): Update for new front-end interface. * types.cc (TypeVisitor::visit): Likewise. (TypeVisitor::visit (TypeNoreturn *)): Return noreturn_type_node. (TypeVisitor::visit (TypeFunction *)): Stop adding parameters when 'notreturn' type has been encountered. Qualify function types that return 'noreturn' as TYPE_QUAL_VOLATILE. libphobos/ChangeLog: PR d/103558 * libdruntime/MERGE: Merge upstream druntime 178c44ff. * libdruntime/Makefile.am (DRUNTIME_DSOURCES_LINUX): Add core/sys/linux/syscalls.d. (DRUNTIME_DSOURCES_OPENBSD): Add core/sys/openbsd/pthread_np.d. * libdruntime/Makefile.in: Regenerate. * src/MERGE: Merge upstream phobos 574bf883b. * src/Makefile.am (D_EXTRA_DFLAGS): Add -fpreview=fieldwise. * src/Makefile.in: Regenerate. * testsuite/libphobos.exceptions/assert_fail.d: Update test. * testsuite/libphobos.betterc/test22336.d: New test.
Diffstat (limited to 'libphobos')
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/Makefile.am18
-rw-r--r--libphobos/libdruntime/Makefile.in34
-rw-r--r--libphobos/libdruntime/core/demangle.d98
-rw-r--r--libphobos/libdruntime/core/exception.d19
-rw-r--r--libphobos/libdruntime/core/internal/array/construction.d55
-rw-r--r--libphobos/libdruntime/core/internal/atomic.d24
-rw-r--r--libphobos/libdruntime/core/internal/dassert.d2
-rw-r--r--libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d279
-rw-r--r--libphobos/libdruntime/core/internal/gc/os.d44
-rw-r--r--libphobos/libdruntime/core/internal/hash.d9
-rw-r--r--libphobos/libdruntime/core/internal/parseoptions.d2
-rw-r--r--libphobos/libdruntime/core/internal/traits.d8
-rw-r--r--libphobos/libdruntime/core/internal/util/array.d49
-rw-r--r--libphobos/libdruntime/core/lifetime.d4
-rw-r--r--libphobos/libdruntime/core/runtime.d1
-rw-r--r--libphobos/libdruntime/core/stdc/stdlib.d2
-rw-r--r--libphobos/libdruntime/core/sync/rwmutex.d418
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/config.d4
-rw-r--r--libphobos/libdruntime/core/sys/linux/fs.d63
-rw-r--r--libphobos/libdruntime/core/sys/linux/perf_event.d2
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/mman.d32
-rw-r--r--libphobos/libdruntime/core/sys/linux/syscalls.d745
-rw-r--r--libphobos/libdruntime/core/sys/linux/unistd.d26
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/dlfcn.d4
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/pthread_np.d23
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/stdlib.d8
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/string.d6
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/sys/mman.d6
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/sys/sysctl.d3
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/unistd.d2
-rw-r--r--libphobos/libdruntime/core/sys/posix/netdb.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/filio.d12
-rwxr-xr-xlibphobos/libdruntime/core/sys/posix/sys/ioccom.d56
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/ioctl.d7
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/mman.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/socket.d3
-rwxr-xr-xlibphobos/libdruntime/core/sys/posix/sys/ttycom.d101
-rw-r--r--libphobos/libdruntime/core/sys/posix/time.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/accctrl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/aclapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/aclui.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/basetsd.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/basetyps.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/cderr.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/cguid.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/comcat.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/commctrl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/commdlg.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/core.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/cpl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/cplext.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/custcntl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/dbt.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/dde.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ddeml.d76
-rw-r--r--libphobos/libdruntime/core/sys/windows/dhcpcsdk.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/dlgs.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/dll.d6
-rw-r--r--libphobos/libdruntime/core/sys/windows/docobj.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/errorrep.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/exdisp.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/exdispid.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/httpext.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/idispids.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/imagehlp.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/imm.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/intshcut.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ipexport.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/iphlpapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ipifcons.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/iprtrmib.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/iptypes.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/isguids.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lm.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmaccess.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmalert.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmapibuf.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmat.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmaudit.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmbrowsr.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmchdev.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmconfig.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmcons.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmerr.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmerrlog.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmmsg.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmremutl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmrepl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmserver.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmshare.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmsname.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmstats.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmsvc.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmuse.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmuseflg.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmwksta.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lzexpand.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/mapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/mciavi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/mcx.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/mgmtapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/mmsystem.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/msacm.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/mshtml.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/mswsock.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/nb30.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/nddeapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/nspapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntdef.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntdll.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntldap.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntsecapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntsecpkg.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/oaidl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/objbase.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/objfwd.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/objidl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/objsafe.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ocidl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/odbcinst.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ole.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ole2.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ole2ver.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/oleacc.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/oleauto.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/olectl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/olectlid.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/oledlg.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/oleidl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/pbt.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/powrprof.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/prsht.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/psapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ras.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rasdlg.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/raserror.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rassapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/reason.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/regstr.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/richedit.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/richole.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpc.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcdce.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcdce2.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcdcep.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcndr.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcnsi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcnsip.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcnterr.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/schannel.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/sdkddkver.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/secext.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/security.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/servprov.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/setupapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/shellapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/shldisp.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/shlguid.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/shlobj.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/shlwapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/snmp.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/sql.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/sqlext.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/sqltypes.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/sqlucode.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/sspi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/stdc/malloc.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/subauth.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/tlhelp32.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/tmschema.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/unknwn.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/vfw.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/w32api.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winbase.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winber.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/wincon.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/wincrypt.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/windef.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/windows.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winerror.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/wingdi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winhttp.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/wininet.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winioctl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winldap.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winnetwk.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winnls.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winnt.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winperf.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winreg.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winspool.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winsvc.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winuser.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/winver.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/wtsapi32.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/wtypes.d2
-rw-r--r--libphobos/libdruntime/core/thread/fiber.d8
-rw-r--r--libphobos/libdruntime/core/thread/osthread.d1
-rw-r--r--libphobos/libdruntime/core/time.d34
-rw-r--r--libphobos/libdruntime/object.d78
-rw-r--r--libphobos/libdruntime/rt/aApplyR.d11
-rw-r--r--libphobos/libdruntime/rt/aaA.d6
-rw-r--r--libphobos/libdruntime/rt/dmain2.d4
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/Makefile.am5
-rw-r--r--libphobos/src/Makefile.in5
-rw-r--r--libphobos/src/etc/c/curl.d43
-rw-r--r--libphobos/src/index.dd (renamed from libphobos/src/index.d)0
-rw-r--r--libphobos/src/std/algorithm/comparison.d401
-rw-r--r--libphobos/src/std/algorithm/iteration.d237
-rw-r--r--libphobos/src/std/algorithm/mutation.d2
-rw-r--r--libphobos/src/std/algorithm/searching.d8
-rw-r--r--libphobos/src/std/algorithm/sorting.d12
-rw-r--r--libphobos/src/std/array.d22
-rw-r--r--libphobos/src/std/bitmanip.d6
-rw-r--r--libphobos/src/std/concurrency.d79
-rw-r--r--libphobos/src/std/container/array.d206
-rw-r--r--libphobos/src/std/datetime/systime.d52
-rw-r--r--libphobos/src/std/datetime/timezone.d1
-rw-r--r--libphobos/src/std/digest/ripemd.d2
-rw-r--r--libphobos/src/std/exception.d50
-rw-r--r--libphobos/src/std/experimental/checkedint.d10
-rw-r--r--libphobos/src/std/file.d75
-rw-r--r--libphobos/src/std/format/internal/floats.d12
-rw-r--r--libphobos/src/std/format/internal/write.d154
-rw-r--r--libphobos/src/std/functional.d31
-rw-r--r--libphobos/src/std/getopt.d13
-rw-r--r--libphobos/src/std/internal/math/biguintcore.d6
-rw-r--r--libphobos/src/std/internal/windows/advapi32.d12
-rw-r--r--libphobos/src/std/json.d6
-rw-r--r--libphobos/src/std/math/algebraic.d89
-rw-r--r--libphobos/src/std/math/operations.d3
-rw-r--r--libphobos/src/std/meta.d384
-rw-r--r--libphobos/src/std/parallelism.d71
-rw-r--r--libphobos/src/std/process.d27
-rw-r--r--libphobos/src/std/random.d24
-rw-r--r--libphobos/src/std/range/interfaces.d51
-rw-r--r--libphobos/src/std/range/package.d102
-rw-r--r--libphobos/src/std/range/primitives.d17
-rw-r--r--libphobos/src/std/socket.d79
-rw-r--r--libphobos/src/std/stdio.d52
-rw-r--r--libphobos/src/std/string.d16
-rw-r--r--libphobos/src/std/system.d2
-rw-r--r--libphobos/src/std/traits.d602
-rw-r--r--libphobos/src/std/typecons.d243
-rw-r--r--libphobos/src/std/uni/package.d38
-rw-r--r--libphobos/src/std/variant.d2
-rw-r--r--libphobos/src/std/windows/registry.d5
-rw-r--r--libphobos/testsuite/libphobos.betterc/test22336.d19
-rw-r--r--libphobos/testsuite/libphobos.exceptions/assert_fail.d12
252 files changed, 4065 insertions, 1941 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 11bef0f3388..d0d3a25ad1e 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
1e6caaab9d359198b760c698dcb6d253afb3f81f6 1178c44ff362902af589603767055cfac89215652
2 2
3The first line of this file holds the git revision number of the last 3The first line of this file holds the git revision number of the last
4merge done from the dlang/druntime repository. 4merge done from the dlang/druntime repository.
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 80c7567079a..44d4fe16be0 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -280,8 +280,9 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
280 core/sys/linux/sys/procfs.d core/sys/linux/sys/signalfd.d \ 280 core/sys/linux/sys/procfs.d core/sys/linux/sys/signalfd.d \
281 core/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \ 281 core/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \
282 core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \ 282 core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \
283 core/sys/linux/termios.d core/sys/linux/time.d \ 283 core/sys/linux/syscalls.d core/sys/linux/termios.d \
284 core/sys/linux/timerfd.d core/sys/linux/tipc.d core/sys/linux/unistd.d 284 core/sys/linux/time.d core/sys/linux/timerfd.d core/sys/linux/tipc.d \
285 core/sys/linux/unistd.d
285 286
286DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \ 287DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
287 core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \ 288 core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \
@@ -294,12 +295,13 @@ DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
294 295
295DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \ 296DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \
296 core/sys/openbsd/err.d core/sys/openbsd/execinfo.d \ 297 core/sys/openbsd/err.d core/sys/openbsd/execinfo.d \
297 core/sys/openbsd/stdlib.d core/sys/openbsd/string.d \ 298 core/sys/openbsd/pthread_np.d core/sys/openbsd/stdlib.d \
298 core/sys/openbsd/sys/cdefs.d core/sys/openbsd/sys/elf.d \ 299 core/sys/openbsd/string.d core/sys/openbsd/sys/cdefs.d \
299 core/sys/openbsd/sys/elf32.d core/sys/openbsd/sys/elf64.d \ 300 core/sys/openbsd/sys/elf.d core/sys/openbsd/sys/elf32.d \
300 core/sys/openbsd/sys/elf_common.d core/sys/openbsd/sys/link_elf.d \ 301 core/sys/openbsd/sys/elf64.d core/sys/openbsd/sys/elf_common.d \
301 core/sys/openbsd/sys/mman.d core/sys/openbsd/sys/sysctl.d \ 302 core/sys/openbsd/sys/link_elf.d core/sys/openbsd/sys/mman.d \
302 core/sys/openbsd/time.d core/sys/openbsd/unistd.d 303 core/sys/openbsd/sys/sysctl.d core/sys/openbsd/time.d \
304 core/sys/openbsd/unistd.d
303 305
304DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \ 306DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \
305 core/sys/posix/arpa/inet.d core/sys/posix/config.d \ 307 core/sys/posix/arpa/inet.d core/sys/posix/config.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index b5f29da8540..84be8082f7a 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -343,10 +343,10 @@ am__objects_14 = core/sys/netbsd/dlfcn.lo core/sys/netbsd/err.lo \
343 core/sys/netbsd/sys/sysctl.lo core/sys/netbsd/time.lo 343 core/sys/netbsd/sys/sysctl.lo core/sys/netbsd/time.lo
344@DRUNTIME_OS_NETBSD_TRUE@am__objects_15 = $(am__objects_14) 344@DRUNTIME_OS_NETBSD_TRUE@am__objects_15 = $(am__objects_14)
345am__objects_16 = core/sys/openbsd/dlfcn.lo core/sys/openbsd/err.lo \ 345am__objects_16 = core/sys/openbsd/dlfcn.lo core/sys/openbsd/err.lo \
346 core/sys/openbsd/execinfo.lo core/sys/openbsd/stdlib.lo \ 346 core/sys/openbsd/execinfo.lo core/sys/openbsd/pthread_np.lo \
347 core/sys/openbsd/string.lo core/sys/openbsd/sys/cdefs.lo \ 347 core/sys/openbsd/stdlib.lo core/sys/openbsd/string.lo \
348 core/sys/openbsd/sys/elf.lo core/sys/openbsd/sys/elf32.lo \ 348 core/sys/openbsd/sys/cdefs.lo core/sys/openbsd/sys/elf.lo \
349 core/sys/openbsd/sys/elf64.lo \ 349 core/sys/openbsd/sys/elf32.lo core/sys/openbsd/sys/elf64.lo \
350 core/sys/openbsd/sys/elf_common.lo \ 350 core/sys/openbsd/sys/elf_common.lo \
351 core/sys/openbsd/sys/link_elf.lo core/sys/openbsd/sys/mman.lo \ 351 core/sys/openbsd/sys/link_elf.lo core/sys/openbsd/sys/mman.lo \
352 core/sys/openbsd/sys/sysctl.lo core/sys/openbsd/time.lo \ 352 core/sys/openbsd/sys/sysctl.lo core/sys/openbsd/time.lo \
@@ -367,9 +367,9 @@ am__objects_18 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
367 core/sys/linux/sys/procfs.lo core/sys/linux/sys/signalfd.lo \ 367 core/sys/linux/sys/procfs.lo core/sys/linux/sys/signalfd.lo \
368 core/sys/linux/sys/socket.lo core/sys/linux/sys/sysinfo.lo \ 368 core/sys/linux/sys/socket.lo core/sys/linux/sys/sysinfo.lo \
369 core/sys/linux/sys/time.lo core/sys/linux/sys/xattr.lo \ 369 core/sys/linux/sys/time.lo core/sys/linux/sys/xattr.lo \
370 core/sys/linux/termios.lo core/sys/linux/time.lo \ 370 core/sys/linux/syscalls.lo core/sys/linux/termios.lo \
371 core/sys/linux/timerfd.lo core/sys/linux/tipc.lo \ 371 core/sys/linux/time.lo core/sys/linux/timerfd.lo \
372 core/sys/linux/unistd.lo 372 core/sys/linux/tipc.lo core/sys/linux/unistd.lo
373@DRUNTIME_OS_LINUX_TRUE@am__objects_19 = $(am__objects_18) 373@DRUNTIME_OS_LINUX_TRUE@am__objects_19 = $(am__objects_18)
374am__objects_20 = core/sys/windows/accctrl.lo \ 374am__objects_20 = core/sys/windows/accctrl.lo \
375 core/sys/windows/aclapi.lo core/sys/windows/aclui.lo \ 375 core/sys/windows/aclapi.lo core/sys/windows/aclui.lo \
@@ -944,8 +944,9 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
944 core/sys/linux/sys/procfs.d core/sys/linux/sys/signalfd.d \ 944 core/sys/linux/sys/procfs.d core/sys/linux/sys/signalfd.d \
945 core/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \ 945 core/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \
946 core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \ 946 core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \
947 core/sys/linux/termios.d core/sys/linux/time.d \ 947 core/sys/linux/syscalls.d core/sys/linux/termios.d \
948 core/sys/linux/timerfd.d core/sys/linux/tipc.d core/sys/linux/unistd.d 948 core/sys/linux/time.d core/sys/linux/timerfd.d core/sys/linux/tipc.d \
949 core/sys/linux/unistd.d
949 950
950DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \ 951DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
951 core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \ 952 core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \
@@ -958,12 +959,13 @@ DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
958 959
959DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \ 960DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \
960 core/sys/openbsd/err.d core/sys/openbsd/execinfo.d \ 961 core/sys/openbsd/err.d core/sys/openbsd/execinfo.d \
961 core/sys/openbsd/stdlib.d core/sys/openbsd/string.d \ 962 core/sys/openbsd/pthread_np.d core/sys/openbsd/stdlib.d \
962 core/sys/openbsd/sys/cdefs.d core/sys/openbsd/sys/elf.d \ 963 core/sys/openbsd/string.d core/sys/openbsd/sys/cdefs.d \
963 core/sys/openbsd/sys/elf32.d core/sys/openbsd/sys/elf64.d \ 964 core/sys/openbsd/sys/elf.d core/sys/openbsd/sys/elf32.d \
964 core/sys/openbsd/sys/elf_common.d core/sys/openbsd/sys/link_elf.d \ 965 core/sys/openbsd/sys/elf64.d core/sys/openbsd/sys/elf_common.d \
965 core/sys/openbsd/sys/mman.d core/sys/openbsd/sys/sysctl.d \ 966 core/sys/openbsd/sys/link_elf.d core/sys/openbsd/sys/mman.d \
966 core/sys/openbsd/time.d core/sys/openbsd/unistd.d 967 core/sys/openbsd/sys/sysctl.d core/sys/openbsd/time.d \
968 core/sys/openbsd/unistd.d
967 969
968DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \ 970DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \
969 core/sys/posix/arpa/inet.d core/sys/posix/config.d \ 971 core/sys/posix/arpa/inet.d core/sys/posix/config.d \
@@ -1616,6 +1618,7 @@ core/sys/openbsd/$(am__dirstamp):
1616core/sys/openbsd/dlfcn.lo: core/sys/openbsd/$(am__dirstamp) 1618core/sys/openbsd/dlfcn.lo: core/sys/openbsd/$(am__dirstamp)
1617core/sys/openbsd/err.lo: core/sys/openbsd/$(am__dirstamp) 1619core/sys/openbsd/err.lo: core/sys/openbsd/$(am__dirstamp)
1618core/sys/openbsd/execinfo.lo: core/sys/openbsd/$(am__dirstamp) 1620core/sys/openbsd/execinfo.lo: core/sys/openbsd/$(am__dirstamp)
1621core/sys/openbsd/pthread_np.lo: core/sys/openbsd/$(am__dirstamp)
1619core/sys/openbsd/stdlib.lo: core/sys/openbsd/$(am__dirstamp) 1622core/sys/openbsd/stdlib.lo: core/sys/openbsd/$(am__dirstamp)
1620core/sys/openbsd/string.lo: core/sys/openbsd/$(am__dirstamp) 1623core/sys/openbsd/string.lo: core/sys/openbsd/$(am__dirstamp)
1621core/sys/openbsd/sys/$(am__dirstamp): 1624core/sys/openbsd/sys/$(am__dirstamp):
@@ -1672,6 +1675,7 @@ core/sys/linux/sys/socket.lo: core/sys/linux/sys/$(am__dirstamp)
1672core/sys/linux/sys/sysinfo.lo: core/sys/linux/sys/$(am__dirstamp) 1675core/sys/linux/sys/sysinfo.lo: core/sys/linux/sys/$(am__dirstamp)
1673core/sys/linux/sys/time.lo: core/sys/linux/sys/$(am__dirstamp) 1676core/sys/linux/sys/time.lo: core/sys/linux/sys/$(am__dirstamp)
1674core/sys/linux/sys/xattr.lo: core/sys/linux/sys/$(am__dirstamp) 1677core/sys/linux/sys/xattr.lo: core/sys/linux/sys/$(am__dirstamp)
1678core/sys/linux/syscalls.lo: core/sys/linux/$(am__dirstamp)
1675core/sys/linux/termios.lo: core/sys/linux/$(am__dirstamp) 1679core/sys/linux/termios.lo: core/sys/linux/$(am__dirstamp)
1676core/sys/linux/time.lo: core/sys/linux/$(am__dirstamp) 1680core/sys/linux/time.lo: core/sys/linux/$(am__dirstamp)
1677core/sys/linux/timerfd.lo: core/sys/linux/$(am__dirstamp) 1681core/sys/linux/timerfd.lo: core/sys/linux/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d
index ad9b44a1ee5..33ca0ddc7bd 100644
--- a/libphobos/libdruntime/core/demangle.d
+++ b/libphobos/libdruntime/core/demangle.d
@@ -346,6 +346,13 @@ pure @safe:
346 } 346 }
347 347
348 348
349 void popFront(int i)
350 {
351 while (i--)
352 popFront();
353 }
354
355
349 void match( char val ) 356 void match( char val )
350 { 357 {
351 test( val ); 358 test( val );
@@ -636,6 +643,7 @@ pure @safe:
636 TypeDelegate 643 TypeDelegate
637 TypeNone 644 TypeNone
638 TypeVoid 645 TypeVoid
646 TypeNoreturn
639 TypeByte 647 TypeByte
640 TypeUbyte 648 TypeUbyte
641 TypeShort 649 TypeShort
@@ -715,6 +723,9 @@ pure @safe:
715 TypeVoid: 723 TypeVoid:
716 v 724 v
717 725
726 TypeNoreturn
727 Nn
728
718 TypeByte: 729 TypeByte:
719 g 730 g
720 731
@@ -873,6 +884,10 @@ pure @safe:
873 popFront(); 884 popFront();
874 switch ( front ) 885 switch ( front )
875 { 886 {
887 case 'n': // Noreturn
888 popFront();
889 put("noreturn");
890 return dst[beg .. len];
876 case 'g': // Wild (Ng Type) 891 case 'g': // Wild (Ng Type)
877 popFront(); 892 popFront();
878 // TODO: Anything needed here? 893 // TODO: Anything needed here?
@@ -1164,9 +1179,11 @@ pure @safe:
1164 case 'g': 1179 case 'g':
1165 case 'h': 1180 case 'h':
1166 case 'k': 1181 case 'k':
1182 case 'n':
1167 // NOTE: The inout parameter type is represented as "Ng". 1183 // NOTE: The inout parameter type is represented as "Ng".
1168 // The vector parameter type is represented as "Nh". 1184 // The vector parameter type is represented as "Nh".
1169 // The return parameter type is represented as "Nk". 1185 // The return parameter type is represented as "Nk".
1186 // The noreturn parameter type is represented as "Nn".
1170 // These make it look like a FuncAttr, but infact 1187 // These make it look like a FuncAttr, but infact
1171 // if we see these, then we know we're really in 1188 // if we see these, then we know we're really in
1172 // the parameter list. Rewind and break. 1189 // the parameter list. Rewind and break.
@@ -1217,6 +1234,59 @@ pure @safe:
1217 break; 1234 break;
1218 } 1235 }
1219 putComma(n); 1236 putComma(n);
1237
1238 /* Do special return, scope, ref, out combinations
1239 */
1240 int npops;
1241 if ( 'M' == front && peek(1) == 'N' && peek(2) == 'k')
1242 {
1243 const c3 = peek(3);
1244 if (c3 == 'J')
1245 {
1246 put("scope return out "); // MNkJ
1247 npops = 4;
1248 }
1249 else if (c3 == 'K')
1250 {
1251 put("scope return ref "); // MNkK
1252 npops = 4;
1253 }
1254 }
1255 else if ('N' == front && peek(1) == 'k')
1256 {
1257 const c2 = peek(2);
1258 if (c2 == 'J')
1259 {
1260 put("return out "); // NkJ
1261 npops = 3;
1262 }
1263 else if (c2 == 'K')
1264 {
1265 put("return ref "); // NkK
1266 npops = 3;
1267 }
1268 else if (c2 == 'M')
1269 {
1270 const c3 = peek(3);
1271 if (c3 == 'J')
1272 {
1273 put("return scope out "); // NkMJ
1274 npops = 4;
1275 }
1276 else if (c3 == 'K')
1277 {
1278 put("return scope ref "); // NkMK
1279 npops = 4;
1280 }
1281 else
1282 {
1283 put("return scope "); // NkM
1284 npops = 3;
1285 }
1286 }
1287 }
1288 popFront(npops);
1289
1220 if ( 'M' == front ) 1290 if ( 'M' == front )
1221 { 1291 {
1222 popFront(); 1292 popFront();
@@ -2558,6 +2628,15 @@ else
2558 `nothrow @trusted ulong std.algorithm.iteration.FilterResult!(std.typecons.Tuple!(int, "a", int, "b", int, "c").` 2628 `nothrow @trusted ulong std.algorithm.iteration.FilterResult!(std.typecons.Tuple!(int, "a", int, "b", int, "c").`
2559 ~`Tuple.rename!([0:"c", 2:"a"]).rename().__lambda1, int[]).FilterResult.__xtoHash(ref const(std.algorithm.iteration.` 2629 ~`Tuple.rename!([0:"c", 2:"a"]).rename().__lambda1, int[]).FilterResult.__xtoHash(ref const(std.algorithm.iteration.`
2560 ~`FilterResult!(std.typecons.Tuple!(int, "a", int, "b", int, "c").Tuple.rename!([0:"c", 2:"a"]).rename().__lambda1, int[]).FilterResult))`], 2630 ~`FilterResult!(std.typecons.Tuple!(int, "a", int, "b", int, "c").Tuple.rename!([0:"c", 2:"a"]).rename().__lambda1, int[]).FilterResult))`],
2631
2632 ["_D4test4rrs1FKPiZv", "void test.rrs1(ref int*)"],
2633 ["_D4test4rrs1FMNkJPiZv", "void test.rrs1(scope return out int*)"],
2634 ["_D4test4rrs1FMNkKPiZv", "void test.rrs1(scope return ref int*)"],
2635 ["_D4test4rrs1FNkJPiZv", "void test.rrs1(return out int*)"],
2636 ["_D4test4rrs1FNkKPiZv", "void test.rrs1(return ref int*)"],
2637 ["_D4test4rrs1FNkMJPiZv", "void test.rrs1(return scope out int*)"],
2638 ["_D4test4rrs1FNkMKPiZv", "void test.rrs1(return scope ref int*)"],
2639 ["_D4test4rrs1FNkMPiZv", "void test.rrs1(return scope int*)"],
2561 ]; 2640 ];
2562 2641
2563 2642
@@ -2621,6 +2700,25 @@ unittest
2621 assert(s.demangle == expected); 2700 assert(s.demangle == expected);
2622} 2701}
2623 2702
2703// https://issues.dlang.org/show_bug.cgi?id=22235
2704unittest
2705{
2706 enum parent = __MODULE__ ~ '.' ~ __traits(identifier, __traits(parent, {}));
2707
2708 static noreturn abort() { assert(false); }
2709 assert(demangle(abort.mangleof) == "pure nothrow @nogc @safe noreturn " ~ parent ~ "().abort()");
2710
2711 static void accept(noreturn) {}
2712 assert(demangle(accept.mangleof) == "pure nothrow @nogc @safe void " ~ parent ~ "().accept(noreturn)");
2713
2714 static void templ(T)(T, T) {}
2715 assert(demangle(templ!noreturn.mangleof) == "pure nothrow @nogc @safe void " ~ parent ~ "().templ!(noreturn).templ(noreturn, noreturn)");
2716
2717 static struct S(T) {}
2718 static void aggr(S!noreturn) { assert(0); }
2719 assert(demangle(aggr.mangleof) == "pure nothrow @nogc @safe void " ~ parent ~ "().aggr(" ~ parent ~ "().S!(noreturn).S)");
2720}
2721
2624/* 2722/*
2625 * 2723 *
2626 */ 2724 */
diff --git a/libphobos/libdruntime/core/exception.d b/libphobos/libdruntime/core/exception.d
index fe298d4a09f..a6928660773 100644
--- a/libphobos/libdruntime/core/exception.d
+++ b/libphobos/libdruntime/core/exception.d
@@ -97,7 +97,7 @@ class ArrayIndexError : RangeError
97 this.length = length; 97 this.length = length;
98 98
99 // Constructing the message is a bit clumsy: 99 // Constructing the message is a bit clumsy:
100 // It's essentially `printf("index [%zu] exceeds array of length [%zu]", index, length)`, 100 // It's essentially `printf("index [%zu] is out of bounds for array of length [%zu]", index, length)`,
101 // but even `snprintf` isn't `pure`. 101 // but even `snprintf` isn't `pure`.
102 // Also string concatenation isn't `@nogc`, and casting to/from immutable isn't `@safe` 102 // Also string concatenation isn't `@nogc`, and casting to/from immutable isn't `@safe`
103 import core.internal.string : unsignedToTempString; 103 import core.internal.string : unsignedToTempString;
@@ -106,8 +106,7 @@ class ArrayIndexError : RangeError
106 char[] sink = buf[]; 106 char[] sink = buf[];
107 sink.rangeMsgPut("index ["); 107 sink.rangeMsgPut("index [");
108 sink.rangeMsgPut(unsignedToTempString!10(index, tmpBuf)); 108 sink.rangeMsgPut(unsignedToTempString!10(index, tmpBuf));
109 sink.rangeMsgPut("]"); 109 sink.rangeMsgPut("] is out of bounds for array of length ");
110 sink.rangeMsgPut(" exceeds array of length ");
111 sink.rangeMsgPut(unsignedToTempString!10(length, tmpBuf)); 110 sink.rangeMsgPut(unsignedToTempString!10(length, tmpBuf));
112 this.msgBuf = buf; 111 this.msgBuf = buf;
113 super(msgBuf[0..$-sink.length], file, line, next); 112 super(msgBuf[0..$-sink.length], file, line, next);
@@ -116,7 +115,7 @@ class ArrayIndexError : RangeError
116 115
117@safe pure unittest 116@safe pure unittest
118{ 117{
119 assert(new ArrayIndexError(900, 700).msg == "index [900] exceeds array of length 700"); 118 assert(new ArrayIndexError(900, 700).msg == "index [900] is out of bounds for array of length 700");
120 // Ensure msg buffer doesn't overflow on large numbers 119 // Ensure msg buffer doesn't overflow on large numbers
121 assert(new ArrayIndexError(size_t.max, size_t.max-1).msg); 120 assert(new ArrayIndexError(size_t.max, size_t.max-1).msg);
122} 121}
@@ -836,12 +835,24 @@ extern (C)
836 onArraySliceError(lower, upper, length, file[0 .. strlen(file)], line); 835 onArraySliceError(lower, upper, length, file[0 .. strlen(file)], line);
837 } 836 }
838 837
838 /// ditto
839 void _d_arraybounds_slice(string file, uint line, size_t lower, size_t upper, size_t length)
840 {
841 onArraySliceError(lower, upper, length, file, line);
842 }
843
839 /// Called when an out of range array index is accessed 844 /// Called when an out of range array index is accessed
840 void _d_arraybounds_indexp(immutable(char*) file, uint line, size_t index, size_t length) 845 void _d_arraybounds_indexp(immutable(char*) file, uint line, size_t index, size_t length)
841 { 846 {
842 import core.stdc.string : strlen; 847 import core.stdc.string : strlen;
843 onArrayIndexError(index, length, file[0 .. strlen(file)], line); 848 onArrayIndexError(index, length, file[0 .. strlen(file)], line);
844 } 849 }
850
851 /// ditto
852 void _d_arraybounds_index(string file, uint line, size_t index, size_t length)
853 {
854 onArrayIndexError(index, length, file, line);
855 }
845} 856}
846 857
847// TLS storage shared for all errors, chaining might create circular reference 858// TLS storage shared for all errors, chaining might create circular reference
diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d
index b58ed51557f..9c8223767e1 100644
--- a/libphobos/libdruntime/core/internal/array/construction.d
+++ b/libphobos/libdruntime/core/internal/array/construction.d
@@ -9,44 +9,50 @@
9*/ 9*/
10module core.internal.array.construction; 10module core.internal.array.construction;
11 11
12import core.internal.traits : Unqual;
13
12/** 14/**
13 * Does array initialization (not assignment) from another array of the same element type. 15 * Does array initialization (not assignment) from another array of the same element type.
14 * Params: 16 * Params:
15 * to = what array to initialize
16 * from = what data the array should be initialized with 17 * from = what data the array should be initialized with
17 * Returns: 18 * Returns:
18 * The constructed `to` 19 * The created and initialized array `to`
19 * Bugs: 20 * Bugs:
20 * This function template was ported from a much older runtime hook that bypassed safety, 21 * This function template was ported from a much older runtime hook that bypassed safety,
21 * purity, and throwabilty checks. To prevent breaking existing code, this function template 22 * purity, and throwabilty checks. To prevent breaking existing code, this function template
22 * is temporarily declared `@trusted` until the implementation can be brought up to modern D expectations. 23 * is temporarily declared `@trusted` until the implementation can be brought up to modern D expectations.
23 */ 24 */
24Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted 25Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @trusted
26 if (is(Unqual!T1 == Unqual!T2))
25{ 27{
26 pragma(inline, false); 28 pragma(inline, false);
27 import core.internal.traits : hasElaborateCopyConstructor, Unqual; 29 import core.internal.traits : hasElaborateCopyConstructor;
28 import core.lifetime : copyEmplace; 30 import core.lifetime : copyEmplace;
29 import core.stdc.string : memcpy; 31 import core.stdc.string : memcpy;
30 debug(PRINTF) import core.stdc.stdio; 32 import core.stdc.stdint : uintptr_t;
33 debug(PRINTF) import core.stdc.stdio : printf;
34
35 debug(PRINTF) printf("_d_arrayctor(to = %p,%d, from = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, T1.tsize);
36
37 Tarr1 to = void;
38
39 void[] vFrom = (cast(void*)from.ptr)[0..from.length];
40 void[] vTo = (cast(void*)to.ptr)[0..to.length];
31 41
32 // Force `enforceRawArraysConformable` to be `pure` 42 // Force `enforceRawArraysConformable` to be `pure`
33 void enforceRawArraysConformable(const char[] action, const size_t elementSize, const void[] a1, const void[] a2, in bool allowOverlap = false) @trusted 43 void enforceRawArraysConformable(const char[] action, const size_t elementSize,
44 const void[] a1, const void[] a2) @trusted
34 { 45 {
35 import core.internal.util.array : enforceRawArraysConformable; 46 import core.internal.util.array : enforceRawArraysConformableNogc;
36 47
37 alias Type = void function(const char[] action, const size_t elementSize, const void[] a1, const void[] a2, in bool allowOverlap = false) pure nothrow; 48 alias Type = void function(const char[] action, const size_t elementSize,
38 (cast(Type)&enforceRawArraysConformable)(action, elementSize, a1, a2, allowOverlap); 49 const void[] a1, const void[] a2, in bool allowOverlap = false) @nogc pure nothrow;
50 (cast(Type)&enforceRawArraysConformableNogc)(action, elementSize, a1, a2, false);
39 } 51 }
40 52
41 debug(PRINTF) printf("_d_arrayctor(to = %p,%d, from = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, T.tsize); 53 enforceRawArraysConformable("initialization", T1.sizeof, vFrom, vTo);
42
43 auto element_size = T.sizeof;
44
45 void[] vFrom = (cast(void*)from.ptr)[0..from.length];
46 void[] vTo = (cast(void*)to.ptr)[0..to.length];
47 enforceRawArraysConformable("initialization", element_size, vFrom, vTo, false);
48 54
49 static if (hasElaborateCopyConstructor!T) 55 static if (hasElaborateCopyConstructor!T1)
50 { 56 {
51 size_t i; 57 size_t i;
52 try 58 try
@@ -60,7 +66,7 @@ Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted
60 */ 66 */
61 while (i--) 67 while (i--)
62 { 68 {
63 auto elem = cast(Unqual!T*)&to[i]; 69 auto elem = cast(Unqual!T1*)&to[i];
64 destroy(*elem); 70 destroy(*elem);
65 } 71 }
66 72
@@ -70,7 +76,7 @@ Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted
70 else 76 else
71 { 77 {
72 // blit all elements at once 78 // blit all elements at once
73 memcpy(cast(void*) to.ptr, from.ptr, to.length * T.sizeof); 79 memcpy(cast(void*) to.ptr, from.ptr, to.length * T1.sizeof);
74 } 80 }
75 81
76 return to; 82 return to;
@@ -88,7 +94,7 @@ Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted
88 94
89 S[4] arr1; 95 S[4] arr1;
90 S[4] arr2 = [S(0), S(1), S(2), S(3)]; 96 S[4] arr2 = [S(0), S(1), S(2), S(3)];
91 _d_arrayctor(arr1[], arr2[]); 97 arr1 = _d_arrayctor!(typeof(arr1))(arr2[]);
92 98
93 assert(counter == 4); 99 assert(counter == 4);
94 assert(arr1 == arr2); 100 assert(arr1 == arr2);
@@ -111,7 +117,7 @@ Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted
111 117
112 S[4] arr1; 118 S[4] arr1;
113 S[4] arr2 = [S(0), S(1), S(2), S(3)]; 119 S[4] arr2 = [S(0), S(1), S(2), S(3)];
114 _d_arrayctor(arr1[], arr2[]); 120 arr1 = _d_arrayctor!(typeof(arr1))(arr2[]);
115 121
116 assert(counter == 4); 122 assert(counter == 4);
117 assert(arr1 == arr2); 123 assert(arr1 == arr2);
@@ -137,7 +143,7 @@ Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted
137 { 143 {
138 Throw[4] a; 144 Throw[4] a;
139 Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)]; 145 Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)];
140 _d_arrayctor(a[], b[]); 146 a = _d_arrayctor!(typeof(a))(b[]);
141 } 147 }
142 catch (Exception) 148 catch (Exception)
143 { 149 {
@@ -162,7 +168,7 @@ Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted
162 { 168 {
163 NoThrow[4] a; 169 NoThrow[4] a;
164 NoThrow[4] b = [NoThrow(1), NoThrow(2), NoThrow(3), NoThrow(4)]; 170 NoThrow[4] b = [NoThrow(1), NoThrow(2), NoThrow(3), NoThrow(4)];
165 _d_arrayctor(a[], b[]); 171 a = _d_arrayctor!(typeof(a))(b[]);
166 } 172 }
167 catch (Exception) 173 catch (Exception)
168 { 174 {
@@ -186,7 +192,6 @@ Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted
186void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted 192void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted
187{ 193{
188 pragma(inline, false); 194 pragma(inline, false);
189 import core.internal.traits : Unqual;
190 import core.lifetime : copyEmplace; 195 import core.lifetime : copyEmplace;
191 196
192 size_t i; 197 size_t i;
@@ -269,7 +274,7 @@ void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted
269 { 274 {
270 Throw[4] a; 275 Throw[4] a;
271 Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)]; 276 Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)];
272 _d_arrayctor(a[], b[]); 277 a = _d_arrayctor!(typeof(a))(b[]);
273 } 278 }
274 catch (Exception) 279 catch (Exception)
275 { 280 {
diff --git a/libphobos/libdruntime/core/internal/atomic.d b/libphobos/libdruntime/core/internal/atomic.d
index 3036ea72d15..5daab89a387 100644
--- a/libphobos/libdruntime/core/internal/atomic.d
+++ b/libphobos/libdruntime/core/internal/atomic.d
@@ -104,7 +104,7 @@ version (DigitalMars)
104 pop RBX; 104 pop RBX;
105 ret; 105 ret;
106 } 106 }
107 }, SrcPtr, RetPtr)); 107 }, [SrcPtr, RetPtr]));
108 } 108 }
109 else 109 else
110 { 110 {
@@ -139,7 +139,7 @@ version (DigitalMars)
139 mov %0, src; 139 mov %0, src;
140 lock; cmpxchg [%0], %1; 140 lock; cmpxchg [%0], %1;
141 } 141 }
142 }, SrcReg, ZeroReg, ResReg)); 142 }, [SrcReg, ZeroReg, ResReg]));
143 } 143 }
144 else version (D_InlineAsm_X86_64) 144 else version (D_InlineAsm_X86_64)
145 { 145 {
@@ -159,7 +159,7 @@ version (DigitalMars)
159 lock; cmpxchg [%0], %1; 159 lock; cmpxchg [%0], %1;
160 ret; 160 ret;
161 } 161 }
162 }, SrcReg, ZeroReg, ResReg)); 162 }, [SrcReg, ZeroReg, ResReg]));
163 } 163 }
164 } 164 }
165 else 165 else
@@ -252,7 +252,7 @@ version (DigitalMars)
252 mov %0, dest; 252 mov %0, dest;
253 lock; xadd[%0], %1; 253 lock; xadd[%0], %1;
254 } 254 }
255 }, DestReg, ValReg)); 255 }, [DestReg, ValReg]));
256 } 256 }
257 else version (D_InlineAsm_X86_64) 257 else version (D_InlineAsm_X86_64)
258 { 258 {
@@ -276,7 +276,7 @@ version (DigitalMars)
276 ?2 mov %2, %1; 276 ?2 mov %2, %1;
277 ret; 277 ret;
278 } 278 }
279 }, DestReg, ValReg, ResReg)); 279 }, [DestReg, ValReg, ResReg]));
280 } 280 }
281 else 281 else
282 static assert (false, "Unsupported architecture."); 282 static assert (false, "Unsupported architecture.");
@@ -305,7 +305,7 @@ version (DigitalMars)
305 mov %0, dest; 305 mov %0, dest;
306 xchg [%0], %1; 306 xchg [%0], %1;
307 } 307 }
308 }, DestReg, ValReg)); 308 }, [DestReg, ValReg]));
309 } 309 }
310 else version (D_InlineAsm_X86_64) 310 else version (D_InlineAsm_X86_64)
311 { 311 {
@@ -329,7 +329,7 @@ version (DigitalMars)
329 ?2 mov %2, %1; 329 ?2 mov %2, %1;
330 ret; 330 ret;
331 } 331 }
332 }, DestReg, ValReg, ResReg)); 332 }, [DestReg, ValReg, ResReg]));
333 } 333 }
334 else 334 else
335 static assert (false, "Unsupported architecture."); 335 static assert (false, "Unsupported architecture.");
@@ -362,7 +362,7 @@ version (DigitalMars)
362 setz AL; 362 setz AL;
363 pop %1; 363 pop %1;
364 } 364 }
365 }, DestAddr, CmpAddr, Val, Cmp)); 365 }, [DestAddr, CmpAddr, Val, Cmp]));
366 } 366 }
367 else static if (T.sizeof == 8) 367 else static if (T.sizeof == 8)
368 { 368 {
@@ -421,7 +421,7 @@ version (DigitalMars)
421 xor AL, AL; 421 xor AL, AL;
422 ret; 422 ret;
423 } 423 }
424 }, DestAddr, CmpAddr, Val, Res)); 424 }, [DestAddr, CmpAddr, Val, Res]));
425 } 425 }
426 else 426 else
427 { 427 {
@@ -500,7 +500,7 @@ version (DigitalMars)
500 lock; cmpxchg [%0], %2; 500 lock; cmpxchg [%0], %2;
501 setz AL; 501 setz AL;
502 } 502 }
503 }, DestAddr, Cmp, Val)); 503 }, [DestAddr, Cmp, Val]));
504 } 504 }
505 else static if (T.sizeof == 8) 505 else static if (T.sizeof == 8)
506 { 506 {
@@ -551,7 +551,7 @@ version (DigitalMars)
551 setz AL; 551 setz AL;
552 ret; 552 ret;
553 } 553 }
554 }, DestAddr, Cmp, Val, AXReg)); 554 }, [DestAddr, Cmp, Val, AXReg]));
555 } 555 }
556 else 556 else
557 { 557 {
@@ -1094,7 +1094,7 @@ template needsStoreBarrier( MemoryOrder ms )
1094} 1094}
1095 1095
1096// this is a helper to build asm blocks 1096// this is a helper to build asm blocks
1097string simpleFormat(string format, string[] args...) 1097string simpleFormat(string format, scope string[] args)
1098{ 1098{
1099 string result; 1099 string result;
1100 outer: while (format.length) 1100 outer: while (format.length)
diff --git a/libphobos/libdruntime/core/internal/dassert.d b/libphobos/libdruntime/core/internal/dassert.d
index ac7600f8a03..2c51b8641ae 100644
--- a/libphobos/libdruntime/core/internal/dassert.d
+++ b/libphobos/libdruntime/core/internal/dassert.d
@@ -191,7 +191,7 @@ private string miniFormat(V)(const scope ref V v)
191 } 191 }
192 192
193 // Fall back to a simple cast - we're violating the type system anyways 193 // Fall back to a simple cast - we're violating the type system anyways
194 return miniFormat(__ctfe ? cast(const T) v : *cast(const T*) &v); 194 return miniFormat(*cast(const T*) &v);
195 } 195 }
196 // Format enum members using their name 196 // Format enum members using their name
197 else static if (is(V BaseType == enum)) 197 else static if (is(V BaseType == enum))
diff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
index 0c49955c669..a731d6f7ae4 100644
--- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
+++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
@@ -150,7 +150,11 @@ class ConservativeGC : GC
150 static bool _inFinalizer; 150 static bool _inFinalizer;
151 __gshared bool isPrecise = false; 151 __gshared bool isPrecise = false;
152 152
153 // lock GC, throw InvalidMemoryOperationError on recursive locking during finalization 153 /*
154 * Lock the GC.
155 *
156 * Throws: InvalidMemoryOperationError on recursive locking during finalization.
157 */
154 static void lockNR() @nogc nothrow 158 static void lockNR() @nogc nothrow
155 { 159 {
156 if (_inFinalizer) 160 if (_inFinalizer)
@@ -158,6 +162,12 @@ class ConservativeGC : GC
158 gcLock.lock(); 162 gcLock.lock();
159 } 163 }
160 164
165 /*
166 * Initialize the GC based on command line configuration.
167 *
168 * Throws:
169 * OutOfMemoryError if failed to initialize GC due to not enough memory.
170 */
161 this() 171 this()
162 { 172 {
163 //config is assumed to have already been initialized 173 //config is assumed to have already been initialized
@@ -194,6 +204,10 @@ class ConservativeGC : GC
194 } 204 }
195 205
196 206
207 /**
208 * Enables the GC if disable() was previously called. Must be called
209 * for each time disable was called in order to enable the GC again.
210 */
197 void enable() 211 void enable()
198 { 212 {
199 static void go(Gcx* gcx) nothrow 213 static void go(Gcx* gcx) nothrow
@@ -205,6 +219,9 @@ class ConservativeGC : GC
205 } 219 }
206 220
207 221
222 /**
223 * Disable the GC. The GC may still run if it deems necessary.
224 */
208 void disable() 225 void disable()
209 { 226 {
210 static void go(Gcx* gcx) nothrow 227 static void go(Gcx* gcx) nothrow
@@ -216,6 +233,13 @@ class ConservativeGC : GC
216 233
217 debug (GC_RECURSIVE_LOCK) static bool lockedOnThisThread; 234 debug (GC_RECURSIVE_LOCK) static bool lockedOnThisThread;
218 235
236 /**
237 * Run a function inside a lock/unlock set.
238 *
239 * Params:
240 * func = The function to run.
241 * args = The function arguments.
242 */
219 auto runLocked(alias func, Args...)(auto ref Args args) 243 auto runLocked(alias func, Args...)(auto ref Args args)
220 { 244 {
221 debug(PROFILE_API) immutable tm = (config.profile > 1 ? currTime.ticks : 0); 245 debug(PROFILE_API) immutable tm = (config.profile > 1 ? currTime.ticks : 0);
@@ -248,7 +272,17 @@ class ConservativeGC : GC
248 return res; 272 return res;
249 } 273 }
250 274
251 275 /**
276 * Run a function in an lock/unlock set that keeps track of
277 * how much time was spend inside this function (in ticks)
278 * and how many times this fuction was called.
279 *
280 * Params:
281 * func = The function to run.
282 * time = The variable keeping track of the time (in ticks).
283 * count = The variable keeping track of how many times this fuction was called.
284 * args = The function arguments.
285 */
252 auto runLocked(alias func, alias time, alias count, Args...)(auto ref Args args) 286 auto runLocked(alias func, alias time, alias count, Args...)(auto ref Args args)
253 { 287 {
254 debug(PROFILE_API) immutable tm = (config.profile > 1 ? currTime.ticks : 0); 288 debug(PROFILE_API) immutable tm = (config.profile > 1 ? currTime.ticks : 0);
@@ -287,6 +321,17 @@ class ConservativeGC : GC
287 } 321 }
288 322
289 323
324 /**
325 * Returns a bit field representing all block attributes set for the memory
326 * referenced by p.
327 *
328 * Params:
329 * p = A pointer to the base of a valid memory block or to null.
330 *
331 * Returns:
332 * A bit field containing any bits set for the memory block referenced by
333 * p or zero on error.
334 */
290 uint getAttr(void* p) nothrow 335 uint getAttr(void* p) nothrow
291 { 336 {
292 if (!p) 337 if (!p)
@@ -314,7 +359,20 @@ class ConservativeGC : GC
314 return runLocked!(go, otherTime, numOthers)(gcx, p); 359 return runLocked!(go, otherTime, numOthers)(gcx, p);
315 } 360 }
316 361
317 362 /**
363 * Sets the specified bits for the memory references by p.
364 *
365 * If p was not allocated by the GC, points inside a block, or is null, no
366 * action will be taken.
367 *
368 * Params:
369 * p = A pointer to the base of a valid memory block or to null.
370 * mask = A bit field containing any bits to set for this memory block.
371 *
372 * Returns:
373 * The result of a call to getAttr after the specified bits have been
374 * set.
375 */
318 uint setAttr(void* p, uint mask) nothrow 376 uint setAttr(void* p, uint mask) nothrow
319 { 377 {
320 if (!p) 378 if (!p)
@@ -344,6 +402,20 @@ class ConservativeGC : GC
344 } 402 }
345 403
346 404
405 /**
406 * Clears the specified bits for the memory references by p.
407 *
408 * If p was not allocated by the GC, points inside a block, or is null, no
409 * action will be taken.
410 *
411 * Params:
412 * p = A pointer to the base of a valid memory block or to null.
413 * mask = A bit field containing any bits to clear for this memory block.
414 *
415 * Returns:
416 * The result of a call to getAttr after the specified bits have been
417 * cleared
418 */
347 uint clrAttr(void* p, uint mask) nothrow 419 uint clrAttr(void* p, uint mask) nothrow
348 { 420 {
349 if (!p) 421 if (!p)
@@ -372,8 +444,21 @@ class ConservativeGC : GC
372 return runLocked!(go, otherTime, numOthers)(gcx, p, mask); 444 return runLocked!(go, otherTime, numOthers)(gcx, p, mask);
373 } 445 }
374 446
375 447 /**
376 void *malloc(size_t size, uint bits, const TypeInfo ti) nothrow 448 * Requests an aligned block of managed memory from the garbage collector.
449 *
450 * Params:
451 * size = The desired allocation size in bytes.
452 * bits = A bitmask of the attributes to set on this block.
453 * ti = TypeInfo to describe the memory.
454 *
455 * Returns:
456 * A reference to the allocated memory or null if no memory was requested.
457 *
458 * Throws:
459 * OutOfMemoryError on allocation failure
460 */
461 void *malloc(size_t size, uint bits = 0, const TypeInfo ti = null) nothrow
377 { 462 {
378 if (!size) 463 if (!size)
379 { 464 {
@@ -394,7 +479,7 @@ class ConservativeGC : GC
394 479
395 480
396 // 481 //
397 // 482 // Implementation for malloc and calloc.
398 // 483 //
399 private void *mallocNoSync(size_t size, uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow 484 private void *mallocNoSync(size_t size, uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow
400 { 485 {
@@ -423,7 +508,6 @@ class ConservativeGC : GC
423 return p; 508 return p;
424 } 509 }
425 510
426
427 BlkInfo qalloc( size_t size, uint bits, const scope TypeInfo ti) nothrow 511 BlkInfo qalloc( size_t size, uint bits, const scope TypeInfo ti) nothrow
428 { 512 {
429 513
@@ -446,7 +530,22 @@ class ConservativeGC : GC
446 } 530 }
447 531
448 532
449 void *calloc(size_t size, uint bits, const TypeInfo ti) nothrow 533 /**
534 * Requests an aligned block of managed memory from the garbage collector,
535 * which is initialized with all bits set to zero.
536 *
537 * Params:
538 * size = The desired allocation size in bytes.
539 * bits = A bitmask of the attributes to set on this block.
540 * ti = TypeInfo to describe the memory.
541 *
542 * Returns:
543 * A reference to the allocated memory or null if no memory was requested.
544 *
545 * Throws:
546 * OutOfMemoryError on allocation failure.
547 */
548 void *calloc(size_t size, uint bits = 0, const TypeInfo ti = null) nothrow
450 { 549 {
451 if (!size) 550 if (!size)
452 { 551 {
@@ -466,8 +565,27 @@ class ConservativeGC : GC
466 return p; 565 return p;
467 } 566 }
468 567
469 568 /**
470 void *realloc(void *p, size_t size, uint bits, const TypeInfo ti) nothrow 569 * Request that the GC reallocate a block of memory, attempting to adjust
570 * the size in place if possible. If size is 0, the memory will be freed.
571 *
572 * If p was not allocated by the GC, points inside a block, or is null, no
573 * action will be taken.
574 *
575 * Params:
576 * p = A pointer to the root of a valid memory block or to null.
577 * size = The desired allocation size in bytes.
578 * bits = A bitmask of the attributes to set on this block.
579 * ti = TypeInfo to describe the memory.
580 *
581 * Returns:
582 * A reference to the allocated memory on success or null if size is
583 * zero.
584 *
585 * Throws:
586 * OutOfMemoryError on allocation failure.
587 */
588 void *realloc(void *p, size_t size, uint bits = 0, const TypeInfo ti = null) nothrow
471 { 589 {
472 size_t localAllocSize = void; 590 size_t localAllocSize = void;
473 auto oldp = p; 591 auto oldp = p;
@@ -484,6 +602,8 @@ class ConservativeGC : GC
484 602
485 603
486 // 604 //
605 // The implementation of realloc.
606 //
487 // bits will be set to the resulting bits of the new block 607 // bits will be set to the resulting bits of the new block
488 // 608 //
489 private void *reallocNoSync(void *p, size_t size, ref uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow 609 private void *reallocNoSync(void *p, size_t size, ref uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow
@@ -624,7 +744,7 @@ class ConservativeGC : GC
624 744
625 745
626 // 746 //
627 // 747 // Implementation of extend.
628 // 748 //
629 private size_t extendNoSync(void* p, size_t minsize, size_t maxsize, const TypeInfo ti = null) nothrow 749 private size_t extendNoSync(void* p, size_t minsize, size_t maxsize, const TypeInfo ti = null) nothrow
630 in 750 in
@@ -678,6 +798,16 @@ class ConservativeGC : GC
678 } 798 }
679 799
680 800
801 /**
802 * Requests that at least size bytes of memory be obtained from the operating
803 * system and marked as free.
804 *
805 * Params:
806 * size = The desired size in bytes.
807 *
808 * Returns:
809 * The actual number of bytes reserved or zero on error.
810 */
681 size_t reserve(size_t size) nothrow 811 size_t reserve(size_t size) nothrow
682 { 812 {
683 if (!size) 813 if (!size)
@@ -690,7 +820,7 @@ class ConservativeGC : GC
690 820
691 821
692 // 822 //
693 // 823 // Implementation of reserve
694 // 824 //
695 private size_t reserveNoSync(size_t size) nothrow 825 private size_t reserveNoSync(size_t size) nothrow
696 { 826 {
@@ -701,7 +831,16 @@ class ConservativeGC : GC
701 } 831 }
702 832
703 833
704 void free(void *p) nothrow @nogc 834 /**
835 * Deallocates the memory referenced by p.
836 *
837 * If p was not allocated by the GC, points inside a block, is null, or
838 * if free is called from a finalizer, no action will be taken.
839 *
840 * Params:
841 * p = A pointer to the root of a valid memory block or to null.
842 */
843 void free(void *p) nothrow
705 { 844 {
706 if (!p || _inFinalizer) 845 if (!p || _inFinalizer)
707 { 846 {
@@ -713,7 +852,7 @@ class ConservativeGC : GC
713 852
714 853
715 // 854 //
716 // 855 // Implementation of free.
717 // 856 //
718 private void freeNoSync(void *p) nothrow @nogc 857 private void freeNoSync(void *p) nothrow @nogc
719 { 858 {
@@ -792,7 +931,18 @@ class ConservativeGC : GC
792 } 931 }
793 932
794 933
795 void* addrOf(void *p) nothrow @nogc 934 /**
935 * Determine the base address of the block containing p. If p is not a gc
936 * allocated pointer, return null.
937 *
938 * Params:
939 * p = A pointer to the root or the interior of a valid memory block or to
940 * null.
941 *
942 * Returns:
943 * The base address of the memory block referenced by p or null on error.
944 */
945 void* addrOf(void *p) nothrow
796 { 946 {
797 if (!p) 947 if (!p)
798 { 948 {
@@ -804,7 +954,7 @@ class ConservativeGC : GC
804 954
805 955
806 // 956 //
807 // 957 // Implementation of addrOf.
808 // 958 //
809 void* addrOfNoSync(void *p) nothrow @nogc 959 void* addrOfNoSync(void *p) nothrow @nogc
810 { 960 {
@@ -820,7 +970,17 @@ class ConservativeGC : GC
820 } 970 }
821 971
822 972
823 size_t sizeOf(void *p) nothrow @nogc 973 /**
974 * Determine the allocated size of pointer p. If p is an interior pointer
975 * or not a gc allocated pointer, return 0.
976 *
977 * Params:
978 * p = A pointer to the root of a valid memory block or to null.
979 *
980 * Returns:
981 * The size in bytes of the memory block referenced by p or zero on error.
982 */
983 size_t sizeOf(void *p) nothrow
824 { 984 {
825 if (!p) 985 if (!p)
826 { 986 {
@@ -832,7 +992,7 @@ class ConservativeGC : GC
832 992
833 993
834 // 994 //
835 // 995 // Implementation of sizeOf.
836 // 996 //
837 private size_t sizeOfNoSync(void *p) nothrow @nogc 997 private size_t sizeOfNoSync(void *p) nothrow @nogc
838 { 998 {
@@ -852,6 +1012,18 @@ class ConservativeGC : GC
852 } 1012 }
853 1013
854 1014
1015 /**
1016 * Determine the base address of the block containing p. If p is not a gc
1017 * allocated pointer, return null.
1018 *
1019 * Params:
1020 * p = A pointer to the root or the interior of a valid memory block or to
1021 * null.
1022 *
1023 * Returns:
1024 * Information regarding the memory block referenced by p or BlkInfo.init
1025 * on error.
1026 */
855 BlkInfo query(void *p) nothrow 1027 BlkInfo query(void *p) nothrow
856 { 1028 {
857 if (!p) 1029 if (!p)
@@ -864,7 +1036,7 @@ class ConservativeGC : GC
864 } 1036 }
865 1037
866 // 1038 //
867 // 1039 // Implementation of query
868 // 1040 //
869 BlkInfo queryNoSync(void *p) nothrow 1041 BlkInfo queryNoSync(void *p) nothrow
870 { 1042 {
@@ -884,10 +1056,14 @@ class ConservativeGC : GC
884 1056
885 1057
886 /** 1058 /**
887 * Verify that pointer p: 1059 * Performs certain checks on a pointer. These checks will cause asserts to
888 * 1) belongs to this memory pool 1060 * fail unless the following conditions are met:
889 * 2) points to the start of an allocated piece of memory 1061 * 1) The poiinter belongs to this memory pool.
890 * 3) is not on a free list 1062 * 2) The pointer points to the start of an allocated piece of memory.
1063 * 3) The pointer is not on a free list.
1064 *
1065 * Params:
1066 * p = The pointer to be checked.
891 */ 1067 */
892 void check(void *p) nothrow 1068 void check(void *p) nothrow
893 { 1069 {
@@ -901,7 +1077,7 @@ class ConservativeGC : GC
901 1077
902 1078
903 // 1079 //
904 // 1080 // Implementation of check
905 // 1081 //
906 private void checkNoSync(void *p) nothrow 1082 private void checkNoSync(void *p) nothrow
907 { 1083 {
@@ -939,6 +1115,12 @@ class ConservativeGC : GC
939 } 1115 }
940 1116
941 1117
1118 /**
1119 * Add p to list of roots. If p is null, no operation is performed.
1120 *
1121 * Params:
1122 * p = A pointer into a GC-managed memory block or null.
1123 */
942 void addRoot(void *p) nothrow @nogc 1124 void addRoot(void *p) nothrow @nogc
943 { 1125 {
944 if (!p) 1126 if (!p)
@@ -950,6 +1132,13 @@ class ConservativeGC : GC
950 } 1132 }
951 1133
952 1134
1135 /**
1136 * Remove p from list of roots. If p is null or is not a value
1137 * previously passed to addRoot() then no operation is performed.
1138 *
1139 * Params:
1140 * p = A pointer into a GC-managed memory block or null.
1141 */
953 void removeRoot(void *p) nothrow @nogc 1142 void removeRoot(void *p) nothrow @nogc
954 { 1143 {
955 if (!p) 1144 if (!p)
@@ -960,13 +1149,23 @@ class ConservativeGC : GC
960 gcx.removeRoot(p); 1149 gcx.removeRoot(p);
961 } 1150 }
962 1151
963 1152 /**
1153 * Returns an iterator allowing roots to be traversed via a foreach loop.
1154 */
964 @property RootIterator rootIter() @nogc 1155 @property RootIterator rootIter() @nogc
965 { 1156 {
966 return &gcx.rootsApply; 1157 return &gcx.rootsApply;
967 } 1158 }
968 1159
969 1160
1161 /**
1162 * Add range to scan for roots. If p is null or sz is 0, no operation is performed.
1163 *
1164 * Params:
1165 * p = A pointer to a valid memory address or to null.
1166 * sz = The size in bytes of the block to add.
1167 * ti = TypeInfo to describe the memory.
1168 */
970 void addRange(void *p, size_t sz, const TypeInfo ti = null) nothrow @nogc 1169 void addRange(void *p, size_t sz, const TypeInfo ti = null) nothrow @nogc
971 { 1170 {
972 if (!p || !sz) 1171 if (!p || !sz)
@@ -978,6 +1177,14 @@ class ConservativeGC : GC
978 } 1177 }
979 1178
980 1179
1180 /**
1181 * Remove range from list of ranges. If p is null or does not represent
1182 * a value previously passed to addRange() then no operation is
1183 * performed.
1184 *
1185 * Params:
1186 * p = A pointer to a valid memory address or to null.
1187 */
981 void removeRange(void *p) nothrow @nogc 1188 void removeRange(void *p) nothrow @nogc
982 { 1189 {
983 if (!p) 1190 if (!p)
@@ -989,12 +1196,21 @@ class ConservativeGC : GC
989 } 1196 }
990 1197
991 1198
1199 /**
1200 * Returns an iterator allowing ranges to be traversed via a foreach loop.
1201 */
992 @property RangeIterator rangeIter() @nogc 1202 @property RangeIterator rangeIter() @nogc
993 { 1203 {
994 return &gcx.rangesApply; 1204 return &gcx.rangesApply;
995 } 1205 }
996 1206
997 1207
1208 /**
1209 * Run all finalizers in the code segment.
1210 *
1211 * Params:
1212 * segment = address range of a code segment
1213 */
998 void runFinalizers(const scope void[] segment) nothrow 1214 void runFinalizers(const scope void[] segment) nothrow
999 { 1215 {
1000 static void go(Gcx* gcx, const scope void[] segment) nothrow 1216 static void go(Gcx* gcx, const scope void[] segment) nothrow
@@ -1024,8 +1240,10 @@ class ConservativeGC : GC
1024 1240
1025 1241
1026 /** 1242 /**
1027 * Do full garbage collection. 1243 * Begins a full collection, scanning all stack segments for roots.
1028 * Return number of pages free'd. 1244 *
1245 * Returns:
1246 * The number of pages freed.
1029 */ 1247 */
1030 size_t fullCollect() nothrow 1248 size_t fullCollect() nothrow
1031 { 1249 {
@@ -1054,7 +1272,7 @@ class ConservativeGC : GC
1054 1272
1055 1273
1056 /** 1274 /**
1057 * do full garbage collection ignoring roots 1275 * Begins a full collection while ignoring all stack segments for roots.
1058 */ 1276 */
1059 void fullCollectNoStack() nothrow 1277 void fullCollectNoStack() nothrow
1060 { 1278 {
@@ -1068,6 +1286,9 @@ class ConservativeGC : GC
1068 } 1286 }
1069 1287
1070 1288
1289 /**
1290 * Minimize free space usage.
1291 */
1071 void minimize() nothrow 1292 void minimize() nothrow
1072 { 1293 {
1073 static void go(Gcx* gcx) nothrow 1294 static void go(Gcx* gcx) nothrow
@@ -1109,7 +1330,7 @@ class ConservativeGC : GC
1109 1330
1110 1331
1111 // 1332 //
1112 // 1333 // Implementation of getStats
1113 // 1334 //
1114 private void getStatsNoSync(out core.memory.GC.Stats stats) nothrow 1335 private void getStatsNoSync(out core.memory.GC.Stats stats) nothrow
1115 { 1336 {
diff --git a/libphobos/libdruntime/core/internal/gc/os.d b/libphobos/libdruntime/core/internal/gc/os.d
index ca4cbe2b1c8..64f12033c95 100644
--- a/libphobos/libdruntime/core/internal/gc/os.d
+++ b/libphobos/libdruntime/core/internal/gc/os.d
@@ -213,46 +213,38 @@ else
213 Returns: 213 Returns:
214 true if memory is scarce 214 true if memory is scarce
215*/ 215*/
216// TOOD: get virtual mem sizes and current usage from OS 216// TODO: get virtual mem sizes and current usage from OS
217// TODO: compare current RSS and avail. physical memory 217// TODO: compare current RSS and avail. physical memory
218version (Windows) 218bool isLowOnMem(size_t mapped) nothrow @nogc
219{ 219{
220 bool isLowOnMem(size_t mapped) nothrow @nogc 220 version (Windows)
221 { 221 {
222 version (D_LP64) 222 import core.sys.windows.winbase : GlobalMemoryStatusEx, MEMORYSTATUSEX;
223
224 MEMORYSTATUSEX stat;
225 stat.dwLength = stat.sizeof;
226 const success = GlobalMemoryStatusEx(&stat) != 0;
227 assert(success, "GlobalMemoryStatusEx() failed");
228 if (!success)
223 return false; 229 return false;
224 else 230
225 { 231 // dwMemoryLoad is the 'approximate percentage of physical memory that is in use'
226 import core.sys.windows.winbase : GlobalMemoryStatus, MEMORYSTATUS; 232 // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-memorystatusex
227 MEMORYSTATUS stat; 233 const percentPhysicalRAM = stat.ullTotalPhys / 100;
228 GlobalMemoryStatus(&stat); 234 return (stat.dwMemoryLoad >= 95 && mapped > percentPhysicalRAM)
229 // Less than 5 % of virtual address space available 235 || (stat.dwMemoryLoad >= 90 && mapped > 10 * percentPhysicalRAM);
230 return stat.dwAvailVirtual < stat.dwTotalVirtual / 20;
231 }
232 } 236 }
233} 237 else
234else version (Darwin)
235{
236 bool isLowOnMem(size_t mapped) nothrow @nogc
237 { 238 {
238 enum GB = 2 ^^ 30; 239 enum GB = 2 ^^ 30;
239 version (D_LP64) 240 version (D_LP64)
240 return false; 241 return false;
241 else 242 else version (Darwin)
242 { 243 {
243 // 80 % of available 4GB is used for GC (excluding malloc and mmap) 244 // 80 % of available 4GB is used for GC (excluding malloc and mmap)
244 enum size_t limit = 4UL * GB * 8 / 10; 245 enum size_t limit = 4UL * GB * 8 / 10;
245 return mapped > limit; 246 return mapped > limit;
246 } 247 }
247 }
248}
249else
250{
251 bool isLowOnMem(size_t mapped) nothrow @nogc
252 {
253 enum GB = 2 ^^ 30;
254 version (D_LP64)
255 return false;
256 else 248 else
257 { 249 {
258 // be conservative and assume 3GB 250 // be conservative and assume 3GB
diff --git a/libphobos/libdruntime/core/internal/hash.d b/libphobos/libdruntime/core/internal/hash.d
index e999f0cada9..ef9f1e525c0 100644
--- a/libphobos/libdruntime/core/internal/hash.d
+++ b/libphobos/libdruntime/core/internal/hash.d
@@ -646,13 +646,8 @@ size_t hashOf(T)(T aa) if (!is(T == enum) && __traits(isAssociativeArray, T))
646 size_t h = 0; 646 size_t h = 0;
647 647
648 // The computed hash is independent of the foreach traversal order. 648 // The computed hash is independent of the foreach traversal order.
649 foreach (key, ref val; aa) 649 foreach (ref key, ref val; aa)
650 { 650 h += hashOf(hashOf(val), hashOf(key));
651 size_t[2] hpair;
652 hpair[0] = key.hashOf();
653 hpair[1] = val.hashOf();
654 h += hpair.hashOf();
655 }
656 return h; 651 return h;
657} 652}
658 653
diff --git a/libphobos/libdruntime/core/internal/parseoptions.d b/libphobos/libdruntime/core/internal/parseoptions.d
index 4e5105d82da..99204432374 100644
--- a/libphobos/libdruntime/core/internal/parseoptions.d
+++ b/libphobos/libdruntime/core/internal/parseoptions.d
@@ -4,7 +4,7 @@
4* Copyright: Copyright Digital Mars 2017 4* Copyright: Copyright Digital Mars 2017
5* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 5* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6* 6*
7* Source: $(DRUNTIMESRC src/core/internal/parseoptions.d) 7* Source: $(DRUNTIMESRC core/internal/parseoptions.d)
8*/ 8*/
9 9
10module core.internal.parseoptions; 10module core.internal.parseoptions;
diff --git a/libphobos/libdruntime/core/internal/traits.d b/libphobos/libdruntime/core/internal/traits.d
index 1856eb8b881..60d9be3ac9b 100644
--- a/libphobos/libdruntime/core/internal/traits.d
+++ b/libphobos/libdruntime/core/internal/traits.d
@@ -14,7 +14,7 @@ template Fields(T)
14{ 14{
15 static if (is(T == struct) || is(T == union)) 15 static if (is(T == struct) || is(T == union))
16 alias Fields = typeof(T.tupleof[0 .. $ - __traits(isNested, T)]); 16 alias Fields = typeof(T.tupleof[0 .. $ - __traits(isNested, T)]);
17 else static if (is(T == class)) 17 else static if (is(T == class) || is(T == interface))
18 alias Fields = typeof(T.tupleof); 18 alias Fields = typeof(T.tupleof);
19 else 19 else
20 alias Fields = AliasSeq!T; 20 alias Fields = AliasSeq!T;
@@ -326,7 +326,7 @@ template hasElaborateAssign(S)
326template hasIndirections(T) 326template hasIndirections(T)
327{ 327{
328 static if (is(T == struct) || is(T == union)) 328 static if (is(T == struct) || is(T == union))
329 enum hasIndirections = anySatisfy!(.hasIndirections, Fields!T); 329 enum hasIndirections = anySatisfy!(.hasIndirections, typeof(T.tupleof));
330 else static if (is(T == E[N], E, size_t N)) 330 else static if (is(T == E[N], E, size_t N))
331 enum hasIndirections = T.sizeof && is(E == void) ? true : hasIndirections!(BaseElemOf!E); 331 enum hasIndirections = T.sizeof && is(E == void) ? true : hasIndirections!(BaseElemOf!E);
332 else static if (isFunctionPointer!T) 332 else static if (isFunctionPointer!T)
@@ -367,6 +367,10 @@ unittest
367 static assert( hasUnsharedIndirections!(Foo*)); 367 static assert( hasUnsharedIndirections!(Foo*));
368 static assert(!hasUnsharedIndirections!(shared(Foo)*)); 368 static assert(!hasUnsharedIndirections!(shared(Foo)*));
369 static assert(!hasUnsharedIndirections!(immutable(Foo)*)); 369 static assert(!hasUnsharedIndirections!(immutable(Foo)*));
370
371 int local;
372 struct HasContextPointer { int opCall() { return ++local; } }
373 static assert(hasIndirections!HasContextPointer);
370} 374}
371 375
372enum bool isAggregateType(T) = is(T == struct) || is(T == union) || 376enum bool isAggregateType(T) = is(T == struct) || is(T == union) ||
diff --git a/libphobos/libdruntime/core/internal/util/array.d b/libphobos/libdruntime/core/internal/util/array.d
index bc9b72c1474..6136cfef17d 100644
--- a/libphobos/libdruntime/core/internal/util/array.d
+++ b/libphobos/libdruntime/core/internal/util/array.d
@@ -13,6 +13,17 @@ import core.internal.string;
13import core.stdc.stdint; 13import core.stdc.stdint;
14 14
15 15
16// TLS storage shared for all error messages.
17private align(2 * size_t.sizeof) char[256] _store;
18
19private char[] errorMessage(Args...)(scope const(char*) format,
20 const char[] action, Args args) @trusted
21{
22 import core.stdc.stdio : snprintf;
23 snprintf(&_store[0], _store.sizeof, format, &action[0], args);
24 return _store;
25}
26
16@safe /* pure dmd @@@BUG11461@@@ */ nothrow: 27@safe /* pure dmd @@@BUG11461@@@ */ nothrow:
17 28
18void enforceTypedArraysConformable(T)(const char[] action, 29void enforceTypedArraysConformable(T)(const char[] action,
@@ -65,6 +76,44 @@ private void _enforceNoOverlap(const char[] action,
65 assert(0, msg); 76 assert(0, msg);
66} 77}
67 78
79void enforceTypedArraysConformableNogc(T)(const char[] action,
80 const T[] a1, const T[] a2, const bool allowOverlap = false)
81{
82 _enforceSameLengthNogc(action, a1.length, a2.length);
83 if (!allowOverlap)
84 _enforceNoOverlapNogc(action, arrayToPtr(a1), arrayToPtr(a2), T.sizeof * a1.length);
85}
86
87void enforceRawArraysConformableNogc(const char[] action, const size_t elementSize,
88 const void[] a1, const void[] a2, const bool allowOverlap = false)
89{
90 _enforceSameLengthNogc(action, a1.length, a2.length);
91 if (!allowOverlap)
92 _enforceNoOverlapNogc(action, arrayToPtr(a1), arrayToPtr(a2), elementSize * a1.length);
93}
94
95private void _enforceNoOverlapNogc(const ref char[] action,
96 uintptr_t ptr1, uintptr_t ptr2, const size_t bytes)
97{
98 const d = ptr1 > ptr2 ? ptr1 - ptr2 : ptr2 - ptr1;
99 if (d >= bytes)
100 return;
101 const overlappedBytes = bytes - d;
102
103 assert(0, errorMessage("Overlapping arrays in %s: %zu byte(s) overlap of %zu",
104 action, overlappedBytes, bytes));
105}
106
107private void _enforceSameLengthNogc(const ref char[] action,
108 const size_t length1, const size_t length2)
109{
110 if (length1 == length2)
111 return;
112
113 assert(0, errorMessage("Array lengths don't match for %s: %zu != %zu",
114 action, length1, length2));
115}
116
68private uintptr_t arrayToPtr(const void[] array) @trusted 117private uintptr_t arrayToPtr(const void[] array) @trusted
69{ 118{
70 // Ok because the user will never dereference the pointer 119 // Ok because the user will never dereference the pointer
diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d
index fc47b1d9394..d93b891226c 100644
--- a/libphobos/libdruntime/core/lifetime.d
+++ b/libphobos/libdruntime/core/lifetime.d
@@ -2124,7 +2124,9 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
2124 () @trusted { memset(&source, 0, sz); }(); 2124 () @trusted { memset(&source, 0, sz); }();
2125 else 2125 else
2126 { 2126 {
2127 auto init = typeid(T).initializer(); 2127 import core.internal.lifetime : emplaceInitializer;
2128 ubyte[T.sizeof] init = void;
2129 emplaceInitializer(*(() @trusted { return cast(T*)init.ptr; }()));
2128 () @trusted { memcpy(&source, init.ptr, sz); }(); 2130 () @trusted { memcpy(&source, init.ptr, sz); }();
2129 } 2131 }
2130 } 2132 }
diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d
index bfb72e07b05..b08ec52a246 100644
--- a/libphobos/libdruntime/core/runtime.d
+++ b/libphobos/libdruntime/core/runtime.d
@@ -848,6 +848,7 @@ else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInf
848 version (linux) enum enableDwarf = true; 848 version (linux) enum enableDwarf = true;
849 else version (FreeBSD) enum enableDwarf = true; 849 else version (FreeBSD) enum enableDwarf = true;
850 else version (DragonFlyBSD) enum enableDwarf = true; 850 else version (DragonFlyBSD) enum enableDwarf = true;
851 else version (OpenBSD) enum enableDwarf = true;
851 else version (Darwin) enum enableDwarf = true; 852 else version (Darwin) enum enableDwarf = true;
852 else enum enableDwarf = false; 853 else enum enableDwarf = false;
853 854
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 35e81a25414..2f11a663eb5 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -9,7 +9,7 @@
9 * (See accompanying file LICENSE) 9 * (See accompanying file LICENSE)
10 * Authors: Sean Kelly 10 * Authors: Sean Kelly
11 * Standards: ISO/IEC 9899:1999 (E) 11 * Standards: ISO/IEC 9899:1999 (E)
12 * Source: $(DRUNTIMESRC src/core/stdc/_stdlib.d) 12 * Source: $(DRUNTIMESRC core/stdc/_stdlib.d)
13 */ 13 */
14 14
15module core.stdc.stdlib; 15module core.stdc.stdlib;
diff --git a/libphobos/libdruntime/core/sync/rwmutex.d b/libphobos/libdruntime/core/sync/rwmutex.d
index 89ef6671e2f..07c5bdbe360 100644
--- a/libphobos/libdruntime/core/sync/rwmutex.d
+++ b/libphobos/libdruntime/core/sync/rwmutex.d
@@ -86,7 +86,7 @@ class ReadWriteMutex
86 * Throws: 86 * Throws:
87 * SyncError on error. 87 * SyncError on error.
88 */ 88 */
89 this( Policy policy = Policy.PREFER_WRITERS ) 89 this( Policy policy = Policy.PREFER_WRITERS ) @safe nothrow
90 { 90 {
91 m_commonMutex = new Mutex; 91 m_commonMutex = new Mutex;
92 if ( !m_commonMutex ) 92 if ( !m_commonMutex )
@@ -105,6 +105,26 @@ class ReadWriteMutex
105 m_writer = new Writer; 105 m_writer = new Writer;
106 } 106 }
107 107
108 /// ditto
109 shared this( Policy policy = Policy.PREFER_WRITERS ) @safe nothrow
110 {
111 m_commonMutex = new shared Mutex;
112 if ( !m_commonMutex )
113 throw new SyncError( "Unable to initialize mutex" );
114
115 m_readerQueue = new shared Condition( m_commonMutex );
116 if ( !m_readerQueue )
117 throw new SyncError( "Unable to initialize mutex" );
118
119 m_writerQueue = new shared Condition( m_commonMutex );
120 if ( !m_writerQueue )
121 throw new SyncError( "Unable to initialize mutex" );
122
123 m_policy = policy;
124 m_reader = new shared Reader;
125 m_writer = new shared Writer;
126 }
127
108 //////////////////////////////////////////////////////////////////////////// 128 ////////////////////////////////////////////////////////////////////////////
109 // General Properties 129 // General Properties
110 //////////////////////////////////////////////////////////////////////////// 130 ////////////////////////////////////////////////////////////////////////////
@@ -116,11 +136,16 @@ class ReadWriteMutex
116 * Returns: 136 * Returns:
117 * The policy used by this mutex. 137 * The policy used by this mutex.
118 */ 138 */
119 @property Policy policy() 139 @property Policy policy() @safe nothrow
120 { 140 {
121 return m_policy; 141 return m_policy;
122 } 142 }
123 143
144 ///ditto
145 @property Policy policy() shared @safe nothrow
146 {
147 return m_policy;
148 }
124 149
125 //////////////////////////////////////////////////////////////////////////// 150 ////////////////////////////////////////////////////////////////////////////
126 // Reader/Writer Handles 151 // Reader/Writer Handles
@@ -133,11 +158,16 @@ class ReadWriteMutex
133 * Returns: 158 * Returns:
134 * A reader sub-mutex. 159 * A reader sub-mutex.
135 */ 160 */
136 @property Reader reader() 161 @property Reader reader() @safe nothrow
137 { 162 {
138 return m_reader; 163 return m_reader;
139 } 164 }
140 165
166 ///ditto
167 @property shared(Reader) reader() shared @safe nothrow
168 {
169 return m_reader;
170 }
141 171
142 /** 172 /**
143 * Gets an object representing the writer lock for the associated mutex. 173 * Gets an object representing the writer lock for the associated mutex.
@@ -145,7 +175,13 @@ class ReadWriteMutex
145 * Returns: 175 * Returns:
146 * A writer sub-mutex. 176 * A writer sub-mutex.
147 */ 177 */
148 @property Writer writer() 178 @property Writer writer() @safe nothrow
179 {
180 return m_writer;
181 }
182
183 ///ditto
184 @property shared(Writer) writer() shared @safe nothrow
149 { 185 {
150 return m_writer; 186 return m_writer;
151 } 187 }
@@ -166,13 +202,13 @@ class ReadWriteMutex
166 /** 202 /**
167 * Initializes a read/write mutex reader proxy object. 203 * Initializes a read/write mutex reader proxy object.
168 */ 204 */
169 this() 205 this(this Q)() @trusted nothrow
206 if (is(Q == Reader) || is(Q == shared Reader))
170 { 207 {
171 m_proxy.link = this; 208 m_proxy.link = this;
172 this.__monitor = &m_proxy; 209 this.__monitor = cast(void*) &m_proxy;
173 } 210 }
174 211
175
176 /** 212 /**
177 * Acquires a read lock on the enclosing mutex. 213 * Acquires a read lock on the enclosing mutex.
178 */ 214 */
@@ -189,6 +225,19 @@ class ReadWriteMutex
189 } 225 }
190 } 226 }
191 227
228 /// ditto
229 @trusted void lock() shared
230 {
231 synchronized( m_commonMutex )
232 {
233 ++(cast()m_numQueuedReaders);
234 scope(exit) --(cast()m_numQueuedReaders);
235
236 while ( shouldQueueReader )
237 m_readerQueue.wait();
238 ++(cast()m_numActiveReaders);
239 }
240 }
192 241
193 /** 242 /**
194 * Releases a read lock on the enclosing mutex. 243 * Releases a read lock on the enclosing mutex.
@@ -205,6 +254,18 @@ class ReadWriteMutex
205 } 254 }
206 } 255 }
207 256
257 /// ditto
258 @trusted void unlock() shared
259 {
260 synchronized( m_commonMutex )
261 {
262 if ( --(cast()m_numActiveReaders) < 1 )
263 {
264 if ( m_numQueuedWriters > 0 )
265 m_writerQueue.notify();
266 }
267 }
268 }
208 269
209 /** 270 /**
210 * Attempts to acquire a read lock on the enclosing mutex. If one can 271 * Attempts to acquire a read lock on the enclosing mutex. If one can
@@ -214,7 +275,7 @@ class ReadWriteMutex
214 * Returns: 275 * Returns:
215 * true if the lock was acquired and false if not. 276 * true if the lock was acquired and false if not.
216 */ 277 */
217 bool tryLock() 278 @trusted bool tryLock()
218 { 279 {
219 synchronized( m_commonMutex ) 280 synchronized( m_commonMutex )
220 { 281 {
@@ -225,6 +286,18 @@ class ReadWriteMutex
225 } 286 }
226 } 287 }
227 288
289 /// ditto
290 @trusted bool tryLock() shared
291 {
292 synchronized( m_commonMutex )
293 {
294 if ( shouldQueueReader )
295 return false;
296 ++(cast()m_numActiveReaders);
297 return true;
298 }
299 }
300
228 /** 301 /**
229 * Attempts to acquire a read lock on the enclosing mutex. If one can 302 * Attempts to acquire a read lock on the enclosing mutex. If one can
230 * be obtained without blocking, the lock is acquired and true is 303 * be obtained without blocking, the lock is acquired and true is
@@ -237,7 +310,7 @@ class ReadWriteMutex
237 * Returns: 310 * Returns:
238 * true if the lock was acquired and false if not. 311 * true if the lock was acquired and false if not.
239 */ 312 */
240 bool tryLock(Duration timeout) 313 @trusted bool tryLock(Duration timeout)
241 { 314 {
242 synchronized( m_commonMutex ) 315 synchronized( m_commonMutex )
243 { 316 {
@@ -270,9 +343,34 @@ class ReadWriteMutex
270 } 343 }
271 } 344 }
272 345
346 /// ditto
347 @trusted bool tryLock(Duration timeout) shared
348 {
349 const initialTime = MonoTime.currTime;
350 synchronized( m_commonMutex )
351 {
352 ++(cast()m_numQueuedReaders);
353 scope(exit) --(cast()m_numQueuedReaders);
354
355 while (shouldQueueReader)
356 {
357 const timeElapsed = MonoTime.currTime - initialTime;
358 if (timeElapsed >= timeout)
359 return false;
360 auto nextWait = timeout - timeElapsed;
361 // Avoid problems calling wait(Duration) with huge arguments.
362 enum maxWaitPerCall = dur!"hours"(24 * 365);
363 m_readerQueue.wait(nextWait < maxWaitPerCall ? nextWait : maxWaitPerCall);
364 }
365 ++(cast()m_numActiveReaders);
366 return true;
367 }
368 }
369
273 370
274 private: 371 private:
275 @property bool shouldQueueReader() 372 @property bool shouldQueueReader(this Q)() nothrow @safe @nogc
373 if (is(Q == Reader) || is(Q == shared Reader))
276 { 374 {
277 if ( m_numActiveWriters > 0 ) 375 if ( m_numActiveWriters > 0 )
278 return true; 376 return true;
@@ -314,10 +412,11 @@ class ReadWriteMutex
314 /** 412 /**
315 * Initializes a read/write mutex writer proxy object. 413 * Initializes a read/write mutex writer proxy object.
316 */ 414 */
317 this() 415 this(this Q)() @trusted nothrow
416 if (is(Q == Writer) || is(Q == shared Writer))
318 { 417 {
319 m_proxy.link = this; 418 m_proxy.link = this;
320 this.__monitor = &m_proxy; 419 this.__monitor = cast(void*) &m_proxy;
321 } 420 }
322 421
323 422
@@ -337,6 +436,20 @@ class ReadWriteMutex
337 } 436 }
338 } 437 }
339 438
439 /// ditto
440 @trusted void lock() shared
441 {
442 synchronized( m_commonMutex )
443 {
444 ++(cast()m_numQueuedWriters);
445 scope(exit) --(cast()m_numQueuedWriters);
446
447 while ( shouldQueueWriter )
448 m_writerQueue.wait();
449 ++(cast()m_numActiveWriters);
450 }
451 }
452
340 453
341 /** 454 /**
342 * Releases a write lock on the enclosing mutex. 455 * Releases a write lock on the enclosing mutex.
@@ -366,6 +479,32 @@ class ReadWriteMutex
366 } 479 }
367 } 480 }
368 481
482 /// ditto
483 @trusted void unlock() shared
484 {
485 synchronized( m_commonMutex )
486 {
487 if ( --(cast()m_numActiveWriters) < 1 )
488 {
489 switch ( m_policy )
490 {
491 default:
492 case Policy.PREFER_READERS:
493 if ( m_numQueuedReaders > 0 )
494 m_readerQueue.notifyAll();
495 else if ( m_numQueuedWriters > 0 )
496 m_writerQueue.notify();
497 break;
498 case Policy.PREFER_WRITERS:
499 if ( m_numQueuedWriters > 0 )
500 m_writerQueue.notify();
501 else if ( m_numQueuedReaders > 0 )
502 m_readerQueue.notifyAll();
503 }
504 }
505 }
506 }
507
369 508
370 /** 509 /**
371 * Attempts to acquire a write lock on the enclosing mutex. If one can 510 * Attempts to acquire a write lock on the enclosing mutex. If one can
@@ -375,7 +514,7 @@ class ReadWriteMutex
375 * Returns: 514 * Returns:
376 * true if the lock was acquired and false if not. 515 * true if the lock was acquired and false if not.
377 */ 516 */
378 bool tryLock() 517 @trusted bool tryLock()
379 { 518 {
380 synchronized( m_commonMutex ) 519 synchronized( m_commonMutex )
381 { 520 {
@@ -386,6 +525,18 @@ class ReadWriteMutex
386 } 525 }
387 } 526 }
388 527
528 /// ditto
529 @trusted bool tryLock() shared
530 {
531 synchronized( m_commonMutex )
532 {
533 if ( shouldQueueWriter )
534 return false;
535 ++(cast()m_numActiveWriters);
536 return true;
537 }
538 }
539
389 /** 540 /**
390 * Attempts to acquire a write lock on the enclosing mutex. If one can 541 * Attempts to acquire a write lock on the enclosing mutex. If one can
391 * be obtained without blocking, the lock is acquired and true is 542 * be obtained without blocking, the lock is acquired and true is
@@ -398,7 +549,7 @@ class ReadWriteMutex
398 * Returns: 549 * Returns:
399 * true if the lock was acquired and false if not. 550 * true if the lock was acquired and false if not.
400 */ 551 */
401 bool tryLock(Duration timeout) 552 @trusted bool tryLock(Duration timeout)
402 { 553 {
403 synchronized( m_commonMutex ) 554 synchronized( m_commonMutex )
404 { 555 {
@@ -431,8 +582,33 @@ class ReadWriteMutex
431 } 582 }
432 } 583 }
433 584
585 /// ditto
586 @trusted bool tryLock(Duration timeout) shared
587 {
588 const initialTime = MonoTime.currTime;
589 synchronized( m_commonMutex )
590 {
591 ++(cast()m_numQueuedWriters);
592 scope(exit) --(cast()m_numQueuedWriters);
593
594 while (shouldQueueWriter)
595 {
596 const timeElapsed = MonoTime.currTime - initialTime;
597 if (timeElapsed >= timeout)
598 return false;
599 auto nextWait = timeout - timeElapsed;
600 // Avoid problems calling wait(Duration) with huge arguments.
601 enum maxWaitPerCall = dur!"hours"(24 * 365);
602 m_writerQueue.wait(nextWait < maxWaitPerCall ? nextWait : maxWaitPerCall);
603 }
604 ++(cast()m_numActiveWriters);
605 return true;
606 }
607 }
608
434 private: 609 private:
435 @property bool shouldQueueWriter() 610 @property bool shouldQueueWriter(this Q)()
611 if (is(Q == Writer) || is(Q == shared Writer))
436 { 612 {
437 if ( m_numActiveWriters > 0 || 613 if ( m_numActiveWriters > 0 ||
438 m_numActiveReaders > 0 ) 614 m_numActiveReaders > 0 )
@@ -691,3 +867,215 @@ unittest
691 otherThread.join; 867 otherThread.join;
692 } 868 }
693} 869}
870
871unittest
872{
873 import core.atomic, core.thread, core.sync.semaphore;
874
875 static void runTest(ReadWriteMutex.Policy policy)
876 {
877 shared scope mutex = new shared ReadWriteMutex(policy);
878 scope rdSemA = new Semaphore, rdSemB = new Semaphore,
879 wrSemA = new Semaphore, wrSemB = new Semaphore;
880 shared size_t numReaders, numWriters;
881
882 void readerFn()
883 {
884 synchronized (mutex.reader)
885 {
886 atomicOp!"+="(numReaders, 1);
887 rdSemA.notify();
888 rdSemB.wait();
889 atomicOp!"-="(numReaders, 1);
890 }
891 }
892
893 void writerFn()
894 {
895 synchronized (mutex.writer)
896 {
897 atomicOp!"+="(numWriters, 1);
898 wrSemA.notify();
899 wrSemB.wait();
900 atomicOp!"-="(numWriters, 1);
901 }
902 }
903
904 void waitQueued(size_t queuedReaders, size_t queuedWriters)
905 {
906 for (;;)
907 {
908 synchronized (mutex.m_commonMutex)
909 {
910 if (mutex.m_numQueuedReaders == queuedReaders &&
911 mutex.m_numQueuedWriters == queuedWriters)
912 break;
913 }
914 Thread.yield();
915 }
916 }
917
918 scope group = new ThreadGroup;
919
920 // 2 simultaneous readers
921 group.create(&readerFn); group.create(&readerFn);
922 rdSemA.wait(); rdSemA.wait();
923 assert(numReaders == 2);
924 rdSemB.notify(); rdSemB.notify();
925 group.joinAll();
926 assert(numReaders == 0);
927 foreach (t; group) group.remove(t);
928
929 // 1 writer at a time
930 group.create(&writerFn); group.create(&writerFn);
931 wrSemA.wait();
932 assert(!wrSemA.tryWait());
933 assert(numWriters == 1);
934 wrSemB.notify();
935 wrSemA.wait();
936 assert(numWriters == 1);
937 wrSemB.notify();
938 group.joinAll();
939 assert(numWriters == 0);
940 foreach (t; group) group.remove(t);
941
942 // reader and writer are mutually exclusive
943 group.create(&readerFn);
944 rdSemA.wait();
945 group.create(&writerFn);
946 waitQueued(0, 1);
947 assert(!wrSemA.tryWait());
948 assert(numReaders == 1 && numWriters == 0);
949 rdSemB.notify();
950 wrSemA.wait();
951 assert(numReaders == 0 && numWriters == 1);
952 wrSemB.notify();
953 group.joinAll();
954 assert(numReaders == 0 && numWriters == 0);
955 foreach (t; group) group.remove(t);
956
957 // writer and reader are mutually exclusive
958 group.create(&writerFn);
959 wrSemA.wait();
960 group.create(&readerFn);
961 waitQueued(1, 0);
962 assert(!rdSemA.tryWait());
963 assert(numReaders == 0 && numWriters == 1);
964 wrSemB.notify();
965 rdSemA.wait();
966 assert(numReaders == 1 && numWriters == 0);
967 rdSemB.notify();
968 group.joinAll();
969 assert(numReaders == 0 && numWriters == 0);
970 foreach (t; group) group.remove(t);
971
972 // policy determines whether queued reader or writers progress first
973 group.create(&writerFn);
974 wrSemA.wait();
975 group.create(&readerFn);
976 group.create(&writerFn);
977 waitQueued(1, 1);
978 assert(numReaders == 0 && numWriters == 1);
979 wrSemB.notify();
980
981 if (policy == ReadWriteMutex.Policy.PREFER_READERS)
982 {
983 rdSemA.wait();
984 assert(numReaders == 1 && numWriters == 0);
985 rdSemB.notify();
986 wrSemA.wait();
987 assert(numReaders == 0 && numWriters == 1);
988 wrSemB.notify();
989 }
990 else if (policy == ReadWriteMutex.Policy.PREFER_WRITERS)
991 {
992 wrSemA.wait();
993 assert(numReaders == 0 && numWriters == 1);
994 wrSemB.notify();
995 rdSemA.wait();
996 assert(numReaders == 1 && numWriters == 0);
997 rdSemB.notify();
998 }
999 group.joinAll();
1000 assert(numReaders == 0 && numWriters == 0);
1001 foreach (t; group) group.remove(t);
1002 }
1003 runTest(ReadWriteMutex.Policy.PREFER_READERS);
1004 runTest(ReadWriteMutex.Policy.PREFER_WRITERS);
1005}
1006
1007unittest
1008{
1009 import core.atomic, core.thread;
1010 shared static ReadWriteMutex rwmutex;
1011 shared static bool threadTriedOnceToGetLock;
1012 shared static bool threadFinallyGotLock;
1013
1014 rwmutex = new shared ReadWriteMutex();
1015 atomicFence;
1016 const maxTimeAllowedForTest = dur!"seconds"(20);
1017 // Test ReadWriteMutex.Reader.tryLock(Duration).
1018 {
1019 static void testReaderTryLock()
1020 {
1021 assert(!rwmutex.reader.tryLock(Duration.min));
1022 threadTriedOnceToGetLock.atomicStore(true);
1023 assert(rwmutex.reader.tryLock(Duration.max));
1024 threadFinallyGotLock.atomicStore(true);
1025 rwmutex.reader.unlock;
1026 }
1027 assert(rwmutex.writer.tryLock(Duration.zero), "should have been able to obtain lock without blocking");
1028 auto otherThread = new Thread(&testReaderTryLock).start;
1029 const failIfThisTimeisReached = MonoTime.currTime + maxTimeAllowedForTest;
1030 Thread.yield;
1031 // We started otherThread with the writer lock held so otherThread's
1032 // first rwlock.reader.tryLock with timeout Duration.min should fail.
1033 while (!threadTriedOnceToGetLock.atomicLoad)
1034 {
1035 assert(MonoTime.currTime < failIfThisTimeisReached, "timed out");
1036 Thread.yield;
1037 }
1038 rwmutex.writer.unlock;
1039 // Soon after we release the writer lock otherThread's second
1040 // rwlock.reader.tryLock with timeout Duration.max should succeed.
1041 while (!threadFinallyGotLock.atomicLoad)
1042 {
1043 assert(MonoTime.currTime < failIfThisTimeisReached, "timed out");
1044 Thread.yield;
1045 }
1046 otherThread.join;
1047 }
1048 threadTriedOnceToGetLock.atomicStore(false); // Reset.
1049 threadFinallyGotLock.atomicStore(false); // Reset.
1050 // Test ReadWriteMutex.Writer.tryLock(Duration).
1051 {
1052 static void testWriterTryLock()
1053 {
1054 assert(!rwmutex.writer.tryLock(Duration.min));
1055 threadTriedOnceToGetLock.atomicStore(true);
1056 assert(rwmutex.writer.tryLock(Duration.max));
1057 threadFinallyGotLock.atomicStore(true);
1058 rwmutex.writer.unlock;
1059 }
1060 assert(rwmutex.reader.tryLock(Duration.zero), "should have been able to obtain lock without blocking");
1061 auto otherThread = new Thread(&testWriterTryLock).start;
1062 const failIfThisTimeisReached = MonoTime.currTime + maxTimeAllowedForTest;
1063 Thread.yield;
1064 // We started otherThread with the reader lock held so otherThread's
1065 // first rwlock.writer.tryLock with timeout Duration.min should fail.
1066 while (!threadTriedOnceToGetLock.atomicLoad)
1067 {
1068 assert(MonoTime.currTime < failIfThisTimeisReached, "timed out");
1069 Thread.yield;
1070 }
1071 rwmutex.reader.unlock;
1072 // Soon after we release the reader lock otherThread's second
1073 // rwlock.writer.tryLock with timeout Duration.max should succeed.
1074 while (!threadFinallyGotLock.atomicLoad)
1075 {
1076 assert(MonoTime.currTime < failIfThisTimeisReached, "timed out");
1077 Thread.yield;
1078 }
1079 otherThread.join;
1080 }
1081}
diff --git a/libphobos/libdruntime/core/sys/freebsd/config.d b/libphobos/libdruntime/core/sys/freebsd/config.d
index 4eda066b293..5e3129e2422 100644
--- a/libphobos/libdruntime/core/sys/freebsd/config.d
+++ b/libphobos/libdruntime/core/sys/freebsd/config.d
@@ -13,7 +13,9 @@ public import core.sys.posix.config;
13// __FreeBSD_version numbers are documented in the Porter's Handbook. 13// __FreeBSD_version numbers are documented in the Porter's Handbook.
14// NOTE: When adding newer versions of FreeBSD, verify all current versioned 14// NOTE: When adding newer versions of FreeBSD, verify all current versioned
15// bindings are still compatible with the release. 15// bindings are still compatible with the release.
16 version (FreeBSD_12) enum __FreeBSD_version = 1202000; 16
17 version (FreeBSD_13) enum __FreeBSD_version = 1300000;
18else version (FreeBSD_12) enum __FreeBSD_version = 1202000;
17else version (FreeBSD_11) enum __FreeBSD_version = 1104000; 19else version (FreeBSD_11) enum __FreeBSD_version = 1104000;
18else version (FreeBSD_10) enum __FreeBSD_version = 1004000; 20else version (FreeBSD_10) enum __FreeBSD_version = 1004000;
19else version (FreeBSD_9) enum __FreeBSD_version = 903000; 21else version (FreeBSD_9) enum __FreeBSD_version = 903000;
diff --git a/libphobos/libdruntime/core/sys/linux/fs.d b/libphobos/libdruntime/core/sys/linux/fs.d
index 5faa7564d1b..c5525066969 100644
--- a/libphobos/libdruntime/core/sys/linux/fs.d
+++ b/libphobos/libdruntime/core/sys/linux/fs.d
@@ -154,39 +154,42 @@ enum {
154 S_XFLAG_HASATTR = 0x80000000, /// no DIFLAG for this 154 S_XFLAG_HASATTR = 0x80000000, /// no DIFLAG for this
155} 155}
156 156
157enum BLKROSET = _IO(0x12, 93); /// set device read-only 157static if (__traits(compiles, _IO(1, 2)))
158enum BLKROGET = _IO(0x12, 94); /// get read-only status 158{
159enum BLKRRPART = _IO(0x12, 95); /// re-read partition table 159 enum BLKROSET = _IO(0x12, 93); /// set device read-only
160enum BLKGETSIZE = _IO(0x12, 96); /// return device size 160 enum BLKROGET = _IO(0x12, 94); /// get read-only status
161enum BLKFLSBUF = _IO(0x12, 97); /// flush buffer cache 161 enum BLKRRPART = _IO(0x12, 95); /// re-read partition table
162enum BLKRASET = _IO(0x12, 98); /// set read ahead for block device 162 enum BLKGETSIZE = _IO(0x12, 96); /// return device size
163enum BLKRAGET = _IO(0x12, 99); /// get current read ahead setting 163 enum BLKFLSBUF = _IO(0x12, 97); /// flush buffer cache
164enum BLKFRASET = _IO(0x12, 100); /// set filesystem 164 enum BLKRASET = _IO(0x12, 98); /// set read ahead for block device
165enum BLKFRAGET = _IO(0x12, 101); /// get filesystem 165 enum BLKRAGET = _IO(0x12, 99); /// get current read ahead setting
166enum BLKSECTSET = _IO(0x12, 102); /// set max sectors per request 166 enum BLKFRASET = _IO(0x12, 100); /// set filesystem
167enum BLKSECTGET = _IO(0x12, 103); /// get max sectors per request 167 enum BLKFRAGET = _IO(0x12, 101); /// get filesystem
168enum BLKSSZGET = _IO(0x12, 104); /// get block device sector size 168 enum BLKSECTSET = _IO(0x12, 102); /// set max sectors per request
169 enum BLKSECTGET = _IO(0x12, 103); /// get max sectors per request
170 enum BLKSSZGET = _IO(0x12, 104); /// get block device sector size
169 171
170 172
171enum BLKBSZGET = _IOR!size_t(0x12, 112); 173 enum BLKBSZGET = _IOR!size_t(0x12, 112);
172enum BLKBSZSET = _IOW!size_t(0x12, 113); 174 enum BLKBSZSET = _IOW!size_t(0x12, 113);
173enum BLKGETSIZE64 = _IOR!size_t(0x12, 114); 175 enum BLKGETSIZE64 = _IOR!size_t(0x12, 114);
174enum BLKTRACESTART = _IO(0x12, 116); 176 enum BLKTRACESTART = _IO(0x12, 116);
175enum BLKTRACESTOP = _IO(0x12, 117); 177 enum BLKTRACESTOP = _IO(0x12, 117);
176enum BLKTRACETEARDOWN = _IO(0x12, 118); 178 enum BLKTRACETEARDOWN = _IO(0x12, 118);
177enum BLKDISCARD = _IO(0x12, 119); 179 enum BLKDISCARD = _IO(0x12, 119);
178enum BLKIOMIN = _IO(0x12, 120); 180 enum BLKIOMIN = _IO(0x12, 120);
179enum BLKIOOPT = _IO(0x12, 121); 181 enum BLKIOOPT = _IO(0x12, 121);
180enum BLKALIGNOFF = _IO(0x12, 122); 182 enum BLKALIGNOFF = _IO(0x12, 122);
181enum BLKPBSZGET = _IO(0x12, 123); 183 enum BLKPBSZGET = _IO(0x12, 123);
182enum BLKDISCARDZEROES = _IO(0x12, 124); 184 enum BLKDISCARDZEROES = _IO(0x12, 124);
183enum BLKSECDISCARD = _IO(0x12, 125); 185 enum BLKSECDISCARD = _IO(0x12, 125);
184enum BLKROTATIONAL = _IO(0x12, 126); 186 enum BLKROTATIONAL = _IO(0x12, 126);
185enum BLKZEROOUT = _IO(0x12, 127); 187 enum BLKZEROOUT = _IO(0x12, 127);
186 188
187enum BMAP_IOCTL = 1; /// obsolete - kept for compatibility 189 enum BMAP_IOCTL = 1; /// obsolete - kept for compatibility
188enum FIBMAP = _IO(0x00, 1); /// bmap access 190 enum FIBMAP = _IO(0x00, 1); /// bmap access
189enum FIGETBSZ = _IO(0x00, 2); /// get the block size used for bmap 191 enum FIGETBSZ = _IO(0x00, 2); /// get the block size used for bmap
192}
190 193
191enum FSLABEL_MAX = 256; /// Max chars for the interface; each fs may differ 194enum FSLABEL_MAX = 256; /// Max chars for the interface; each fs may differ
192 195
diff --git a/libphobos/libdruntime/core/sys/linux/perf_event.d b/libphobos/libdruntime/core/sys/linux/perf_event.d
index 805b47e6e33..9e96a7f5f43 100644
--- a/libphobos/libdruntime/core/sys/linux/perf_event.d
+++ b/libphobos/libdruntime/core/sys/linux/perf_event.d
@@ -2073,8 +2073,6 @@ else
2073 2073
2074 struct 2074 struct
2075 { 2075 {
2076 import std.bitmanip : bitfields;
2077
2078 /* mixin(bitfields!(ulong, "mem_rsvd", 24, ulong, "mem_snoopx", 2, ulong, 2076 /* mixin(bitfields!(ulong, "mem_rsvd", 24, ulong, "mem_snoopx", 2, ulong,
2079 "mem_remote", 1, ulong, "mem_lvl_num", 4, ulong, "mem_dtlb", 7, ulong, 2077 "mem_remote", 1, ulong, "mem_lvl_num", 4, ulong, "mem_dtlb", 7, ulong,
2080 "mem_lock", 2, ulong, "mem_snoop", 5, ulong, "mem_lvl", 2078 "mem_lock", 2, ulong, "mem_snoop", 5, ulong, "mem_lvl",
diff --git a/libphobos/libdruntime/core/sys/linux/sys/mman.d b/libphobos/libdruntime/core/sys/linux/sys/mman.d
index 20e8cf29f8d..a6548a7802c 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/mman.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/mman.d
@@ -32,7 +32,7 @@ public import core.sys.posix.sys.mman;
32import core.sys.linux.config; 32import core.sys.linux.config;
33 33
34// <bits/mman.h> 34// <bits/mman.h>
35// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/powerpc/bits/mman.h 35// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/powerpc/bits/mman.h
36version (PPC_Any) 36version (PPC_Any)
37{ 37{
38 enum PROT_SAO = 0x10; 38 enum PROT_SAO = 0x10;
@@ -57,7 +57,7 @@ version (PPC_Any)
57 // MCL_FUTURE = 0x4000, 57 // MCL_FUTURE = 0x4000,
58 // } 58 // }
59} 59}
60// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/riscv/bits/mman.h 60// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/riscv/bits/mman.h
61else version (RISCV_Any) 61else version (RISCV_Any)
62{ 62{
63 static if (__USE_MISC) enum 63 static if (__USE_MISC) enum
@@ -82,7 +82,7 @@ else version (RISCV_Any)
82 // MCL_FUTURE = 0x4000, 82 // MCL_FUTURE = 0x4000,
83 // } 83 // }
84} 84}
85// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/s390/bits/mman.h 85// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/s390/bits/mman.h
86else version (IBMZ_Any) 86else version (IBMZ_Any)
87{ 87{
88 static if (__USE_MISC) enum 88 static if (__USE_MISC) enum
@@ -98,7 +98,7 @@ else version (IBMZ_Any)
98 MAP_HUGETLB = 0x40000, 98 MAP_HUGETLB = 0x40000,
99 } 99 }
100} 100}
101// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/sh/bits/mman.h 101// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sh/bits/mman.h
102else version (SH) 102else version (SH)
103{ 103{
104 static if (__USE_MISC) enum 104 static if (__USE_MISC) enum
@@ -114,7 +114,7 @@ else version (SH)
114 MAP_HUGETLB = 0x40000, 114 MAP_HUGETLB = 0x40000,
115 } 115 }
116} 116}
117// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/sparc/bits/mman.h 117// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sparc/bits/mman.h
118else version (SPARC_Any) 118else version (SPARC_Any)
119{ 119{
120 static if (__USE_MISC) enum 120 static if (__USE_MISC) enum
@@ -138,7 +138,7 @@ else version (SPARC_Any)
138 // MCL_FUTURE = 0x4000, 138 // MCL_FUTURE = 0x4000,
139 // } 139 // }
140} 140}
141// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/x86/bits/mman.h 141// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86/bits/mman.h
142else version (X86_Any) 142else version (X86_Any)
143{ 143{
144 static if (__USE_MISC) enum MAP_32BIT = 0x40; 144 static if (__USE_MISC) enum MAP_32BIT = 0x40;
@@ -156,7 +156,7 @@ else version (X86_Any)
156 MAP_HUGETLB = 0x40000, 156 MAP_HUGETLB = 0x40000,
157 } 157 }
158} 158}
159// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/aarch64/bits/mman.h 159// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/aarch64/bits/mman.h
160else version (AArch64) 160else version (AArch64)
161{ 161{
162 static if (__USE_MISC) enum 162 static if (__USE_MISC) enum
@@ -172,7 +172,7 @@ else version (AArch64)
172 MAP_HUGETLB = 0x40000, 172 MAP_HUGETLB = 0x40000,
173 } 173 }
174} 174}
175// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/alpha/bits/mman.h 175// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/alpha/bits/mman.h
176else version (Alpha) 176else version (Alpha)
177{ 177{
178 enum 178 enum
@@ -264,7 +264,7 @@ else version (Alpha)
264 // POSIX_MADV_DONTNEED = 6, 264 // POSIX_MADV_DONTNEED = 6,
265 // } 265 // }
266} 266}
267// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/arm/bits/mman.h 267// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/arm/bits/mman.h
268else version (ARM) 268else version (ARM)
269{ 269{
270 static if (__USE_MISC) enum 270 static if (__USE_MISC) enum
@@ -280,7 +280,7 @@ else version (ARM)
280 MAP_HUGETLB = 0x40000, 280 MAP_HUGETLB = 0x40000,
281 } 281 }
282} 282}
283// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/hppa/bits/mman.h 283// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/hppa/bits/mman.h
284else version (HPPA_Any) 284else version (HPPA_Any)
285{ 285{
286 enum 286 enum
@@ -384,7 +384,7 @@ else version (HPPA_Any)
384 // POSIX_MADV_DONTNEED = 4, 384 // POSIX_MADV_DONTNEED = 4,
385 // } 385 // }
386} 386}
387// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/ia64/bits/mman.h 387// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/ia64/bits/mman.h
388else version (IA64) 388else version (IA64)
389{ 389{
390 static if (__USE_MISC) enum 390 static if (__USE_MISC) enum
@@ -401,7 +401,7 @@ else version (IA64)
401 MAP_HUGETLB = 0x40000, 401 MAP_HUGETLB = 0x40000,
402 } 402 }
403} 403}
404// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/m68k/bits/mman.h 404// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/m68k/bits/mman.h
405else version (M68K) 405else version (M68K)
406{ 406{
407 static if (__USE_MISC) enum 407 static if (__USE_MISC) enum
@@ -417,7 +417,7 @@ else version (M68K)
417 MAP_HUGETLB = 0x40000, 417 MAP_HUGETLB = 0x40000,
418 } 418 }
419} 419}
420// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/mips/bits/mman.h 420// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/mips/bits/mman.h
421else version (MIPS_Any) 421else version (MIPS_Any)
422{ 422{
423 static if (__USE_MISC) enum 423 static if (__USE_MISC) enum
@@ -440,7 +440,7 @@ else
440 440
441 441
442// <bits/mman-linux.h> 442// <bits/mman-linux.h>
443// https://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=bits/mman-linux.h 443// https://sourceware.org/git/?p=glibc.git;a=blob;f=bits/mman-linux.h
444version (Alpha) 444version (Alpha)
445{ 445{
446} 446}
@@ -527,12 +527,12 @@ else
527} 527}
528 528
529// Workaround https://issues.dlang.org/show_bug.cgi?id=17883 529// Workaround https://issues.dlang.org/show_bug.cgi?id=17883
530// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/sparc/bits/mman.h 530// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sparc/bits/mman.h
531version (SPARC_Any) 531version (SPARC_Any)
532{ 532{
533 static if (__USE_MISC) enum MAP_RENAME = MAP_ANONYMOUS; 533 static if (__USE_MISC) enum MAP_RENAME = MAP_ANONYMOUS;
534} 534}
535// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/mips/bits/mman.h 535// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/mips/bits/mman.h
536else version (MIPS_Any) 536else version (MIPS_Any)
537{ 537{
538 static if (__USE_MISC) enum MAP_RENAME = MAP_ANONYMOUS; 538 static if (__USE_MISC) enum MAP_RENAME = MAP_ANONYMOUS;
diff --git a/libphobos/libdruntime/core/sys/linux/syscalls.d b/libphobos/libdruntime/core/sys/linux/syscalls.d
new file mode 100644
index 00000000000..8c653719317
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/linux/syscalls.d
@@ -0,0 +1,745 @@
1module core.sys.linux.syscalls;
2
3version (linux):
4extern (C):
5@system:
6nothrow:
7@nogc:
8
9import core.stdc.config : c_long;
10
11version (CoreDdoc)
12{
13 /// Linux system call number from Linux's asm/unistd.h
14 enum SystemCall : c_long;
15}
16else version (X86_64)
17{
18 // https://github.com/torvalds/linux/blob/v4.14/arch/sh/include/uapi/asm/unistd_64.h
19 // https://github.com/torvalds/linux/blob/v4.14/arch/x86/entry/syscalls/syscall_64.tbl
20 enum SystemCall : c_long
21 {
22 read = 0,
23 write = 1,
24 open = 2,
25 close = 3,
26 stat = 4,
27 fstat = 5,
28 lstat = 6,
29 poll = 7,
30 lseek = 8,
31 mmap = 9,
32 mprotect = 10,
33 munmap = 11,
34 brk = 12,
35 rt_sigaction = 13,
36 rt_sigprocmask = 14,
37 rt_sigreturn = 15,
38 ioctl = 16,
39 pread64 = 17,
40 pwrite64 = 18,
41 readv = 19,
42 writev = 20,
43 access = 21,
44 pipe = 22,
45 select = 23,
46 sched_yield = 24,
47 mremap = 25,
48 msync = 26,
49 mincore = 27,
50 madvise = 28,
51 shmget = 29,
52 shmat = 30,
53 shmctl = 31,
54 dup = 32,
55 dup2 = 33,
56 pause = 34,
57 nanosleep = 35,
58 getitimer = 36,
59 alarm = 37,
60 setitimer = 38,
61 getpid = 39,
62 sendfile = 40,
63 socket = 41,
64 connect = 42,
65 accept = 43,
66 sendto = 44,
67 recvfrom = 45,
68 sendmsg = 46,
69 recvmsg = 47,
70 shutdown = 48,
71 bind = 49,
72 listen = 50,
73 getsockname = 51,
74 getpeername = 52,
75 socketpair = 53,
76 setsockopt = 54,
77 getsockopt = 55,
78 clone = 56,
79 fork = 57,
80 vfork = 58,
81 execve = 59,
82 exit = 60,
83 wait4 = 61,
84 kill = 62,
85 uname = 63,
86 semget = 64,
87 semop = 65,
88 semctl = 66,
89 shmdt = 67,
90 msgget = 68,
91 msgsnd = 69,
92 msgrcv = 70,
93 msgctl = 71,
94 fcntl = 72,
95 flock = 73,
96 fsync = 74,
97 fdatasync = 75,
98 truncate = 76,
99 ftruncate = 77,
100 getdents = 78,
101 getcwd = 79,
102 chdir = 80,
103 fchdir = 81,
104 rename = 82,
105 mkdir = 83,
106 rmdir = 84,
107 creat = 85,
108 link = 86,
109 unlink = 87,
110 symlink = 88,
111 readlink = 89,
112 chmod = 90,
113 fchmod = 91,
114 chown = 92,
115 fchown = 93,
116 lchown = 94,
117 umask = 95,
118 gettimeofday = 96,
119 getrlimit = 97,
120 getrusage = 98,
121 sysinfo = 99,
122 times = 100,
123 ptrace = 101,
124 getuid = 102,
125 syslog = 103,
126 getgid = 104,
127 setuid = 105,
128 setgid = 106,
129 geteuid = 107,
130 getegid = 108,
131 setpgid = 109,
132 getppid = 110,
133 getpgrp = 111,
134 setsid = 112,
135 setreuid = 113,
136 setregid = 114,
137 getgroups = 115,
138 setgroups = 116,
139 setresuid = 117,
140 getresuid = 118,
141 setresgid = 119,
142 getresgid = 120,
143 getpgid = 121,
144 setfsuid = 122,
145 setfsgid = 123,
146 getsid = 124,
147 capget = 125,
148 capset = 126,
149 rt_sigpending = 127,
150 rt_sigtimedwait = 128,
151 rt_sigqueueinfo = 129,
152 rt_sigsuspend = 130,
153 sigaltstack = 131,
154 utime = 132,
155 mknod = 133,
156 uselib = 134,
157 personality = 135,
158 ustat = 136,
159 statfs = 137,
160 fstatfs = 138,
161 sysfs = 139,
162 getpriority = 140,
163 setpriority = 141,
164 sched_setparam = 142,
165 sched_getparam = 143,
166 sched_setscheduler = 144,
167 sched_getscheduler = 145,
168 sched_get_priority_max = 146,
169 sched_get_priority_min = 147,
170 sched_rr_get_interval = 148,
171 mlock = 149,
172 munlock = 150,
173 mlockall = 151,
174 munlockall = 152,
175 vhangup = 153,
176 modify_ldt = 154,
177 pivot_root = 155,
178 _sysctl = 156,
179 prctl = 157,
180 arch_prctl = 158,
181 adjtimex = 159,
182 setrlimit = 160,
183 chroot = 161,
184 sync = 162,
185 acct = 163,
186 settimeofday = 164,
187 mount = 165,
188 umount2 = 166,
189 swapon = 167,
190 swapoff = 168,
191 reboot = 169,
192 sethostname = 170,
193 setdomainname = 171,
194 iopl = 172,
195 ioperm = 173,
196 create_module = 174,
197 init_module = 175,
198 delete_module = 176,
199 get_kernel_syms = 177,
200 query_module = 178,
201 quotactl = 179,
202 nfsservctl = 180,
203 getpmsg = 181,
204 putpmsg = 182,
205 afs_syscall = 183,
206 tuxcall = 184,
207 security = 185,
208 gettid = 186,
209 readahead = 187,
210 setxattr = 188,
211 lsetxattr = 189,
212 fsetxattr = 190,
213 getxattr = 191,
214 lgetxattr = 192,
215 fgetxattr = 193,
216 listxattr = 194,
217 llistxattr = 195,
218 flistxattr = 196,
219 removexattr = 197,
220 lremovexattr = 198,
221 fremovexattr = 199,
222 tkill = 200,
223 time = 201,
224 futex = 202,
225 sched_setaffinity = 203,
226 sched_getaffinity = 204,
227 set_thread_area = 205,
228 io_setup = 206,
229 io_destroy = 207,
230 io_getevents = 208,
231 io_submit = 209,
232 io_cancel = 210,
233 get_thread_area = 211,
234 lookup_dcookie = 212,
235 epoll_create = 213,
236 epoll_ctl_old = 214,
237 epoll_wait_old = 215,
238 remap_file_pages = 216,
239 getdents64 = 217,
240 set_tid_address = 218,
241 restart_syscall = 219,
242 semtimedop = 220,
243 fadvise64 = 221,
244 timer_create = 222,
245 timer_settime = 223,
246 timer_gettime = 224,
247 timer_getoverrun = 225,
248 timer_delete = 226,
249 clock_settime = 227,
250 clock_gettime = 228,
251 clock_getres = 229,
252 clock_nanosleep = 230,
253 exit_group = 231,
254 epoll_wait = 232,
255 epoll_ctl = 233,
256 tgkill = 234,
257 utimes = 235,
258 vserver = 236,
259 mbind = 237,
260 set_mempolicy = 238,
261 get_mempolicy = 239,
262 mq_open = 240,
263 mq_unlink = 241,
264 mq_timedsend = 242,
265 mq_timedreceive = 243,
266 mq_notify = 244,
267 mq_getsetattr = 245,
268 kexec_load = 246,
269 waitid = 247,
270 add_key = 248,
271 request_key = 249,
272 keyctl = 250,
273 ioprio_set = 251,
274 ioprio_get = 252,
275 inotify_init = 253,
276 inotify_add_watch = 254,
277 inotify_rm_watch = 255,
278 migrate_pages = 256,
279 openat = 257,
280 mkdirat = 258,
281 mknodat = 259,
282 fchownat = 260,
283 futimesat = 261,
284 newfstatat = 262,
285 unlinkat = 263,
286 renameat = 264,
287 linkat = 265,
288 symlinkat = 266,
289 readlinkat = 267,
290 fchmodat = 268,
291 faccessat = 269,
292 pselect6 = 270,
293 ppoll = 271,
294 unshare = 272,
295 set_robust_list = 273,
296 get_robust_list = 274,
297 splice = 275,
298 tee = 276,
299 sync_file_range = 277,
300 vmsplice = 278,
301 move_pages = 279,
302 utimensat = 280,
303 epoll_pwait = 281,
304 signalfd = 282,
305 timerfd_create = 283,
306 eventfd = 284,
307 fallocate = 285,
308 timerfd_settime = 286,
309 timerfd_gettime = 287,
310 accept4 = 288,
311 signalfd4 = 289,
312 eventfd2 = 290,
313 epoll_create1 = 291,
314 dup3 = 292,
315 pipe2 = 293,
316 inotify_init1 = 294,
317 preadv = 295,
318 pwritev = 296,
319 rt_tgsigqueueinfo = 297,
320 perf_event_open = 298,
321 recvmmsg = 299,
322 fanotify_init = 300,
323 fanotify_mark = 301,
324 prlimit64 = 302,
325 name_to_handle_at = 303,
326 open_by_handle_at = 304,
327 clock_adjtime = 305,
328 syncfs = 306,
329 sendmmsg = 307,
330 setns = 308,
331 getcpu = 309,
332 process_vm_readv = 310,
333 process_vm_writev = 311,
334 kcmp = 312,
335 finit_module = 313,
336 sched_setattr = 314,
337 sched_getattr = 315,
338 renameat2 = 316,
339 seccomp = 317,
340 getrandom = 318,
341 memfd_create = 319,
342 kexec_file_load = 320,
343 bpf = 321,
344 execveat = 322,
345 userfaultfd = 323,
346 membarrier = 324,
347 mlock2 = 325,
348 copy_file_range = 326,
349 preadv2 = 327,
350 pwritev2 = 328,
351 pkey_mprotect = 329,
352 pkey_alloc = 330,
353 pkey_free = 331,
354 statx = 332,
355 }
356}
357else version (X86)
358{
359 // https://github.com/torvalds/linux/blob/master/arch/x86/entry/syscalls/syscall_32.tbl
360 // https://github.com/torvalds/linux/blob/v4.14/arch/sh/include/uapi/asm/unistd_32.h
361 enum SystemCall : c_long
362 {
363 restart_syscall = 0,
364 exit = 1,
365 fork = 2,
366 read = 3,
367 write = 4,
368 open = 5,
369 close = 6,
370 waitpid = 7,
371 creat = 8,
372 link = 9,
373 unlink = 10,
374 execve = 11,
375 chdir = 12,
376 time = 13,
377 mknod = 14,
378 chmod = 15,
379 lchown = 16,
380 break_ = 17,
381 oldstat = 18,
382 lseek = 19,
383 getpid = 20,
384 mount = 21,
385 umount = 22,
386 setuid = 23,
387 getuid = 24,
388 stime = 25,
389 ptrace = 26,
390 alarm = 27,
391 oldfstat = 28,
392 pause = 29,
393 utime = 30,
394 stty = 31,
395 gtty = 32,
396 access = 33,
397 nice = 34,
398 ftime = 35,
399 sync = 36,
400 kill = 37,
401 rename = 38,
402 mkdir = 39,
403 rmdir = 40,
404 dup = 41,
405 pipe = 42,
406 times = 43,
407 prof = 44,
408 brk = 45,
409 setgid = 46,
410 getgid = 47,
411 signal = 48,
412 geteuid = 49,
413 getegid = 50,
414 acct = 51,
415 umount2 = 52,
416 lock = 53,
417 ioctl = 54,
418 fcntl = 55,
419 mpx = 56,
420 setpgid = 57,
421 ulimit = 58,
422 oldolduname = 59,
423 umask = 60,
424 chroot = 61,
425 ustat = 62,
426 dup2 = 63,
427 getppid = 64,
428 getpgrp = 65,
429 setsid = 66,
430 sigaction = 67,
431 sgetmask = 68,
432 ssetmask = 69,
433 setreuid = 70,
434 setregid = 71,
435 sigsuspend = 72,
436 sigpending = 73,
437 sethostname = 74,
438 setrlimit = 75,
439 getrlimit = 76,
440 getrusage = 77,
441 gettimeofday = 78,
442 settimeofday = 79,
443 getgroups = 80,
444 setgroups = 81,
445 select = 82,
446 symlink = 83,
447 oldlstat = 84,
448 readlink = 85,
449 uselib = 86,
450 swapon = 87,
451 reboot = 88,
452 readdir = 89,
453 mmap = 90,
454 munmap = 91,
455 truncate = 92,
456 ftruncate = 93,
457 fchmod = 94,
458 fchown = 95,
459 getpriority = 96,
460 setpriority = 97,
461 profil = 98,
462 statfs = 99,
463 fstatfs = 100,
464 ioperm = 101,
465 socketcall = 102,
466 syslog = 103,
467 setitimer = 104,
468 getitimer = 105,
469 stat = 106,
470 lstat = 107,
471 fstat = 108,
472 olduname = 109,
473 iopl = 110,
474 vhangup = 111,
475 idle = 112,
476 vm86old = 113,
477 wait4 = 114,
478 swapoff = 115,
479 sysinfo = 116,
480 ipc = 117,
481 fsync = 118,
482 sigreturn = 119,
483 clone = 120,
484 setdomainname = 121,
485 uname = 122,
486 modify_ldt = 123,
487 adjtimex = 124,
488 mprotect = 125,
489 sigprocmask = 126,
490 create_module = 127,
491 init_module = 128,
492 delete_module = 129,
493 get_kernel_syms = 130,
494 quotactl = 131,
495 getpgid = 132,
496 fchdir = 133,
497 bdflush = 134,
498 sysfs = 135,
499 personality = 136,
500 afs_syscall = 137,
501 setfsuid = 138,
502 setfsgid = 139,
503 _llseek = 140,
504 getdents = 141,
505 _newselect = 142,
506 flock = 143,
507 msync = 144,
508 readv = 145,
509 writev = 146,
510 getsid = 147,
511 fdatasync = 148,
512 _sysctl = 149,
513 mlock = 150,
514 munlock = 151,
515 mlockall = 152,
516 munlockall = 153,
517 sched_setparam = 154,
518 sched_getparam = 155,
519 sched_setscheduler = 156,
520 sched_getscheduler = 157,
521 sched_yield = 158,
522 sched_get_priority_max = 159,
523 sched_get_priority_min = 160,
524 sched_rr_get_interval = 161,
525 nanosleep = 162,
526 mremap = 163,
527 setresuid = 164,
528 getresuid = 165,
529 vm86 = 166,
530 query_module = 167,
531 poll = 168,
532 nfsservctl = 169,
533 setresgid = 170,
534 getresgid = 171,
535 prctl = 172,
536 rt_sigreturn = 173,
537 rt_sigaction = 174,
538 rt_sigprocmask = 175,
539 rt_sigpending = 176,
540 rt_sigtimedwait = 177,
541 rt_sigqueueinfo = 178,
542 rt_sigsuspend = 179,
543 pread64 = 180,
544 pwrite64 = 181,
545 chown = 182,
546 getcwd = 183,
547 capget = 184,
548 capset = 185,
549 sigaltstack = 186,
550 sendfile = 187,
551 getpmsg = 188,
552 putpmsg = 189,
553 vfork = 190,
554 ugetrlimit = 191,
555 mmap2 = 192,
556 truncate64 = 193,
557 ftruncate64 = 194,
558 stat64 = 195,
559 lstat64 = 196,
560 fstat64 = 197,
561 lchown32 = 198,
562 getuid32 = 199,
563 getgid32 = 200,
564 geteuid32 = 201,
565 getegid32 = 202,
566 setreuid32 = 203,
567 setregid32 = 204,
568 getgroups32 = 205,
569 setgroups32 = 206,
570 fchown32 = 207,
571 setresuid32 = 208,
572 getresuid32 = 209,
573 setresgid32 = 210,
574 getresgid32 = 211,
575 chown32 = 212,
576 setuid32 = 213,
577 setgid32 = 214,
578 setfsuid32 = 215,
579 setfsgid32 = 216,
580 pivot_root = 217,
581 mincore = 218,
582 madvise = 219,
583 getdents64 = 220,
584 fcntl64 = 221,
585 gettid = 224,
586 readahead = 225,
587 setxattr = 226,
588 lsetxattr = 227,
589 fsetxattr = 228,
590 getxattr = 229,
591 lgetxattr = 230,
592 fgetxattr = 231,
593 listxattr = 232,
594 llistxattr = 233,
595 flistxattr = 234,
596 removexattr = 235,
597 lremovexattr = 236,
598 fremovexattr = 237,
599 tkill = 238,
600 sendfile64 = 239,
601 futex = 240,
602 sched_setaffinity = 241,
603 sched_getaffinity = 242,
604 set_thread_area = 243,
605 get_thread_area = 244,
606 io_setup = 245,
607 io_destroy = 246,
608 io_getevents = 247,
609 io_submit = 248,
610 io_cancel = 249,
611 fadvise64 = 250,
612 exit_group = 252,
613 lookup_dcookie = 253,
614 epoll_create = 254,
615 epoll_ctl = 255,
616 epoll_wait = 256,
617 remap_file_pages = 257,
618 set_tid_address = 258,
619 timer_create = 259,
620 timer_settime = 260,
621 timer_gettime = 261,
622 timer_getoverrun = 262,
623 timer_delete = 263,
624 clock_settime = 264,
625 clock_gettime = 265,
626 clock_getres = 266,
627 clock_nanosleep = 267,
628 statfs64 = 268,
629 fstatfs64 = 269,
630 tgkill = 270,
631 utimes = 271,
632 fadvise64_64 = 272,
633 vserver = 273,
634 mbind = 274,
635 get_mempolicy = 275,
636 set_mempolicy = 276,
637 mq_open = 277,
638 mq_unlink = 278,
639 mq_timedsend = 279,
640 mq_timedreceive = 280,
641 mq_notify = 281,
642 mq_getsetattr = 282,
643 kexec_load = 283,
644 waitid = 284,
645 add_key = 286,
646 request_key = 287,
647 keyctl = 288,
648 ioprio_set = 289,
649 ioprio_get = 290,
650 inotify_init = 291,
651 inotify_add_watch = 292,
652 inotify_rm_watch = 293,
653 migrate_pages = 294,
654 openat = 295,
655 mkdirat = 296,
656 mknodat = 297,
657 fchownat = 298,
658 futimesat = 299,
659 fstatat64 = 300,
660 unlinkat = 301,
661 renameat = 302,
662 linkat = 303,
663 symlinkat = 304,
664 readlinkat = 305,
665 fchmodat = 306,
666 faccessat = 307,
667 pselect6 = 308,
668 ppoll = 309,
669 unshare = 310,
670 set_robust_list = 311,
671 get_robust_list = 312,
672 splice = 313,
673 sync_file_range = 314,
674 tee = 315,
675 vmsplice = 316,
676 move_pages = 317,
677 getcpu = 318,
678 epoll_pwait = 319,
679 utimensat = 320,
680 signalfd = 321,
681 timerfd_create = 322,
682 eventfd = 323,
683 fallocate = 324,
684 timerfd_settime = 325,
685 timerfd_gettime = 326,
686 signalfd4 = 327,
687 eventfd2 = 328,
688 epoll_create1 = 329,
689 dup3 = 330,
690 pipe2 = 331,
691 inotify_init1 = 332,
692 preadv = 333,
693 pwritev = 334,
694 rt_tgsigqueueinfo = 335,
695 perf_event_open = 336,
696 recvmmsg = 337,
697 fanotify_init = 338,
698 fanotify_mark = 339,
699 prlimit64 = 340,
700 name_to_handle_at = 341,
701 open_by_handle_at = 342,
702 clock_adjtime = 343,
703 syncfs = 344,
704 sendmmsg = 345,
705 setns = 346,
706 process_vm_readv = 347,
707 process_vm_writev = 348,
708 kcmp = 349,
709 finit_module = 350,
710 sched_setattr = 351,
711 sched_getattr = 352,
712 renameat2 = 353,
713 seccomp = 354,
714 getrandom = 355,
715 memfd_create = 356,
716 bpf = 357,
717 execveat = 358,
718 socket = 359,
719 socketpair = 360,
720 bind = 361,
721 connect = 362,
722 listen = 363,
723 accept4 = 364,
724 getsockopt = 365,
725 setsockopt = 366,
726 getsockname = 367,
727 getpeername = 368,
728 sendto = 369,
729 sendmsg = 370,
730 recvfrom = 371,
731 recvmsg = 372,
732 shutdown = 373,
733 userfaultfd = 374,
734 membarrier = 375,
735 mlock2 = 376,
736 copy_file_range = 377,
737 preadv2 = 378,
738 pwritev2 = 379,
739 pkey_mprotect = 380,
740 pkey_alloc = 381,
741 pkey_free = 382,
742 statx = 383,
743 arch_prctl = 384,
744 }
745}
diff --git a/libphobos/libdruntime/core/sys/linux/unistd.d b/libphobos/libdruntime/core/sys/linux/unistd.d
index 48457467005..1ef16c12689 100644
--- a/libphobos/libdruntime/core/sys/linux/unistd.d
+++ b/libphobos/libdruntime/core/sys/linux/unistd.d
@@ -1,16 +1,20 @@
1module core.sys.linux.unistd; 1module core.sys.linux.unistd;
2 2
3public import core.sys.posix.unistd;
4
5version (linux): 3version (linux):
6extern(C): 4extern (C):
7nothrow: 5nothrow:
8@system: 6@system:
7@nogc:
8
9public import core.sys.posix.unistd;
10public import core.sys.linux.syscalls : SystemCall;
11import core.stdc.config : c_long;
9 12
10// Additional seek constants for sparse file handling 13// Additional seek constants for sparse file handling
11// from Linux's unistd.h, stdio.h, and linux/fs.h 14// from Linux's unistd.h, stdio.h, and linux/fs.h
12// (see http://man7.org/linux/man-pages/man2/lseek.2.html) 15// (see http://man7.org/linux/man-pages/man2/lseek.2.html)
13enum { 16enum
17{
14 /// Offset is relative to the next location containing data 18 /// Offset is relative to the next location containing data
15 SEEK_DATA = 3, 19 SEEK_DATA = 3,
16 /// Offset is relative to the next hole (or EOF if file is not sparse) 20 /// Offset is relative to the next hole (or EOF if file is not sparse)
@@ -22,3 +26,17 @@ char* getpass(const(char)* prompt);
22 26
23// Exit all threads in a process 27// Exit all threads in a process
24void exit_group(int status); 28void exit_group(int status);
29
30/**
31Invoke system call specified by number, passing it the remaining arguments.
32This is completely system-dependent, and not often useful.
33
34In Unix, `syscall' sets `errno' for all errors and most calls return -1
35for errors; in many systems you cannot pass arguments or get return
36values for all system calls (`pipe', `fork', and `getppid' typically
37among them).
38
39In Mach, all system calls take normal arguments and always return an
40error code (zero for success).
41*/
42c_long syscall(SystemCall number, ...) @nogc nothrow;
diff --git a/libphobos/libdruntime/core/sys/openbsd/dlfcn.d b/libphobos/libdruntime/core/sys/openbsd/dlfcn.d
index a8e8565cb48..b28dc63d5c7 100644
--- a/libphobos/libdruntime/core/sys/openbsd/dlfcn.d
+++ b/libphobos/libdruntime/core/sys/openbsd/dlfcn.d
@@ -1,7 +1,7 @@
1/** 1/**
2 * D header file for OpenBSD. 2 * D header file for OpenBSD.
3 * 3 *
4 * $(LINK2 http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/include/link_elf.h?rev=1.6&content-type=text/x-cvsweb-markup, dlfcn.h) 4 * $(LINK2 https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/include/dlfcn.h?rev=1.15&content-type=text/plain, dlfcn.h)
5 */ 5 */
6module core.sys.openbsd.dlfcn; 6module core.sys.openbsd.dlfcn;
7 7
@@ -16,6 +16,7 @@ static assert(RTLD_NOW == 2);
16static assert(RTLD_GLOBAL == 0x100); 16static assert(RTLD_GLOBAL == 0x100);
17static assert(RTLD_LOCAL == 0); 17static assert(RTLD_LOCAL == 0);
18enum RTLD_TRACE = 0x200; 18enum RTLD_TRACE = 0x200;
19enum RTLD_NODELETE = 0x400;
19 20
20enum RTLD_NEXT = cast(void *)-1; 21enum RTLD_NEXT = cast(void *)-1;
21enum RTLD_DEFAULT = cast(void *)-2; 22enum RTLD_DEFAULT = cast(void *)-2;
@@ -24,6 +25,7 @@ enum RTLD_SELF = cast(void *)-3;
24enum DL_GETERRNO = 1; 25enum DL_GETERRNO = 1;
25enum DL_SETTHREADLCK = 2; 26enum DL_SETTHREADLCK = 2;
26enum DL_SETBINDLCK = 3; 27enum DL_SETBINDLCK = 3;
28enum DL_REFERENCE = 4;
27 29
28enum DL_LAZY = RTLD_LAZY; 30enum DL_LAZY = RTLD_LAZY;
29 31
diff --git a/libphobos/libdruntime/core/sys/openbsd/pthread_np.d b/libphobos/libdruntime/core/sys/openbsd/pthread_np.d
new file mode 100644
index 00000000000..8344df23950
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/openbsd/pthread_np.d
@@ -0,0 +1,23 @@
1/**
2 * D header file for OpenBSD pthread_np.h.
3 *
4 * Copyright: Copyright © 2021, The D Language Foundation
5 * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
6