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

Commit

Permalink
Allow configuration of the signals used for GC
Browse files Browse the repository at this point in the history
On Posix systems druntime's GC uses SIGUSR1 and SIGUSR2 to implement
suspension of threads for its garbage collector. When integrating D into
existing programs written in other languages such as C or C++,
SIGUSR1/SIGUSR2 may already have an existing meaning. This allows those
programs to use currently unused signals for D's GC, most likely some of
the POSIX real time signals where availble.

This is acheived by calling thread_setGCSignals prior to thread_init, at
most once. If it is not called the runtime will continue to use SIGUSR1
and SIGUSR2. The functionality leaves the choice of signals up to the
caller, it does not assume any particular real time signal or that real
time signals are available.
  • Loading branch information
lcapaldo committed Jul 13, 2014
1 parent b0920b6 commit a29efb7
Showing 1 changed file with 47 additions and 8 deletions.
55 changes: 47 additions & 8 deletions src/core/thread.d
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ else version( Posix )
extern (C) void thread_suspendHandler( int sig ) nothrow
in
{
assert( sig == SIGUSR1 );
assert( sig == suspendSignalNumber );
}
body
{
Expand Down Expand Up @@ -427,7 +427,7 @@ else version( Posix )
status = sigfillset( &sigres );
assert( status == 0 );

status = sigdelset( &sigres, SIGUSR2 );
status = sigdelset( &sigres, resumeSignalNumber );
assert( status == 0 );

status = sem_post( &suspendCount );
Expand All @@ -448,7 +448,7 @@ else version( Posix )
extern (C) void thread_resumeHandler( int sig ) nothrow
in
{
assert( sig == SIGUSR2 );
assert( sig == resumeSignalNumber );
}
body
{
Expand Down Expand Up @@ -1725,6 +1725,35 @@ unittest
// GC Support Routines
///////////////////////////////////////////////////////////////////////////////

version( Posix )
{
__gshared int suspendSignalNumber;
__gshared int resumeSignalNumber;

/**
* Instruct the thread module, when initialized,, to use a different set of
* signals besides SIGUSR1 and SIGUSr2 for suspension and resumption of threads.
* This function should be called at most once, prior to thread_init().
*/
extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo)
in
{
assert(suspendSignalNumber == 0);
assert(resumeSignalNumber == 0);
assert(suspendSignalNo != 0);
assert(resumeSignalNo != 0);
}
out
{
assert(suspendSignalNumber != 0);
assert(resumeSignalNumber != 0);
}
body
{
suspendSignalNumber = suspendSignalNo;
resumeSignalNumber = resumeSignalNo;
}
}

/**
* Initializes the thread module. This function must be called by the
Expand All @@ -1746,6 +1775,16 @@ extern (C) void thread_init()
}
else version( Posix )
{
if( suspendSignalNumber == 0 )
{
suspendSignalNumber = SIGUSR1;
}

if( resumeSignalNumber == 0 )
{
resumeSignalNumber = SIGUSR2;
}

int status;
sigaction_t sigusr1 = void;
sigaction_t sigusr2 = void;
Expand All @@ -1768,7 +1807,7 @@ extern (C) void thread_init()
status = sigfillset( &sigusr1.sa_mask );
assert( status == 0 );

// NOTE: Since SIGUSR2 should only be issued for threads within the
// NOTE: Since resumeSignalNumber should only be issued for threads within the
// suspend handler, we don't want this signal to trigger a
// restart.
sigusr2.sa_flags = 0;
Expand All @@ -1778,10 +1817,10 @@ extern (C) void thread_init()
status = sigfillset( &sigusr2.sa_mask );
assert( status == 0 );

status = sigaction( SIGUSR1, &sigusr1, null );
status = sigaction( suspendSignalNumber, &sigusr1, null );
assert( status == 0 );

status = sigaction( SIGUSR2, &sigusr2, null );
status = sigaction( resumeSignalNumber, &sigusr2, null );
assert( status == 0 );

status = sem_init( &suspendCount, 0, 0 );
Expand Down Expand Up @@ -2275,7 +2314,7 @@ private void suspend( Thread t ) nothrow
{
if( t.m_addr != pthread_self() )
{
if( pthread_kill( t.m_addr, SIGUSR1 ) != 0 )
if( pthread_kill( t.m_addr, suspendSignalNumber ) != 0 )
{
if( !t.isRunning )
{
Expand Down Expand Up @@ -2430,7 +2469,7 @@ private void resume( Thread t ) nothrow
{
if( t.m_addr != pthread_self() )
{
if( pthread_kill( t.m_addr, SIGUSR2 ) != 0 )
if( pthread_kill( t.m_addr, resumeSignalNumber ) != 0 )
{
if( !t.isRunning )
{
Expand Down

0 comments on commit a29efb7

Please sign in to comment.