Skip to content

Commit 08e3610

Browse files
committed
osthread: thread_entryPoint() moved to OS-related *_impl modules
1 parent b3f5932 commit 08e3610

3 files changed

Lines changed: 347 additions & 364 deletions

File tree

druntime/src/core/thread/osthread.d

Lines changed: 0 additions & 364 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,370 +1326,6 @@ extern (C) void thread_term() @nogc nothrow
13261326
}
13271327

13281328

1329-
///////////////////////////////////////////////////////////////////////////////
1330-
// Thread Entry Point and Signal Handlers
1331-
///////////////////////////////////////////////////////////////////////////////
1332-
1333-
1334-
version (Windows)
1335-
{
1336-
package
1337-
{
1338-
//
1339-
// Entry point for Windows threads
1340-
//
1341-
extern (Windows) uint thread_entryPoint( void* arg ) nothrow
1342-
{
1343-
Thread obj = cast(Thread) arg;
1344-
assert( obj );
1345-
1346-
obj.initDataStorage();
1347-
1348-
Thread.registerThis(obj);
1349-
1350-
scope (exit)
1351-
{
1352-
// allow the GC to clean up any resources it allocated for this thread.
1353-
import core.internal.gc.proxy : gc_getProxy;
1354-
gc_getProxy().cleanupThread(obj);
1355-
1356-
Thread.remove(obj);
1357-
obj.destroyDataStorage();
1358-
}
1359-
Thread.add(&obj.m_main);
1360-
1361-
// NOTE: No GC allocations may occur until the stack pointers have
1362-
// been set and Thread.getThis returns a valid reference to
1363-
// this thread object (this latter condition is not strictly
1364-
// necessary on Windows but it should be followed for the
1365-
// sake of consistency).
1366-
1367-
// TODO: Consider putting an auto exception object here (using
1368-
// alloca) forOutOfMemoryError plus something to track
1369-
// whether an exception is in-flight?
1370-
1371-
void append( Throwable t )
1372-
{
1373-
obj.filterCaughtThrowable(t);
1374-
if (t !is null)
1375-
obj.m_unhandled = Throwable.chainTogether(obj.m_unhandled, t);
1376-
}
1377-
1378-
version (D_InlineAsm_X86)
1379-
{
1380-
asm nothrow @nogc { fninit; }
1381-
}
1382-
1383-
try
1384-
{
1385-
rt_moduleTlsCtor();
1386-
try
1387-
{
1388-
obj.runFromEntryPoint();
1389-
}
1390-
catch ( Throwable t )
1391-
{
1392-
append( t );
1393-
}
1394-
rt_moduleTlsDtor();
1395-
}
1396-
catch ( Throwable t )
1397-
{
1398-
append( t );
1399-
}
1400-
return 0;
1401-
}
1402-
1403-
1404-
HANDLE GetCurrentThreadHandle() nothrow @nogc
1405-
{
1406-
const uint DUPLICATE_SAME_ACCESS = 0x00000002;
1407-
1408-
HANDLE curr = GetCurrentThread(),
1409-
proc = GetCurrentProcess(),
1410-
hndl;
1411-
1412-
DuplicateHandle( proc, curr, proc, &hndl, 0, TRUE, DUPLICATE_SAME_ACCESS );
1413-
return hndl;
1414-
}
1415-
}
1416-
}
1417-
else version (Posix)
1418-
{
1419-
// NOTE: A thread's cancelability state, determined by pthread_setcancelstate,
1420-
// can be enabled (the default for new threads) or disabled.
1421-
// If a thread has disabled cancelation, then a cancelation request remains
1422-
// queued until the thread enables cancelation. If a thread has enabled
1423-
// cancelation, then its cancelability type determines when cancelation occurs.
1424-
//
1425-
// Call these routines when entering/leaving critical sections of the code that
1426-
// are not cancellation points.
1427-
1428-
extern (C) int thread_cancelDisable() nothrow
1429-
{
1430-
static if (__traits(compiles, core.sys.posix.pthread.PTHREAD_CANCEL_DISABLE))
1431-
{
1432-
import core.sys.posix.pthread : pthread_setcancelstate, PTHREAD_CANCEL_DISABLE;
1433-
int oldstate;
1434-
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
1435-
return oldstate;
1436-
}
1437-
else
1438-
{
1439-
return 0; // No thread cancellation on platform
1440-
}
1441-
}
1442-
1443-
extern (C) void thread_cancelRestore(int oldstate) nothrow
1444-
{
1445-
static if (__traits(compiles, core.sys.posix.pthread.PTHREAD_CANCEL_DISABLE))
1446-
{
1447-
import core.sys.posix.pthread : pthread_setcancelstate;
1448-
pthread_setcancelstate(oldstate, null);
1449-
}
1450-
}
1451-
1452-
package
1453-
{
1454-
//
1455-
// Entry point for POSIX threads
1456-
//
1457-
version (CoreDdoc) {} else
1458-
extern (C) void* thread_entryPoint( void* arg ) nothrow
1459-
{
1460-
version (Shared)
1461-
{
1462-
Thread obj = cast(Thread)(cast(void**)arg)[0];
1463-
auto loadedLibraries = (cast(void**)arg)[1];
1464-
.free(arg);
1465-
}
1466-
else
1467-
{
1468-
Thread obj = cast(Thread)arg;
1469-
}
1470-
assert( obj );
1471-
1472-
// loadedLibraries need to be inherited from parent thread
1473-
// before initilizing GC for TLS (rt_tlsgc_init)
1474-
version (Shared)
1475-
{
1476-
externDFunc!("rt.sections_elf_shared.inheritLoadedLibraries",
1477-
void function(void*) @nogc nothrow)(loadedLibraries);
1478-
}
1479-
1480-
obj.initDataStorage();
1481-
1482-
atomicStore!(MemoryOrder.raw)(obj.m_isRunning, true);
1483-
1484-
Thread.registerThis(obj); // can only receive signals from here on
1485-
1486-
scope (exit)
1487-
{
1488-
// allow the GC to clean up any resources it allocated for this thread.
1489-
import core.internal.gc.proxy : gc_getProxy;
1490-
gc_getProxy().cleanupThread(obj);
1491-
1492-
Thread.remove(obj);
1493-
atomicStore!(MemoryOrder.raw)(obj.m_isRunning, false);
1494-
obj.destroyDataStorage();
1495-
}
1496-
Thread.add(&obj.m_main);
1497-
1498-
static extern (C) void thread_cleanupHandler( void* arg ) nothrow @nogc
1499-
{
1500-
Thread obj = cast(Thread) arg;
1501-
assert( obj );
1502-
1503-
// NOTE: If the thread terminated abnormally, just set it as
1504-
// not running and let thread_suspendAll remove it from
1505-
// the thread list. This is safer and is consistent
1506-
// with the Windows thread code.
1507-
atomicStore!(MemoryOrder.raw)(obj.m_isRunning,false);
1508-
}
1509-
1510-
// NOTE: Using void to skip the initialization here relies on
1511-
// knowledge of how pthread_cleanup is implemented. It may
1512-
// not be appropriate for all platforms. However, it does
1513-
// avoid the need to link the pthread module. If any
1514-
// implementation actually requires default initialization
1515-
// then pthread_cleanup should be restructured to maintain
1516-
// the current lack of a link dependency.
1517-
static if (__traits(compiles, core.sys.posix.pthread.pthread_cleanup))
1518-
{
1519-
import core.sys.posix.pthread : pthread_cleanup;
1520-
1521-
pthread_cleanup cleanup = void;
1522-
cleanup.push( &thread_cleanupHandler, cast(void*) obj );
1523-
}
1524-
else static if (__traits(compiles, core.sys.posix.pthread.pthread_cleanup_push))
1525-
{
1526-
import core.sys.posix.pthread : pthread_cleanup_push;
1527-
1528-
pthread_cleanup_push(&thread_cleanupHandler, cast(void*) obj);
1529-
}
1530-
else
1531-
{
1532-
static assert( false, "Platform not supported." );
1533-
}
1534-
1535-
// NOTE: No GC allocations may occur until the stack pointers have
1536-
// been set and Thread.getThis returns a valid reference to
1537-
// this thread object (this latter condition is not strictly
1538-
// necessary on Windows but it should be followed for the
1539-
// sake of consistency).
1540-
1541-
// TODO: Consider putting an auto exception object here (using
1542-
// alloca) forOutOfMemoryError plus something to track
1543-
// whether an exception is in-flight?
1544-
1545-
void append( Throwable t )
1546-
{
1547-
obj.filterCaughtThrowable(t);
1548-
if (t !is null)
1549-
obj.m_unhandled = Throwable.chainTogether(obj.m_unhandled, t);
1550-
}
1551-
try
1552-
{
1553-
rt_moduleTlsCtor();
1554-
try
1555-
{
1556-
obj.runFromEntryPoint();
1557-
}
1558-
catch ( Throwable t )
1559-
{
1560-
append( t );
1561-
}
1562-
rt_moduleTlsDtor();
1563-
version (Shared)
1564-
{
1565-
externDFunc!("rt.sections_elf_shared.cleanupLoadedLibraries",
1566-
void function() @nogc nothrow)();
1567-
}
1568-
}
1569-
catch ( Throwable t )
1570-
{
1571-
append( t );
1572-
}
1573-
1574-
// NOTE: Normal cleanup is handled by scope(exit).
1575-
1576-
static if (__traits(compiles, core.sys.posix.pthread.pthread_cleanup))
1577-
{
1578-
cleanup.pop( 0 );
1579-
}
1580-
else static if (__traits(compiles, core.sys.posix.pthread.pthread_cleanup_push))
1581-
{
1582-
import core.sys.posix.pthread : pthread_cleanup_pop;
1583-
1584-
pthread_cleanup_pop( 0 );
1585-
}
1586-
1587-
return null;
1588-
}
1589-
1590-
1591-
version (WASI) {}
1592-
else
1593-
{
1594-
//
1595-
// Used to track the number of suspended threads
1596-
//
1597-
__gshared sem_t suspendCount;
1598-
1599-
1600-
extern (C) bool thread_preSuspend( void* sp ) nothrow {
1601-
// NOTE: Since registers are being pushed and popped from the
1602-
// stack, any other stack data used by this function should
1603-
// be gone before the stack cleanup code is called below.
1604-
Thread obj = Thread.getThis();
1605-
if (obj is null)
1606-
{
1607-
return false;
1608-
}
1609-
1610-
if ( !obj.m_lock )
1611-
{
1612-
obj.m_curr.tstack = sp;
1613-
}
1614-
1615-
return true;
1616-
}
1617-
1618-
extern (C) bool thread_postSuspend() nothrow {
1619-
Thread obj = Thread.getThis();
1620-
if (obj is null)
1621-
{
1622-
return false;
1623-
}
1624-
1625-
if ( !obj.m_lock )
1626-
{
1627-
obj.m_curr.tstack = obj.m_curr.bstack;
1628-
}
1629-
1630-
return true;
1631-
}
1632-
1633-
extern (C) void thread_suspendHandler( int sig ) nothrow
1634-
in
1635-
{
1636-
assert( sig == suspendSignalNumber );
1637-
}
1638-
do
1639-
{
1640-
void op(void* sp) nothrow
1641-
{
1642-
int cancel_state = thread_cancelDisable();
1643-
scope(exit) thread_cancelRestore(cancel_state);
1644-
1645-
bool supported = thread_preSuspend(getStackTop());
1646-
assert(supported, "Tried to suspend a detached thread!");
1647-
1648-
scope(exit)
1649-
{
1650-
supported = thread_postSuspend();
1651-
assert(supported, "Tried to suspend a detached thread!");
1652-
}
1653-
1654-
sigset_t sigres = void;
1655-
int status;
1656-
1657-
status = sigfillset( &sigres );
1658-
assert( status == 0 );
1659-
1660-
status = sigdelset( &sigres, resumeSignalNumber );
1661-
assert( status == 0 );
1662-
1663-
status = sem_post( &suspendCount );
1664-
assert( status == 0 );
1665-
1666-
sigsuspend( &sigres );
1667-
}
1668-
callWithStackShell(&op);
1669-
}
1670-
1671-
1672-
extern (C) void thread_resumeHandler( int sig ) nothrow
1673-
in
1674-
{
1675-
assert( sig == resumeSignalNumber );
1676-
}
1677-
do
1678-
{
1679-
1680-
}
1681-
}
1682-
}
1683-
}
1684-
else
1685-
{
1686-
// NOTE: This is the only place threading versions are checked. If a new
1687-
// version is added, the module code will need to be searched for
1688-
// places where version-specific code may be required. This can be
1689-
// easily accomlished by searching for 'Windows' or 'Posix'.
1690-
static assert( false, "Unknown threading implementation." );
1691-
}
1692-
16931329
//
16941330
// exposed by compiler runtime
16951331
//

0 commit comments

Comments
 (0)