From dbd3be3ba7de97cafbb8357bd56f562084cdb96c Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Thu, 3 Feb 2011 19:08:49 +0000 Subject: [PATCH 1/6] Issue 5318 - core.sys.osx: add version (OSX) at top of all files. --- src/core/sys/osx/mach/kern_return.d | 2 ++ src/core/sys/osx/mach/port.d | 2 ++ src/core/sys/osx/mach/semaphore.d | 2 ++ src/core/sys/osx/mach/thread_act.d | 2 ++ 4 files changed, 8 insertions(+) diff --git a/src/core/sys/osx/mach/kern_return.d b/src/core/sys/osx/mach/kern_return.d index 93b64ee9c9..51bded628d 100644 --- a/src/core/sys/osx/mach/kern_return.d +++ b/src/core/sys/osx/mach/kern_return.d @@ -13,6 +13,8 @@ */ module core.sys.osx.mach.kern_return; +version (OSX): + extern (C): alias int kern_return_t; diff --git a/src/core/sys/osx/mach/port.d b/src/core/sys/osx/mach/port.d index a95a258d6c..f160e6815f 100644 --- a/src/core/sys/osx/mach/port.d +++ b/src/core/sys/osx/mach/port.d @@ -13,6 +13,8 @@ */ module core.sys.osx.mach.port; +version (OSX): + extern (C): version( X86 ) diff --git a/src/core/sys/osx/mach/semaphore.d b/src/core/sys/osx/mach/semaphore.d index 47912aea16..99697b0e90 100644 --- a/src/core/sys/osx/mach/semaphore.d +++ b/src/core/sys/osx/mach/semaphore.d @@ -13,6 +13,8 @@ */ module core.sys.osx.mach.semaphore; +version (OSX): + public import core.sys.osx.mach.kern_return; public import core.sys.osx.mach.port; diff --git a/src/core/sys/osx/mach/thread_act.d b/src/core/sys/osx/mach/thread_act.d index 7045cf1f6a..9f2b9cd0af 100644 --- a/src/core/sys/osx/mach/thread_act.d +++ b/src/core/sys/osx/mach/thread_act.d @@ -13,6 +13,8 @@ */ module core.sys.osx.mach.thread_act; +version (OSX): + public import core.sys.osx.mach.kern_return; public import core.sys.osx.mach.port; From fd2ea42bb108173746a3c8267970dd254199faab Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Thu, 3 Feb 2011 19:15:41 +0000 Subject: [PATCH 2/6] Issue 5319 - rt.critical/monitor: Add support for Solaris --- src/rt/critical.c | 2 +- src/rt/monitor.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rt/critical.c b/src/rt/critical.c index e9053061b7..f78cb1eda3 100644 --- a/src/rt/critical.c +++ b/src/rt/critical.c @@ -83,7 +83,7 @@ void _STD_critical_term() /* ================================= linux ============================ */ -#if linux || __APPLE__ || __FreeBSD__ +#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 #include #include diff --git a/src/rt/monitor.c b/src/rt/monitor.c index b16debfb44..3816839473 100644 --- a/src/rt/monitor.c +++ b/src/rt/monitor.c @@ -16,7 +16,7 @@ #include #if _WIN32 -#elif linux || __APPLE__ || __FreeBSD__ +#elif linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 #define USE_PTHREADS 1 #else #endif From 0e4bb82c5666fe964b3eaeedd737a0c4b62a90dd Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Thu, 3 Feb 2011 19:16:42 +0000 Subject: [PATCH 3/6] Issue 5496 - 64bit: possible ABI issue in mars.h for D runtime. --- src/rt/mars.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rt/mars.h b/src/rt/mars.h index f13a4528c1..cbc61c24db 100644 --- a/src/rt/mars.h +++ b/src/rt/mars.h @@ -12,6 +12,7 @@ * http://www.boost.org/LICENSE_1_0.txt) */ #include +#include #if __cplusplus extern "C" { @@ -30,7 +31,7 @@ typedef struct Interface { struct ClassInfo *classinfo; struct Vtbl vtbl; - int offset; + ptrdiff_t offset; } Interface; typedef struct Object From d4cdbcb1ffe356438b923aeb903872a923701724 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Thu, 3 Feb 2011 19:26:51 +0000 Subject: [PATCH 4/6] Merges from GDC Druntime. --- src/core/thread.d | 14 +------------- src/gc/gcx.d | 2 ++ src/rt/memory.d | 8 ++++++++ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/core/thread.d b/src/core/thread.d index 9ef2372570..d8e3e2a161 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -96,19 +96,7 @@ private void* getStackTop() { - version( D_InlineAsm_X86 ) - { - asm - { - naked; - mov EAX, ESP; - ret; - } - } - else - { - return rt_stackTop(); - } + return rt_stackTop(); } diff --git a/src/gc/gcx.d b/src/gc/gcx.d index 6a95286a51..d78e7bfc20 100644 --- a/src/gc/gcx.d +++ b/src/gc/gcx.d @@ -42,6 +42,8 @@ private import gc.gcalloc; private import cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc; private import core.stdc.string; +version (GNU) import gcc.builtins; + debug (PRINTF) import core.stdc.stdio : printf; debug (COLLECT_PRINTF) import core.stdc.stdio : printf; debug private import core.stdc.stdio; diff --git a/src/rt/memory.d b/src/rt/memory.d index f30aea8903..ccf3c57a41 100644 --- a/src/rt/memory.d +++ b/src/rt/memory.d @@ -16,6 +16,10 @@ module rt.memory; private { + version( GNU ) + { + import gcc.builtins; + } version( linux ) { version = SimpleLibcStackEnd; @@ -143,6 +147,10 @@ extern (C) void* rt_stackTop() ret; } } + else version( GNU ) + { + return __builtin_frame_address(0); + } else { static assert( false, "Architecture not supported." ); From 4a2b70aea1df0cc4550b151b82f19655b5903279 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Fri, 4 Feb 2011 00:39:26 +0000 Subject: [PATCH 5/6] Add D implementations of critical.c and monitor.c --- src/rt/critical_.d | 197 +++++++++++++++++++++++++++++++++++++ src/rt/monitor_.d | 240 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 437 insertions(+) create mode 100644 src/rt/critical_.d create mode 100644 src/rt/monitor_.d diff --git a/src/rt/critical_.d b/src/rt/critical_.d new file mode 100644 index 0000000000..1d70da9963 --- /dev/null +++ b/src/rt/critical_.d @@ -0,0 +1,197 @@ +/** + * Implementation of support routines for synchronized blocks. + * + * Copyright: Copyright Digital Mars 2000 - 2010. + * License: Boost License 1.0. + * Authors: Walter Bright, Sean Kelly + */ + +/* Copyright Digital Mars 2000 - 2010. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ +module rt.critical_; + +private +{ + debug(PRINTF) import core.stdc.stdio; + import core.stdc.stdlib; + + version( linux ) + { + version = USE_PTHREADS; + } + else version( FreeBSD ) + { + version = USE_PTHREADS; + } + else version( OSX ) + { + version = USE_PTHREADS; + } + + version( Windows ) + { + import core.sys.windows.windows; + + /* We don't initialize critical sections unless we actually need them. + * So keep a linked list of the ones we do use, and in the static destructor + * code, walk the list and release them. + */ + struct D_CRITICAL_SECTION + { + D_CRITICAL_SECTION *next; + CRITICAL_SECTION cs; + } + } + else version( USE_PTHREADS ) + { + import core.sys.posix.pthread; + + /* We don't initialize critical sections unless we actually need them. + * So keep a linked list of the ones we do use, and in the static destructor + * code, walk the list and release them. + */ + struct D_CRITICAL_SECTION + { + D_CRITICAL_SECTION *next; + pthread_mutex_t cs; + } + } + else + { + static assert(0, "Unsupported platform"); + } +} + + +/* ================================= Win32 ============================ */ + +version( Windows ) +{ + /****************************************** + * Enter/exit critical section. + */ + + static __gshared D_CRITICAL_SECTION *dcs_list; + static __gshared D_CRITICAL_SECTION critical_section; + static __gshared int inited; + + extern (C) void _d_criticalenter(D_CRITICAL_SECTION *dcs) + { + debug(PRINTF) printf("_d_criticalenter(dcs = x%x)\n", dcs); + if (!dcs.next) + { + EnterCriticalSection(&critical_section.cs); + if (!dcs.next) // if, in the meantime, another thread didn't set it + { + dcs.next = dcs_list; + dcs_list = dcs; + InitializeCriticalSection(&dcs.cs); + } + LeaveCriticalSection(&critical_section.cs); + } + EnterCriticalSection(&dcs.cs); + } + + extern (C) void _d_criticalexit(D_CRITICAL_SECTION *dcs) + { + debug(PRINTF) printf("_d_criticalexit(dcs = x%x)\n", dcs); + LeaveCriticalSection(&dcs.cs); + } + + extern (C) void _STI_critical_init() + { + if (!inited) + { + debug(PRINTF) printf("_STI_critical_init()\n"); + InitializeCriticalSection(&critical_section.cs); + dcs_list = &critical_section; + inited = 1; + } + } + + extern (C) void _STD_critical_term() + { + if (inited) + { + debug(PRINTF) printf("_STI_critical_term()\n"); + while (dcs_list) + { + debug(PRINTF) printf("\tlooping... %x\n", dcs_list); + DeleteCriticalSection(&dcs_list.cs); + dcs_list = dcs_list.next; + } + inited = 0; + } + } +} + +/* ================================= linux ============================ */ + +version( USE_PTHREADS ) +{ + /****************************************** + * Enter/exit critical section. + */ + + static __gshared D_CRITICAL_SECTION *dcs_list; + static __gshared D_CRITICAL_SECTION critical_section; + static __gshared pthread_mutexattr_t _criticals_attr; + + extern (C) void _d_criticalenter(D_CRITICAL_SECTION *dcs) + { + if (!dcs_list) + { _STI_critical_init(); + atexit(&_STD_critical_term); + } + debug(PRINTF) printf("_d_criticalenter(dcs = x%x)\n", dcs); + if (!dcs.next) + { + pthread_mutex_lock(&critical_section.cs); + if (!dcs.next) // if, in the meantime, another thread didn't set it + { + dcs.next = dcs_list; + dcs_list = dcs; + pthread_mutex_init(&dcs.cs, &_criticals_attr); + } + pthread_mutex_unlock(&critical_section.cs); + } + pthread_mutex_lock(&dcs.cs); + } + + extern (C) void _d_criticalexit(D_CRITICAL_SECTION *dcs) + { + debug(PRINTF) printf("_d_criticalexit(dcs = x%x)\n", dcs); + pthread_mutex_unlock(&dcs.cs); + } + + extern (C) void _STI_critical_init() + { + if (!dcs_list) + { debug(PRINTF) printf("_STI_critical_init()\n"); + pthread_mutexattr_init(&_criticals_attr); + pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE); + + // The global critical section doesn't need to be recursive + pthread_mutex_init(&critical_section.cs, null); + dcs_list = &critical_section; + } + } + + extern (C) void _STD_critical_term() + { + if (dcs_list) + { + debug(PRINTF) printf("_STI_critical_term()\n"); + while (dcs_list) + { + debug(PRINTF) printf("\tlooping... %x\n", dcs_list); + pthread_mutex_destroy(&dcs_list.cs); + dcs_list = dcs_list.next; + } + } + } +} + diff --git a/src/rt/monitor_.d b/src/rt/monitor_.d new file mode 100644 index 0000000000..a76783d625 --- /dev/null +++ b/src/rt/monitor_.d @@ -0,0 +1,240 @@ +/** + * Contains the implementation for object monitors. + * + * Copyright: Copyright Digital Mars 2000 - 2010. + * License: Boost License 1.0. + * Authors: Walter Bright, Sean Kelly + */ + +/* Copyright Digital Mars 2000 - 2010. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ +module rt.monitor_; + +private +{ + debug(PRINTF) import core.stdc.stdio; + import core.stdc.stdlib; + + version( linux ) + { + version = USE_PTHREADS; + } + else version( FreeBSD ) + { + version = USE_PTHREADS; + } + else version( OSX ) + { + version = USE_PTHREADS; + } + + // This is what the monitor reference in Object points to + alias Object.Monitor IMonitor; + alias void delegate(Object) DEvent; + + version( Windows ) + { + import core.sys.windows.windows; + + struct Monitor + { + IMonitor impl; // for user-level monitors + DEvent[] devt; // for internal monitors + size_t refs; // reference count + CRITICAL_SECTION mon; + } + } + else version( USE_PTHREADS ) + { + import core.sys.posix.pthread; + + struct Monitor + { + IMonitor impl; // for user-level monitors + DEvent[] devt; // for internal monitors + size_t refs; // reference count + pthread_mutex_t mon; + } + } + else + { + static assert(0, "Unsupported platform"); + } + + Monitor* getMonitor(Object h) + { + return cast(Monitor*) h.__monitor; + } + + void setMonitor(Object h, Monitor* m) + { + h.__monitor = m; + } + + static __gshared int inited; +} + + +/* =============================== Win32 ============================ */ + +version( Windows ) +{ + static __gshared CRITICAL_SECTION _monitor_critsec; + + extern (C) void _STI_monitor_staticctor() + { + if (!inited) + { InitializeCriticalSection(&_monitor_critsec); + inited = 1; + } + } + + extern (C) void _STD_monitor_staticdtor() + { + if (inited) + { inited = 0; + DeleteCriticalSection(&_monitor_critsec); + } + } + + extern (C) void _d_monitor_create(Object h) + { + /* + * NOTE: Assume this is only called when h.__monitor is null prior to the + * call. However, please note that another thread may call this function + * at the same time, so we can not assert this here. Instead, try and + * create a lock, and if one already exists then forget about it. + */ + + debug(PRINTF) printf("+_d_monitor_create(%p)\n", h); + assert(h); + Monitor *cs; + EnterCriticalSection(&_monitor_critsec); + if (!h.__monitor) + { + cs = cast(Monitor *)calloc(sizeof(Monitor), 1); + assert(cs); + InitializeCriticalSection(&cs.mon); + setMonitor(h, cs); + cs.refs = 1; + cs = null; + } + LeaveCriticalSection(&_monitor_critsec); + if (cs) + free(cs); + debug(PRINTF) printf("-_d_monitor_create(%p)\n", h); + } + + extern (C) void _d_monitor_destroy(Object h) + { + debug(PRINTF) printf("+_d_monitor_destroy(%p)\n", h); + assert(h && h.__monitor && !getMonitor(h).impl); + DeleteCriticalSection(&getMonitor(h).mon); + free(h.__monitor); + setMonitor(h, null); + debug(PRINTF) printf("-_d_monitor_destroy(%p)\n", h); + } + + extern (C) void _d_monitor_lock(Object h) + { + debug(PRINTF) printf("+_d_monitor_acquire(%p)\n", h); + assert(h && h.__monitor && !getMonitor(h).impl); + EnterCriticalSection(&getMonitor(h).mon); + debug(PRINTF) printf("-_d_monitor_acquire(%p)\n", h); + } + + extern (C) void _d_monitor_unlock(Object h) + { + debug(PRINTF) printf("+_d_monitor_release(%p)\n", h); + assert(h && h.__monitor && !getMonitor(h).impl); + LeaveCriticalSection(&getMonitor(h).mon); + debug(PRINTF) printf("-_d_monitor_release(%p)\n", h); + } +} + +/* =============================== linux ============================ */ + +version( USE_PTHREADS ) +{ + // Includes attribute fixes from David Friedman's GDC port + static __gshared pthread_mutex_t _monitor_critsec; + static __gshared pthread_mutexattr_t _monitors_attr; + + extern (C) void _STI_monitor_staticctor() + { + if (!inited) + { + pthread_mutexattr_init(&_monitors_attr); + pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&_monitor_critsec, &_monitors_attr); + inited = 1; + } + } + + extern (C) void _STD_monitor_staticdtor() + { + if (inited) + { inited = 0; + pthread_mutex_destroy(&_monitor_critsec); + pthread_mutexattr_destroy(&_monitors_attr); + } + } + + extern (C) void _d_monitor_create(Object h) + { + /* + * NOTE: Assume this is only called when h.__monitor is null prior to the + * call. However, please note that another thread may call this function + * at the same time, so we can not assert this here. Instead, try and + * create a lock, and if one already exists then forget about it. + */ + + debug(PRINTF) printf("+_d_monitor_create(%p)\n", h); + assert(h); + Monitor *cs; + pthread_mutex_lock(&_monitor_critsec); + if (!h.__monitor) + { + cs = cast(Monitor *)calloc(Monitor.sizeof, 1); + assert(cs); + pthread_mutex_init(&cs.mon, & _monitors_attr); + setMonitor(h, cs); + cs.refs = 1; + cs = null; + } + pthread_mutex_unlock(&_monitor_critsec); + if (cs) + free(cs); + debug(PRINTF) printf("-_d_monitor_create(%p)\n", h); + } + + extern (C) void _d_monitor_destroy(Object h) + { + debug(PRINTF) printf("+_d_monitor_destroy(%p)\n", h); + assert(h && h.__monitor && !getMonitor(h).impl); + pthread_mutex_destroy(&getMonitor(h).mon); + free(h.__monitor); + setMonitor(h, null); + debug(PRINTF) printf("-_d_monitor_destroy(%p)\n", h); + } + + extern (C) void _d_monitor_lock(Object h) + { + debug(PRINTF) printf("+_d_monitor_acquire(%p)\n", h); + assert(h && h.__monitor && !getMonitor(h).impl); + pthread_mutex_lock(&getMonitor(h).mon); + debug(PRINTF) printf("-_d_monitor_acquire(%p)\n", h); + } + + extern (C) void _d_monitor_unlock(Object h) + { + debug(PRINTF) printf("+_d_monitor_release(%p)\n", h); + assert(h && h.__monitor && !getMonitor(h).impl); + pthread_mutex_unlock(&getMonitor(h).mon); + debug(PRINTF) printf("-_d_monitor_release(%p)\n", h); + } +} + From 6bdcb9e2763dd6b82974f757b388ac106cc8aafe Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Fri, 4 Feb 2011 11:17:05 +0000 Subject: [PATCH 6/6] Update year, indents, and correct a C-style sizeof in Windows of previous commit. --- src/rt/critical_.d | 10 ++++++---- src/rt/monitor_.d | 17 ++++++++++------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/rt/critical_.d b/src/rt/critical_.d index 1d70da9963..fc54e9af10 100644 --- a/src/rt/critical_.d +++ b/src/rt/critical_.d @@ -1,12 +1,12 @@ /** * Implementation of support routines for synchronized blocks. * - * Copyright: Copyright Digital Mars 2000 - 2010. + * Copyright: Copyright Digital Mars 2000 - 2011. * License: Boost License 1.0. * Authors: Walter Bright, Sean Kelly */ -/* Copyright Digital Mars 2000 - 2010. +/* Copyright Digital Mars 2000 - 2011. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) @@ -143,7 +143,8 @@ version( USE_PTHREADS ) extern (C) void _d_criticalenter(D_CRITICAL_SECTION *dcs) { if (!dcs_list) - { _STI_critical_init(); + { + _STI_critical_init(); atexit(&_STD_critical_term); } debug(PRINTF) printf("_d_criticalenter(dcs = x%x)\n", dcs); @@ -170,7 +171,8 @@ version( USE_PTHREADS ) extern (C) void _STI_critical_init() { if (!dcs_list) - { debug(PRINTF) printf("_STI_critical_init()\n"); + { + debug(PRINTF) printf("_STI_critical_init()\n"); pthread_mutexattr_init(&_criticals_attr); pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE); diff --git a/src/rt/monitor_.d b/src/rt/monitor_.d index a76783d625..c0c8467019 100644 --- a/src/rt/monitor_.d +++ b/src/rt/monitor_.d @@ -1,12 +1,12 @@ /** * Contains the implementation for object monitors. * - * Copyright: Copyright Digital Mars 2000 - 2010. + * Copyright: Copyright Digital Mars 2000 - 2011. * License: Boost License 1.0. * Authors: Walter Bright, Sean Kelly */ -/* Copyright Digital Mars 2000 - 2010. +/* Copyright Digital Mars 2000 - 2011. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) @@ -87,7 +87,8 @@ version( Windows ) extern (C) void _STI_monitor_staticctor() { if (!inited) - { InitializeCriticalSection(&_monitor_critsec); + { + InitializeCriticalSection(&_monitor_critsec); inited = 1; } } @@ -95,7 +96,8 @@ version( Windows ) extern (C) void _STD_monitor_staticdtor() { if (inited) - { inited = 0; + { + inited = 0; DeleteCriticalSection(&_monitor_critsec); } } @@ -115,7 +117,7 @@ version( Windows ) EnterCriticalSection(&_monitor_critsec); if (!h.__monitor) { - cs = cast(Monitor *)calloc(sizeof(Monitor), 1); + cs = cast(Monitor *)calloc(Monitor.sizeof, 1); assert(cs); InitializeCriticalSection(&cs.mon); setMonitor(h, cs); @@ -177,7 +179,8 @@ version( USE_PTHREADS ) extern (C) void _STD_monitor_staticdtor() { if (inited) - { inited = 0; + { + inited = 0; pthread_mutex_destroy(&_monitor_critsec); pthread_mutexattr_destroy(&_monitors_attr); } @@ -200,7 +203,7 @@ version( USE_PTHREADS ) { cs = cast(Monitor *)calloc(Monitor.sizeof, 1); assert(cs); - pthread_mutex_init(&cs.mon, & _monitors_attr); + pthread_mutex_init(&cs.mon, &_monitors_attr); setMonitor(h, cs); cs.refs = 1; cs = null;