@@ -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