Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1109 from MartinNowak/nothrowStart
Browse files Browse the repository at this point in the history
mark Thread.start as nothrow
  • Loading branch information
andralex committed Feb 2, 2015
2 parents 86f8b7c + 3651202 commit a844ed0
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 34 deletions.
4 changes: 4 additions & 0 deletions src/core/internal/traits.d
Expand Up @@ -91,3 +91,7 @@ template staticIota(int beg, int end)
}
}

template dtorIsNothrow(T)
{
enum dtorIsNothrow = is(typeof(function{T t=void;}) : void function() nothrow);
}
70 changes: 41 additions & 29 deletions src/core/thread.d
Expand Up @@ -128,7 +128,7 @@ version( Windows )
const CREATE_SUSPENDED = 0x00000004;

extern (Windows) alias uint function(void*) btex_fptr;
extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*);
extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*) nothrow;

//
// Entry point for Windows threads
Expand Down Expand Up @@ -229,7 +229,7 @@ else version( Posix )
version( OSX )
{
import core.sys.osx.mach.thread_act;
extern (C) mach_port_t pthread_mach_thread_np(pthread_t);
import core.sys.osx.pthread : pthread_mach_thread_np;
}

version( GNU )
Expand Down Expand Up @@ -510,9 +510,8 @@ class Thread
}
body
{
this();
this(sz);
m_fn = fn;
m_sz = sz;
m_call = Call.FN;
m_curr = &m_main;
}
Expand All @@ -536,9 +535,8 @@ class Thread
}
body
{
this();
this(sz);
m_dg = dg;
m_sz = sz;
m_call = Call.DG;
m_curr = &m_main;
}
Expand Down Expand Up @@ -589,7 +587,7 @@ class Thread
* Throws:
* ThreadException if the thread fails to start.
*/
final Thread start()
final Thread start() nothrow
in
{
assert( !next && !prev );
Expand All @@ -610,11 +608,9 @@ class Thread
pthread_attr_t attr;

if( pthread_attr_init( &attr ) )
throw new ThreadException( "Error initializing thread attributes" );
onThreadError( "Error initializing thread attributes" );
if( m_sz && pthread_attr_setstacksize( &attr, m_sz ) )
throw new ThreadException( "Error initializing thread stack size" );
if( pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ) )
throw new ThreadException( "Error setting thread joinable" );
onThreadError( "Error initializing thread stack size" );
}

version( Windows )
Expand All @@ -631,7 +627,7 @@ class Thread
assert(m_sz <= uint.max, "m_sz must be less than or equal to uint.max");
m_hndl = cast(HANDLE) _beginthreadex( null, cast(uint) m_sz, &thread_entryPoint, cast(void*) this, CREATE_SUSPENDED, &m_addr );
if( cast(size_t) m_hndl == 0 )
throw new ThreadException( "Error creating thread" );
onThreadError( "Error creating thread" );
}

// Start thread as non-suspendable, undone in thread_entryPoint
Expand All @@ -648,7 +644,7 @@ class Thread
version( Windows )
{
if( ResumeThread( m_hndl ) == -1 )
throw new ThreadException( "Error resuming thread" );
onThreadError( "Error resuming thread" );
}
else version( Posix )
{
Expand All @@ -670,20 +666,20 @@ class Thread
{
unpinLoadedLibraries(libs);
.free(ps);
throw new ThreadException( "Error creating thread" );
onThreadError( "Error creating thread" );
}
}
else
{
if( pthread_create( &m_addr, &attr, &thread_entryPoint, cast(void*) this ) != 0 )
throw new ThreadException( "Error creating thread" );
onThreadError( "Error creating thread" );
}
}
version( OSX )
{
m_tmach = pthread_mach_thread_np( m_addr );
if( m_tmach == m_tmach.init )
throw new ThreadException( "Error creating thread" );
onThreadError( "Error creating thread" );
}

add( this );
Expand Down Expand Up @@ -1269,8 +1265,21 @@ private:
// Initializes a thread object which has no associated executable function.
// This is used for the main thread initialized in thread_init().
//
this()
this(size_t sz = 0)
{
if (sz)
{
version (Posix)
{
// stack size must be a multiple of PAGESIZE
sz += PAGESIZE - 1;
sz -= sz % PAGESIZE;
// and at least PTHREAD_STACK_MIN
if (PTHREAD_STACK_MIN > sz)
sz = PTHREAD_STACK_MIN;
}
m_sz = sz;
}
m_call = Call.NO;
m_curr = &m_main;
}
Expand Down Expand Up @@ -3317,32 +3326,29 @@ private
}
}

__gshared const size_t PAGESIZE;
static immutable size_t PAGESIZE;
version (Posix) static immutable size_t PTHREAD_STACK_MIN;
}


shared static this()
{
static if( __traits( compiles, GetSystemInfo ) )
version (Windows)
{
SYSTEM_INFO info;
GetSystemInfo( &info );
GetSystemInfo(&info);

PAGESIZE = info.dwPageSize;
assert( PAGESIZE < int.max );
assert(PAGESIZE < int.max);
}
else static if( __traits( compiles, sysconf ) &&
__traits( compiles, _SC_PAGESIZE ) )
else version (Posix)
{
PAGESIZE = cast(size_t) sysconf( _SC_PAGESIZE );
assert( PAGESIZE < int.max );
PAGESIZE = cast(size_t)sysconf(_SC_PAGESIZE);
PTHREAD_STACK_MIN = cast(size_t)sysconf(_SC_THREAD_STACK_MIN);
}
else
{
version( PPC )
PAGESIZE = 8192;
else
PAGESIZE = 4096;
static assert(0, "unimplemented");
}
}

Expand Down Expand Up @@ -5129,3 +5135,9 @@ version (FreeBSD) unittest
}
thr.join();
}

unittest
{
auto thr = new Thread(function{}, 10).start();
thr.join();
}
4 changes: 2 additions & 2 deletions src/rt/sections.d
Expand Up @@ -49,8 +49,8 @@ static assert(is(typeof(&initTLSRanges) RT == return) &&

version (Shared)
{
static assert(is(typeof(&pinLoadedLibraries) == void* function()));
static assert(is(typeof(&unpinLoadedLibraries) == void function(void*)));
static assert(is(typeof(&pinLoadedLibraries) == void* function() nothrow));
static assert(is(typeof(&unpinLoadedLibraries) == void function(void*) nothrow));
static assert(is(typeof(&inheritLoadedLibraries) == void function(void*)));
static assert(is(typeof(&cleanupLoadedLibraries) == void function()));
}
5 changes: 3 additions & 2 deletions src/rt/sections_elf_shared.d
Expand Up @@ -159,7 +159,7 @@ version (Shared)
}

// interface for core.thread to inherit loaded libraries
void* pinLoadedLibraries()
void* pinLoadedLibraries() nothrow
{
auto res = cast(Array!(ThreadDSO)*)calloc(1, Array!(ThreadDSO).sizeof);
res.length = _loadedDSOs.length;
Expand All @@ -176,7 +176,7 @@ version (Shared)
return res;
}

void unpinLoadedLibraries(void* p)
void unpinLoadedLibraries(void* p) nothrow
{
auto pary = cast(Array!(ThreadDSO)*)p;
// In case something failed we need to undo the pinning.
Expand Down Expand Up @@ -578,6 +578,7 @@ void freeDSO(DSO* pdso)

version (Shared)
{
nothrow:
link_map* linkMapForHandle(void* handle)
{
link_map* map;
Expand Down
1 change: 1 addition & 0 deletions src/rt/util/container/array.d
Expand Up @@ -11,6 +11,7 @@ static import common = rt.util.container.common;

struct Array(T)
{
nothrow:
@disable this(this);

~this()
Expand Down
6 changes: 5 additions & 1 deletion src/rt/util/container/common.d
Expand Up @@ -9,6 +9,8 @@ module rt.util.container.common;

import core.stdc.stdlib : malloc, realloc;
public import core.stdc.stdlib : free;
import core.internal.traits : dtorIsNothrow;
nothrow:

void* xrealloc(void* ptr, size_t sz)
{
Expand All @@ -29,8 +31,9 @@ void* xmalloc(size_t sz) nothrow
assert(0);
}

void destroy(T)(ref T t) if (is(T == struct))
void destroy(T)(ref T t) if (is(T == struct) && dtorIsNothrow!T)
{
scope (failure) assert(0); // nothrow hack
object.destroy(t);
}

Expand All @@ -55,6 +58,7 @@ void initialize(T)(ref T t) if (!is(T == struct))

version (unittest) struct RC
{
nothrow:
this(size_t* cnt) { ++*(_cnt = cnt); }
~this() { if (_cnt) --*_cnt; }
this(this) { if (_cnt) ++*_cnt; }
Expand Down

0 comments on commit a844ed0

Please sign in to comment.