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

Commit

Permalink
Merge branch 'master' of github.com:D-Programming-Language/druntime
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Jul 15, 2012
2 parents 7d45664 + fef4c9c commit ee0b688
Show file tree
Hide file tree
Showing 21 changed files with 256 additions and 186 deletions.
16 changes: 16 additions & 0 deletions import/core/thread.di
Expand Up @@ -668,10 +668,26 @@ alias IsMarked delegate( void* addr ) IsMarkedDg;
extern(C) void thread_processGCMarks( scope IsMarkedDg isMarked );


/**
* Returns the stack top of the currently active stack within the calling
* thread.
*
* In:
* The calling thread must be attached to the runtime.
*
* Returns:
* The address of the stack top.
*/
extern (C) void* thread_stackTop();


/**
* Returns the stack bottom of the currently active stack within the calling
* thread.
*
* In:
* The calling thread must be attached to the runtime.
*
* Returns:
* The address of the stack bottom.
*/
Expand Down
20 changes: 10 additions & 10 deletions import/object.di
Expand Up @@ -224,16 +224,16 @@ class TypeInfo_Pointer : TypeInfo

class TypeInfo_Array : TypeInfo
{
override string toString();
override equals_t opEquals(const Object o);
override hash_t getHash(in void* p) @trusted;
override equals_t equals(in void* p1, in void* p2);
override int compare(in void* p1, in void* p2);
override @property size_t tsize() nothrow pure;
override void swap(void* p1, void* p2);
override string toString() const;
override equals_t opEquals(const Object o) const;
override hash_t getHash(in void* p) @trusted const;
override equals_t equals(in void* p1, in void* p2) const;
override int compare(in void* p1, in void* p2) const;
override @property size_t tsize() nothrow pure const;
override void swap(void* p1, void* p2) const;
override @property const(TypeInfo) next() nothrow pure const;
override @property uint flags() nothrow pure;
override @property size_t talign() nothrow pure;
override @property uint flags() nothrow pure const;
override @property size_t talign() nothrow pure const;
version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2);

TypeInfo value;
Expand Down Expand Up @@ -451,7 +451,7 @@ class Throwable : Object

this(string msg, Throwable next = null);
this(string msg, string file, size_t line, Throwable next = null);
override string toString();
override string toString() const;
}


Expand Down
4 changes: 3 additions & 1 deletion src/core/atomic.d
Expand Up @@ -613,7 +613,7 @@ else version( AsmX86_32 )

Lend:

;
ret;
}
}
}
Expand Down Expand Up @@ -1060,7 +1060,9 @@ else version( AsmX86_64 )
asm
{
naked;

mfence;
ret;
}
}
}
Expand Down
71 changes: 37 additions & 34 deletions src/core/bitop.d
Expand Up @@ -15,6 +15,7 @@
module core.bitop;

nothrow:
@safe:

version( D_InlineAsm_X86_64 )
version = AsmX86;
Expand All @@ -38,7 +39,7 @@ else version( D_InlineAsm_X86 )
* }
* ---
*/
pure int bsf(size_t v);
int bsf(size_t v) pure;

unittest
{
Expand All @@ -63,7 +64,7 @@ unittest
* }
* ---
*/
pure int bsr(size_t v);
int bsr(size_t v) pure;

unittest
{
Expand All @@ -73,19 +74,19 @@ unittest
/**
* Tests the bit.
*/
pure int bt(in size_t* p, size_t bitnum);
int bt(in size_t* p, size_t bitnum) pure;


/**
* Tests and complements the bit.
*/
int btc(size_t* p, size_t bitnum);
int btc(size_t* p, size_t bitnum) pure;


/**
* Tests and resets (sets to 0) the bit.
*/
int btr(size_t* p, size_t bitnum);
int btr(size_t* p, size_t bitnum) pure;


/**
Expand Down Expand Up @@ -137,7 +138,7 @@ int main()
}
* ---
*/
int bts(size_t* p, size_t bitnum);
int bts(size_t* p, size_t bitnum) pure;

unittest
{
Expand Down Expand Up @@ -188,49 +189,51 @@ unittest
* byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3
* becomes byte 0.
*/
pure uint bswap(uint v);
uint bswap(uint v) pure;

@system // not pure
{
/**
* Reads I/O port at port_address.
*/
ubyte inp(uint port_address);

/**
* Reads I/O port at port_address.
*/
ubyte inp(uint port_address);

/**
* ditto
*/
ushort inpw(uint port_address);

/**
* ditto
*/
ushort inpw(uint port_address);

/**
* ditto
*/
uint inpl(uint port_address);

/**
* ditto
*/
uint inpl(uint port_address);


/**
* Writes and returns value to I/O port at port_address.
*/
ubyte outp(uint port_address, ubyte value);
/**
* Writes and returns value to I/O port at port_address.
*/
ubyte outp(uint port_address, ubyte value);


/**
* ditto
*/
ushort outpw(uint port_address, ushort value);
/**
* ditto
*/
ushort outpw(uint port_address, ushort value);


/**
* ditto
*/
uint outpl(uint port_address, uint value);
/**
* ditto
*/
uint outpl(uint port_address, uint value);
}


/**
* Calculates the number of set bits in a 32-bit integer.
*/
pure int popcnt( uint x )
int popcnt( uint x ) pure
{
// Avoid branches, and the potential for cache misses which
// could be incurred with a table lookup.
Expand Down Expand Up @@ -277,7 +280,7 @@ unittest
/**
* Reverses the order of bits in a 32-bit integer.
*/
pure uint bitswap( uint x )
@trusted uint bitswap( uint x ) pure
{
version (AsmX86)
{
Expand Down
6 changes: 3 additions & 3 deletions src/core/memory.d
Expand Up @@ -410,7 +410,7 @@ struct GC
*/
static inout(void)* addrOf( inout(void)* p ) nothrow /* FIXME pure */
{
return cast(inout(void)*)addrOf(cast()p);
return cast(inout(void)*)gc_addrOf(cast(void*)p);
}


Expand All @@ -436,7 +436,7 @@ struct GC
*/
static size_t sizeOf( in void* p ) nothrow
{
return sizeOf(cast(const)p);
return gc_sizeOf(cast(void*)p);
}


Expand Down Expand Up @@ -464,7 +464,7 @@ struct GC
*/
static BlkInfo query( in void* p ) nothrow
{
return query(cast(const)p);
return gc_query(cast(void*)p);
}


Expand Down
2 changes: 1 addition & 1 deletion src/core/runtime.d
Expand Up @@ -462,7 +462,7 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
return ret;
}

override string toString()
override string toString() const
{
string buf;
foreach( i, line; this )
Expand Down
4 changes: 3 additions & 1 deletion src/core/sync/condition.d
Expand Up @@ -594,7 +594,9 @@ version( unittest )
synchronized( mutex )
{
waiting = true;
alertedOne = condReady.wait( dur!"seconds"(1) );
// we never want to miss the notification (30s)
alertedOne = condReady.wait( dur!"seconds"(30) );
// but we don't want to wait long for the timeout (1s)
alertedTwo = condReady.wait( dur!"seconds"(1) );
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/core/sys/posix/signal.d
Expand Up @@ -375,6 +375,13 @@ version( linux )
int si_fd;
} _sigpoll_t _sigpoll;
} _sifields_t _sifields;

@property ref pid_t si_pid() { return _sifields._kill.si_pid; }
@property ref uid_t si_uid() { return _sifields._kill.si_uid; }
@property ref void* si_addr() { return _sifields._sigfault.si_addr; }
@property ref int si_status() { return _sifields._sigchld.si_status; }
@property ref c_long si_band() { return _sifields._sigpoll.si_band; }
@property ref sigval si_value() { return _sifields._rt.si_sigval; }
}

enum
Expand Down Expand Up @@ -502,6 +509,8 @@ else version( FreeBSD )
___spare___ __spare__;
}
__reason _reason;

@property ref c_long si_band() { return _reason._poll._band; }
}

int kill(pid_t, int);
Expand Down
60 changes: 48 additions & 12 deletions src/core/thread.d
Expand Up @@ -122,6 +122,7 @@ version( Windows )
import core.sys.windows.threadaux; // for OpenThreadHandle

const DWORD TLS_OUT_OF_INDEXES = 0xFFFFFFFF;
const CREATE_SUSPENDED = 0x00000004;

extern (Windows) alias uint function(void*) btex_fptr;
extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*);
Expand Down Expand Up @@ -680,6 +681,23 @@ class Thread
throw new ThreadException( "Error setting thread joinable" );
}

version( Windows )
{
// NOTE: If a thread is just executing DllMain()
// while another thread is started here, it holds an OS internal
// lock that serializes DllMain with CreateThread. As the code
// might request a synchronization on slock (e.g. in thread_findByAddr()),
// we cannot hold that lock while creating the thread without
// creating a deadlock
//
// Solution: Create the thread in suspended state and then
// add and resume it with slock acquired
assert(m_sz <= uint.max, "m_sz must be less than or equal to uint.max");
m_hndl = cast(HANDLE) _beginthreadex( null, m_sz, &thread_entryPoint, cast(void*) this, CREATE_SUSPENDED, &m_addr );
if( cast(size_t) m_hndl == 0 )
throw new ThreadException( "Error creating thread" );
}

// NOTE: The starting thread must be added to the global thread list
// here rather than within thread_entryPoint to prevent a race
// with the main thread, which could finish and terminat the
Expand All @@ -690,10 +708,8 @@ class Thread
{
version( Windows )
{
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, 0, &m_addr );
if( cast(size_t) m_hndl == 0 )
throw new ThreadException( "Error creating thread" );
if( ResumeThread( m_hndl ) == -1 )
throw new ThreadException( "Error resuming thread" );
}
else version( Posix )
{
Expand All @@ -712,14 +728,17 @@ class Thread
if( m_tmach == m_tmach.init )
throw new ThreadException( "Error creating thread" );
}
// NOTE: DllMain(THREAD_ATTACH) may be called before this call
// exits, and this in turn calls thread_findByAddr, which
// would expect this thread to be in the global list if it
// is a D-created thread. However, since thread_findByAddr
// acquires Thread.slock before searching the list, it is
// safe to add this thread after _beginthreadex instead
// of before. This also saves us from having to use a
// scope statement to remove the thread on error.

// NOTE: when creating threads from inside a DLL, DllMain(THREAD_ATTACH)
// might be called before ResumeThread returns, but the dll
// helper functions need to know whether the thread is created
// from the runtime itself or from another DLL or the application
// to just attach to it
// as a consequence, the new Thread object is added before actual
// creation of the thread. There should be no problem with the GC
// calling thread_suspendAll, because of the slock synchronization
//
// VERIFY: does this actually also apply to other platforms?
add( this );
}
}
Expand Down Expand Up @@ -2847,7 +2866,24 @@ private void* getStackBottom()
}


extern (C) void* thread_stackTop()
in
{
// Not strictly required, but it gives us more flexibility.
assert(Thread.getThis());
}
body
{
return getStackTop();
}


extern (C) void* thread_stackBottom()
in
{
assert(Thread.getThis());
}
body
{
return Thread.getThis().topContext().bstack;
}
Expand Down

0 comments on commit ee0b688

Please sign in to comment.