/src/core/thread.d

http://github.com/AlexeyProkhin/druntime · D · 4697 lines · 2890 code · 567 blank · 1240 comment · 347 complexity · 672b56f280060a7ede3f5dea172df202 MD5 · raw file

Large files are truncated click here to view the full file

  1. /**
  2. * The thread module provides support for thread creation and management.
  3. *
  4. * Copyright: Copyright Sean Kelly 2005 - 2012.
  5. * License: Distributed under the
  6. * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
  7. * (See accompanying file LICENSE)
  8. * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
  9. * Source: $(DRUNTIMESRC core/_thread.d)
  10. */
  11. module core.thread;
  12. public import core.time; // for Duration
  13. static import rt.tlsgc;
  14. // this should be true for most architectures
  15. version = StackGrowsDown;
  16. /**
  17. * Returns the process ID of the calling process, which is guaranteed to be
  18. * unique on the system. This call is always successful.
  19. *
  20. * Example:
  21. * ---
  22. * writefln("Current process id: %s", getpid());
  23. * ---
  24. */
  25. version(Posix)
  26. {
  27. alias core.sys.posix.unistd.getpid getpid;
  28. }
  29. else version (Windows)
  30. {
  31. alias core.sys.windows.windows.GetCurrentProcessId getpid;
  32. }
  33. ///////////////////////////////////////////////////////////////////////////////
  34. // Thread and Fiber Exceptions
  35. ///////////////////////////////////////////////////////////////////////////////
  36. /**
  37. * Base class for thread exceptions.
  38. */
  39. class ThreadException : Exception
  40. {
  41. this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
  42. {
  43. super(msg, file, line, next);
  44. }
  45. this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)
  46. {
  47. super(msg, file, line, next);
  48. }
  49. }
  50. /**
  51. * Base class for fiber exceptions.
  52. */
  53. class FiberException : Exception
  54. {
  55. this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
  56. {
  57. super(msg, file, line, next);
  58. }
  59. this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)
  60. {
  61. super(msg, file, line, next);
  62. }
  63. }
  64. private
  65. {
  66. import core.sync.mutex;
  67. import core.atomic;
  68. //
  69. // from core.memory
  70. //
  71. extern (C) void gc_enable();
  72. extern (C) void gc_disable();
  73. extern (C) void* gc_malloc(size_t sz, uint ba = 0);
  74. //
  75. // from core.stdc.string
  76. //
  77. extern (C) void* memcpy(void*, const void*, size_t);
  78. //
  79. // exposed by compiler runtime
  80. //
  81. extern (C) void rt_moduleTlsCtor();
  82. extern (C) void rt_moduleTlsDtor();
  83. alias void delegate() gc_atom;
  84. extern (C) void function(scope gc_atom) gc_atomic;
  85. }
  86. ///////////////////////////////////////////////////////////////////////////////
  87. // Thread Entry Point and Signal Handlers
  88. ///////////////////////////////////////////////////////////////////////////////
  89. version( Windows )
  90. {
  91. private
  92. {
  93. import core.stdc.stdint : uintptr_t; // for _beginthreadex decl below
  94. import core.stdc.stdlib; // for malloc, atexit
  95. import core.sys.windows.windows;
  96. import core.sys.windows.threadaux; // for OpenThreadHandle
  97. const DWORD TLS_OUT_OF_INDEXES = 0xFFFFFFFF;
  98. const CREATE_SUSPENDED = 0x00000004;
  99. extern (Windows) alias uint function(void*) btex_fptr;
  100. extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*);
  101. version( DigitalMars )
  102. {
  103. version (Win32)
  104. {
  105. // NOTE: The memory between the addresses of _tlsstart and _tlsend
  106. // is the storage for thread-local data in D 2.0. Both of
  107. // these are defined in dm\src\win32\tlsseg.asm by DMC.
  108. extern (C)
  109. {
  110. extern int _tlsstart;
  111. extern int _tlsend;
  112. }
  113. }
  114. version (Win64)
  115. {
  116. // NOTE: The memory between the addresses of _tls_start and _tls_end
  117. // is the storage for thread-local data in D 2.0. Both of
  118. // these are defined in LIBCMT:tlssub.obj
  119. extern (C)
  120. {
  121. extern int _tls_start;
  122. extern int _tls_end;
  123. }
  124. alias _tls_start _tlsstart;
  125. alias _tls_end _tlsend;
  126. }
  127. }
  128. else version (MinGW)
  129. {
  130. extern (C)
  131. {
  132. extern int _tls_start;
  133. extern int _tls_end;
  134. }
  135. alias _tls_start _tlsstart;
  136. alias _tls_end _tlsend;
  137. }
  138. else
  139. {
  140. __gshared int _tlsstart;
  141. alias _tlsstart _tlsend;
  142. }
  143. //
  144. // Entry point for Windows threads
  145. //
  146. extern (Windows) uint thread_entryPoint( void* arg )
  147. {
  148. Thread obj = cast(Thread) arg;
  149. assert( obj );
  150. assert( obj.m_curr is &obj.m_main );
  151. obj.m_main.bstack = getStackBottom();
  152. obj.m_main.tstack = obj.m_main.bstack;
  153. void* pstart = cast(void*) &_tlsstart;
  154. void* pend = cast(void*) &_tlsend;
  155. obj.m_tls = pstart[0 .. pend - pstart];
  156. Thread.setThis( obj );
  157. //Thread.add( obj );
  158. scope( exit )
  159. {
  160. Thread.remove( obj );
  161. }
  162. Thread.add( &obj.m_main );
  163. obj.m_tlsgcdata = rt.tlsgc.init();
  164. // NOTE: No GC allocations may occur until the stack pointers have
  165. // been set and Thread.getThis returns a valid reference to
  166. // this thread object (this latter condition is not strictly
  167. // necessary on Windows but it should be followed for the
  168. // sake of consistency).
  169. // TODO: Consider putting an auto exception object here (using
  170. // alloca) forOutOfMemoryError plus something to track
  171. // whether an exception is in-flight?
  172. void append( Throwable t )
  173. {
  174. if( obj.m_unhandled is null )
  175. obj.m_unhandled = t;
  176. else
  177. {
  178. Throwable last = obj.m_unhandled;
  179. while( last.next !is null )
  180. last = last.next;
  181. last.next = t;
  182. }
  183. }
  184. version( D_InlineAsm_X86 )
  185. {
  186. asm { fninit; }
  187. }
  188. try
  189. {
  190. rt_moduleTlsCtor();
  191. try
  192. {
  193. obj.run();
  194. }
  195. catch( Throwable t )
  196. {
  197. append( t );
  198. }
  199. rt_moduleTlsDtor();
  200. }
  201. catch( Throwable t )
  202. {
  203. append( t );
  204. }
  205. return 0;
  206. }
  207. HANDLE GetCurrentThreadHandle()
  208. {
  209. const uint DUPLICATE_SAME_ACCESS = 0x00000002;
  210. HANDLE curr = GetCurrentThread(),
  211. proc = GetCurrentProcess(),
  212. hndl;
  213. DuplicateHandle( proc, curr, proc, &hndl, 0, TRUE, DUPLICATE_SAME_ACCESS );
  214. return hndl;
  215. }
  216. }
  217. }
  218. else version( Posix )
  219. {
  220. private
  221. {
  222. import core.stdc.errno;
  223. import core.sys.posix.semaphore;
  224. import core.sys.posix.stdlib; // for malloc, valloc, free, atexit
  225. import core.sys.posix.pthread;
  226. import core.sys.posix.signal;
  227. import core.sys.posix.time;
  228. version( OSX )
  229. {
  230. import core.sys.osx.mach.thread_act;
  231. extern (C) mach_port_t pthread_mach_thread_np(pthread_t);
  232. }
  233. version( GNU )
  234. {
  235. import gcc.builtins;
  236. }
  237. version( DigitalMars )
  238. {
  239. version( linux )
  240. {
  241. extern (C)
  242. {
  243. extern int _tlsstart;
  244. extern int _tlsend;
  245. }
  246. }
  247. else version( OSX )
  248. {
  249. extern (C)
  250. {
  251. __gshared void[][2] _tls_data_array;
  252. }
  253. }
  254. else version( FreeBSD )
  255. {
  256. extern (C)
  257. {
  258. extern void* _tlsstart;
  259. extern void* _tlsend;
  260. }
  261. }
  262. else
  263. {
  264. __gshared int _tlsstart;
  265. alias _tlsstart _tlsend;
  266. }
  267. }
  268. else version (LDC)
  269. {
  270. version = LDC_NoTlsBracketSyms;
  271. }
  272. else
  273. {
  274. __gshared int _tlsstart;
  275. alias _tlsstart _tlsend;
  276. }
  277. //
  278. // Entry point for POSIX threads
  279. //
  280. extern (C) void* thread_entryPoint( void* arg )
  281. {
  282. Thread obj = cast(Thread) arg;
  283. assert( obj );
  284. assert( obj.m_curr is &obj.m_main );
  285. obj.m_main.bstack = getStackBottom();
  286. obj.m_main.tstack = obj.m_main.bstack;
  287. version (LDC_NoTlsBracketSyms)
  288. {
  289. version (OSX)
  290. {
  291. import ldc.memory;
  292. obj.m_tls = getCurrentTLSRange();
  293. }
  294. else
  295. {
  296. // Nothing to do here for Linux – glibc allocates the TLS
  297. // data at the start of the stack area, so we scan it anyway.
  298. }
  299. }
  300. else version(OSX)
  301. {
  302. // NOTE: OSX does not support TLS, so we do it ourselves. The TLS
  303. // data output by the compiler is bracketed by _tls_data_array[2],
  304. // so make a copy of it for each thread.
  305. const sz0 = (_tls_data_array[0].length + 15) & ~cast(size_t)15;
  306. const sz2 = sz0 + _tls_data_array[1].length;
  307. auto p = malloc( sz2 );
  308. assert( p );
  309. obj.m_tls = p[0 .. sz2];
  310. memcpy( p, _tls_data_array[0].ptr, _tls_data_array[0].length );
  311. memcpy( p + sz0, _tls_data_array[1].ptr, _tls_data_array[1].length );
  312. scope (exit) { free( p ); obj.m_tls = null; }
  313. }
  314. else
  315. {
  316. auto pstart = cast(void*) &_tlsstart;
  317. auto pend = cast(void*) &_tlsend;
  318. obj.m_tls = pstart[0 .. pend - pstart];
  319. }
  320. obj.m_isRunning = true;
  321. Thread.setThis( obj );
  322. //Thread.add( obj );
  323. scope( exit )
  324. {
  325. // NOTE: isRunning should be set to false after the thread is
  326. // removed or a double-removal could occur between this
  327. // function and thread_suspendAll.
  328. Thread.remove( obj );
  329. obj.m_isRunning = false;
  330. }
  331. Thread.add( &obj.m_main );
  332. obj.m_tlsgcdata = rt.tlsgc.init();
  333. static extern (C) void thread_cleanupHandler( void* arg ) nothrow
  334. {
  335. Thread obj = cast(Thread) arg;
  336. assert( obj );
  337. // NOTE: If the thread terminated abnormally, just set it as
  338. // not running and let thread_suspendAll remove it from
  339. // the thread list. This is safer and is consistent
  340. // with the Windows thread code.
  341. obj.m_isRunning = false;
  342. }
  343. // NOTE: Using void to skip the initialization here relies on
  344. // knowledge of how pthread_cleanup is implemented. It may
  345. // not be appropriate for all platforms. However, it does
  346. // avoid the need to link the pthread module. If any
  347. // implementation actually requires default initialization
  348. // then pthread_cleanup should be restructured to maintain
  349. // the current lack of a link dependency.
  350. static if( __traits( compiles, pthread_cleanup ) )
  351. {
  352. pthread_cleanup cleanup = void;
  353. cleanup.push( &thread_cleanupHandler, cast(void*) obj );
  354. }
  355. else static if( __traits( compiles, pthread_cleanup_push ) )
  356. {
  357. pthread_cleanup_push( &thread_cleanupHandler, cast(void*) obj );
  358. }
  359. else
  360. {
  361. static assert( false, "Platform not supported." );
  362. }
  363. // NOTE: No GC allocations may occur until the stack pointers have
  364. // been set and Thread.getThis returns a valid reference to
  365. // this thread object (this latter condition is not strictly
  366. // necessary on Windows but it should be followed for the
  367. // sake of consistency).
  368. // TODO: Consider putting an auto exception object here (using
  369. // alloca) forOutOfMemoryError plus something to track
  370. // whether an exception is in-flight?
  371. void append( Throwable t )
  372. {
  373. if( obj.m_unhandled is null )
  374. obj.m_unhandled = t;
  375. else
  376. {
  377. Throwable last = obj.m_unhandled;
  378. while( last.next !is null )
  379. last = last.next;
  380. last.next = t;
  381. }
  382. }
  383. try
  384. {
  385. rt_moduleTlsCtor();
  386. try
  387. {
  388. obj.run();
  389. }
  390. catch( Throwable t )
  391. {
  392. append( t );
  393. }
  394. rt_moduleTlsDtor();
  395. }
  396. catch( Throwable t )
  397. {
  398. append( t );
  399. }
  400. // NOTE: Normal cleanup is handled by scope(exit).
  401. static if( __traits( compiles, pthread_cleanup ) )
  402. {
  403. cleanup.pop( 0 );
  404. }
  405. else static if( __traits( compiles, pthread_cleanup_push ) )
  406. {
  407. pthread_cleanup_pop( 0 );
  408. }
  409. return null;
  410. }
  411. //
  412. // Used to track the number of suspended threads
  413. //
  414. __gshared sem_t suspendCount;
  415. extern (C) void thread_suspendHandler( int sig )
  416. in
  417. {
  418. assert( sig == SIGUSR1 );
  419. }
  420. body
  421. {
  422. void op(void* sp)
  423. {
  424. // NOTE: Since registers are being pushed and popped from the
  425. // stack, any other stack data used by this function should
  426. // be gone before the stack cleanup code is called below.
  427. Thread obj = Thread.getThis();
  428. // NOTE: The thread reference returned by getThis is set within
  429. // the thread startup code, so it is possible that this
  430. // handler may be called before the reference is set. In
  431. // this case it is safe to simply suspend and not worry
  432. // about the stack pointers as the thread will not have
  433. // any references to GC-managed data.
  434. if( obj && !obj.m_lock )
  435. {
  436. obj.m_curr.tstack = getStackTop();
  437. }
  438. sigset_t sigres = void;
  439. int status;
  440. status = sigfillset( &sigres );
  441. assert( status == 0 );
  442. status = sigdelset( &sigres, SIGUSR2 );
  443. assert( status == 0 );
  444. status = sem_post( &suspendCount );
  445. assert( status == 0 );
  446. sigsuspend( &sigres );
  447. if( obj && !obj.m_lock )
  448. {
  449. obj.m_curr.tstack = obj.m_curr.bstack;
  450. }
  451. }
  452. callWithStackShell(&op);
  453. }
  454. extern (C) void thread_resumeHandler( int sig )
  455. in
  456. {
  457. assert( sig == SIGUSR2 );
  458. }
  459. body
  460. {
  461. }
  462. }
  463. }
  464. else
  465. {
  466. // NOTE: This is the only place threading versions are checked. If a new
  467. // version is added, the module code will need to be searched for
  468. // places where version-specific code may be required. This can be
  469. // easily accomlished by searching for 'Windows' or 'Posix'.
  470. static assert( false, "Unknown threading implementation." );
  471. }
  472. ///////////////////////////////////////////////////////////////////////////////
  473. // Thread
  474. ///////////////////////////////////////////////////////////////////////////////
  475. /**
  476. * This class encapsulates all threading functionality for the D
  477. * programming language. As thread manipulation is a required facility
  478. * for garbage collection, all user threads should derive from this
  479. * class, and instances of this class should never be explicitly deleted.
  480. * A new thread may be created using either derivation or composition, as
  481. * in the following example.
  482. *
  483. * Example:
  484. * ----------------------------------------------------------------------------
  485. *
  486. * class DerivedThread : Thread
  487. * {
  488. * this()
  489. * {
  490. * super( &run );
  491. * }
  492. *
  493. * private :
  494. * void run()
  495. * {
  496. * printf( "Derived thread running.\n" );
  497. * }
  498. * }
  499. *
  500. * void threadFunc()
  501. * {
  502. * printf( "Composed thread running.\n" );
  503. * }
  504. *
  505. * // create instances of each type
  506. * Thread derived = new DerivedThread();
  507. * Thread composed = new Thread( &threadFunc );
  508. *
  509. * // start both threads
  510. * derived.start();
  511. * composed.start();
  512. *
  513. * ----------------------------------------------------------------------------
  514. */
  515. class Thread
  516. {
  517. ///////////////////////////////////////////////////////////////////////////
  518. // Initialization
  519. ///////////////////////////////////////////////////////////////////////////
  520. /**
  521. * Initializes a thread object which is associated with a static
  522. * D function.
  523. *
  524. * Params:
  525. * fn = The thread function.
  526. * sz = The stack size for this thread.
  527. *
  528. * In:
  529. * fn must not be null.
  530. */
  531. this( void function() fn, size_t sz = 0 )
  532. in
  533. {
  534. assert( fn );
  535. }
  536. body
  537. {
  538. this();
  539. m_fn = fn;
  540. m_sz = sz;
  541. m_call = Call.FN;
  542. m_curr = &m_main;
  543. }
  544. /**
  545. * Initializes a thread object which is associated with a dynamic
  546. * D function.
  547. *
  548. * Params:
  549. * dg = The thread function.
  550. * sz = The stack size for this thread.
  551. *
  552. * In:
  553. * dg must not be null.
  554. */
  555. this( void delegate() dg, size_t sz = 0 )
  556. in
  557. {
  558. assert( dg );
  559. }
  560. body
  561. {
  562. this();
  563. m_dg = dg;
  564. m_sz = sz;
  565. m_call = Call.DG;
  566. m_curr = &m_main;
  567. }
  568. /**
  569. * Cleans up any remaining resources used by this object.
  570. */
  571. ~this()
  572. {
  573. if( m_addr == m_addr.init )
  574. {
  575. return;
  576. }
  577. version( Windows )
  578. {
  579. m_addr = m_addr.init;
  580. CloseHandle( m_hndl );
  581. m_hndl = m_hndl.init;
  582. }
  583. else version( Posix )
  584. {
  585. pthread_detach( m_addr );
  586. m_addr = m_addr.init;
  587. }
  588. version( OSX )
  589. {
  590. m_tmach = m_tmach.init;
  591. }
  592. rt.tlsgc.destroy( m_tlsgcdata );
  593. m_tlsgcdata = null;
  594. }
  595. ///////////////////////////////////////////////////////////////////////////
  596. // General Actions
  597. ///////////////////////////////////////////////////////////////////////////
  598. /**
  599. * Starts the thread and invokes the function or delegate passed upon
  600. * construction.
  601. *
  602. * In:
  603. * This routine may only be called once per thread instance.
  604. *
  605. * Throws:
  606. * ThreadException if the thread fails to start.
  607. */
  608. final void start()
  609. in
  610. {
  611. assert( !next && !prev );
  612. }
  613. body
  614. {
  615. auto wasThreaded = multiThreadedFlag;
  616. multiThreadedFlag = true;
  617. scope( failure )
  618. {
  619. if( !wasThreaded )
  620. multiThreadedFlag = false;
  621. }
  622. version( Windows ) {} else
  623. version( Posix )
  624. {
  625. pthread_attr_t attr;
  626. if( pthread_attr_init( &attr ) )
  627. throw new ThreadException( "Error initializing thread attributes" );
  628. if( m_sz && pthread_attr_setstacksize( &attr, m_sz ) )
  629. throw new ThreadException( "Error initializing thread stack size" );
  630. if( pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ) )
  631. throw new ThreadException( "Error setting thread joinable" );
  632. }
  633. version( Windows )
  634. {
  635. // NOTE: If a thread is just executing DllMain()
  636. // while another thread is started here, it holds an OS internal
  637. // lock that serializes DllMain with CreateThread. As the code
  638. // might request a synchronization on slock (e.g. in thread_findByAddr()),
  639. // we cannot hold that lock while creating the thread without
  640. // creating a deadlock
  641. //
  642. // Solution: Create the thread in suspended state and then
  643. // add and resume it with slock acquired
  644. assert(m_sz <= uint.max, "m_sz must be less than or equal to uint.max");
  645. m_hndl = cast(HANDLE) _beginthreadex( null, cast(uint) m_sz, &thread_entryPoint, cast(void*) this, CREATE_SUSPENDED, &m_addr );
  646. if( cast(size_t) m_hndl == 0 )
  647. throw new ThreadException( "Error creating thread" );
  648. }
  649. // NOTE: The starting thread must be added to the global thread list
  650. // here rather than within thread_entryPoint to prevent a race
  651. // with the main thread, which could finish and terminat the
  652. // app without ever knowing that it should have waited for this
  653. // starting thread. In effect, not doing the add here risks
  654. // having thread being treated like a daemon thread.
  655. synchronized( slock )
  656. {
  657. version( Windows )
  658. {
  659. if( ResumeThread( m_hndl ) == -1 )
  660. throw new ThreadException( "Error resuming thread" );
  661. }
  662. else version( Posix )
  663. {
  664. // NOTE: This is also set to true by thread_entryPoint, but set it
  665. // here as well so the calling thread will see the isRunning
  666. // state immediately.
  667. m_isRunning = true;
  668. scope( failure ) m_isRunning = false;
  669. if( pthread_create( &m_addr, &attr, &thread_entryPoint, cast(void*) this ) != 0 )
  670. throw new ThreadException( "Error creating thread" );
  671. }
  672. version( OSX )
  673. {
  674. m_tmach = pthread_mach_thread_np( m_addr );
  675. if( m_tmach == m_tmach.init )
  676. throw new ThreadException( "Error creating thread" );
  677. }
  678. // NOTE: when creating threads from inside a DLL, DllMain(THREAD_ATTACH)
  679. // might be called before ResumeThread returns, but the dll
  680. // helper functions need to know whether the thread is created
  681. // from the runtime itself or from another DLL or the application
  682. // to just attach to it
  683. // as a consequence, the new Thread object is added before actual
  684. // creation of the thread. There should be no problem with the GC
  685. // calling thread_suspendAll, because of the slock synchronization
  686. //
  687. // VERIFY: does this actually also apply to other platforms?
  688. add( this );
  689. }
  690. }
  691. /**
  692. * Waits for this thread to complete. If the thread terminated as the
  693. * result of an unhandled exception, this exception will be rethrown.
  694. *
  695. * Params:
  696. * rethrow = Rethrow any unhandled exception which may have caused this
  697. * thread to terminate.
  698. *
  699. * Throws:
  700. * ThreadException if the operation fails.
  701. * Any exception not handled by the joined thread.
  702. *
  703. * Returns:
  704. * Any exception not handled by this thread if rethrow = false, null
  705. * otherwise.
  706. */
  707. final Throwable join( bool rethrow = true )
  708. {
  709. version( Windows )
  710. {
  711. if( WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 )
  712. throw new ThreadException( "Unable to join thread" );
  713. // NOTE: m_addr must be cleared before m_hndl is closed to avoid
  714. // a race condition with isRunning. The operation is done
  715. // with atomicStore to prevent compiler reordering.
  716. atomicStore!(MemoryOrder.raw)(*cast(shared)&m_addr, m_addr.init);
  717. CloseHandle( m_hndl );
  718. m_hndl = m_hndl.init;
  719. }
  720. else version( Posix )
  721. {
  722. if( pthread_join( m_addr, null ) != 0 )
  723. throw new ThreadException( "Unable to join thread" );
  724. // NOTE: pthread_join acts as a substitute for pthread_detach,
  725. // which is normally called by the dtor. Setting m_addr
  726. // to zero ensures that pthread_detach will not be called
  727. // on object destruction.
  728. m_addr = m_addr.init;
  729. }
  730. if( m_unhandled )
  731. {
  732. if( rethrow )
  733. throw m_unhandled;
  734. return m_unhandled;
  735. }
  736. return null;
  737. }
  738. ///////////////////////////////////////////////////////////////////////////
  739. // General Properties
  740. ///////////////////////////////////////////////////////////////////////////
  741. /**
  742. * Gets the user-readable label for this thread.
  743. *
  744. * Returns:
  745. * The name of this thread.
  746. */
  747. final @property string name()
  748. {
  749. synchronized( this )
  750. {
  751. return m_name;
  752. }
  753. }
  754. /**
  755. * Sets the user-readable label for this thread.
  756. *
  757. * Params:
  758. * val = The new name of this thread.
  759. */
  760. final @property void name( string val )
  761. {
  762. synchronized( this )
  763. {
  764. m_name = val;
  765. }
  766. }
  767. /**
  768. * Gets the daemon status for this thread. While the runtime will wait for
  769. * all normal threads to complete before tearing down the process, daemon
  770. * threads are effectively ignored and thus will not prevent the process
  771. * from terminating. In effect, daemon threads will be terminated
  772. * automatically by the OS when the process exits.
  773. *
  774. * Returns:
  775. * true if this is a daemon thread.
  776. */
  777. final @property bool isDaemon()
  778. {
  779. synchronized( this )
  780. {
  781. return m_isDaemon;
  782. }
  783. }
  784. /**
  785. * Sets the daemon status for this thread. While the runtime will wait for
  786. * all normal threads to complete before tearing down the process, daemon
  787. * threads are effectively ignored and thus will not prevent the process
  788. * from terminating. In effect, daemon threads will be terminated
  789. * automatically by the OS when the process exits.
  790. *
  791. * Params:
  792. * val = The new daemon status for this thread.
  793. */
  794. final @property void isDaemon( bool val )
  795. {
  796. synchronized( this )
  797. {
  798. m_isDaemon = val;
  799. }
  800. }
  801. /**
  802. * Tests whether this thread is running.
  803. *
  804. * Returns:
  805. * true if the thread is running, false if not.
  806. */
  807. final @property bool isRunning()
  808. {
  809. if( m_addr == m_addr.init )
  810. {
  811. return false;
  812. }
  813. version( Windows )
  814. {
  815. uint ecode = 0;
  816. GetExitCodeThread( m_hndl, &ecode );
  817. return ecode == STILL_ACTIVE;
  818. }
  819. else version( Posix )
  820. {
  821. // NOTE: It should be safe to access this value without
  822. // memory barriers because word-tearing and such
  823. // really isn't an issue for boolean values.
  824. return m_isRunning;
  825. }
  826. }
  827. ///////////////////////////////////////////////////////////////////////////
  828. // Thread Priority Actions
  829. ///////////////////////////////////////////////////////////////////////////
  830. /**
  831. * The minimum scheduling priority that may be set for a thread. On
  832. * systems where multiple scheduling policies are defined, this value
  833. * represents the minimum valid priority for the scheduling policy of
  834. * the process.
  835. */
  836. __gshared const int PRIORITY_MIN;
  837. /**
  838. * The maximum scheduling priority that may be set for a thread. On
  839. * systems where multiple scheduling policies are defined, this value
  840. * represents the minimum valid priority for the scheduling policy of
  841. * the process.
  842. */
  843. __gshared const int PRIORITY_MAX;
  844. /**
  845. * Gets the scheduling priority for the associated thread.
  846. *
  847. * Returns:
  848. * The scheduling priority of this thread.
  849. */
  850. final @property int priority()
  851. {
  852. version( Windows )
  853. {
  854. return GetThreadPriority( m_hndl );
  855. }
  856. else version( Posix )
  857. {
  858. int policy;
  859. sched_param param;
  860. if( pthread_getschedparam( m_addr, &policy, &param ) )
  861. throw new ThreadException( "Unable to get thread priority" );
  862. return param.sched_priority;
  863. }
  864. }
  865. /**
  866. * Sets the scheduling priority for the associated thread.
  867. *
  868. * Params:
  869. * val = The new scheduling priority of this thread.
  870. */
  871. final @property void priority( int val )
  872. {
  873. version( Windows )
  874. {
  875. if( !SetThreadPriority( m_hndl, val ) )
  876. throw new ThreadException( "Unable to set thread priority" );
  877. }
  878. else version( Posix )
  879. {
  880. // NOTE: pthread_setschedprio is not implemented on linux, so use
  881. // the more complicated get/set sequence below.
  882. //if( pthread_setschedprio( m_addr, val ) )
  883. // throw new ThreadException( "Unable to set thread priority" );
  884. int policy;
  885. sched_param param;
  886. if( pthread_getschedparam( m_addr, &policy, &param ) )
  887. throw new ThreadException( "Unable to set thread priority" );
  888. param.sched_priority = val;
  889. if( pthread_setschedparam( m_addr, policy, &param ) )
  890. throw new ThreadException( "Unable to set thread priority" );
  891. }
  892. }
  893. ///////////////////////////////////////////////////////////////////////////
  894. // Actions on Calling Thread
  895. ///////////////////////////////////////////////////////////////////////////
  896. /**
  897. * Suspends the calling thread for at least the supplied period. This may
  898. * result in multiple OS calls if period is greater than the maximum sleep
  899. * duration supported by the operating system.
  900. *
  901. * Params:
  902. * val = The minimum duration the calling thread should be suspended.
  903. *
  904. * In:
  905. * period must be non-negative.
  906. *
  907. * Example:
  908. * ------------------------------------------------------------------------
  909. *
  910. * Thread.sleep( dur!("msecs")( 50 ) ); // sleep for 50 milliseconds
  911. * Thread.sleep( dur!("seconds")( 5 ) ); // sleep for 5 seconds
  912. *
  913. * ------------------------------------------------------------------------
  914. */
  915. static void sleep( Duration val )
  916. in
  917. {
  918. assert( !val.isNegative );
  919. }
  920. body
  921. {
  922. version( Windows )
  923. {
  924. auto maxSleepMillis = dur!("msecs")( uint.max - 1 );
  925. // NOTE: In instances where all other threads in the process have a
  926. // lower priority than the current thread, the current thread
  927. // will not yield with a sleep time of zero. However, unlike
  928. // yield(), the user is not asking for a yield to occur but
  929. // only for execution to suspend for the requested interval.
  930. // Therefore, expected performance may not be met if a yield
  931. // is forced upon the user.
  932. while( val > maxSleepMillis )
  933. {
  934. Sleep( cast(uint)
  935. maxSleepMillis.total!"msecs" );
  936. val -= maxSleepMillis;
  937. }
  938. Sleep( cast(uint) val.total!"msecs" );
  939. }
  940. else version( Posix )
  941. {
  942. timespec tin = void;
  943. timespec tout = void;
  944. if( val.total!"seconds" > tin.tv_sec.max )
  945. {
  946. tin.tv_sec = tin.tv_sec.max;
  947. tin.tv_nsec = cast(typeof(tin.tv_nsec)) val.fracSec.nsecs;
  948. }
  949. else
  950. {
  951. tin.tv_sec = cast(typeof(tin.tv_sec)) val.total!"seconds";
  952. tin.tv_nsec = cast(typeof(tin.tv_nsec)) val.fracSec.nsecs;
  953. }
  954. while( true )
  955. {
  956. if( !nanosleep( &tin, &tout ) )
  957. return;
  958. if( errno != EINTR )
  959. throw new ThreadException( "Unable to sleep for the specified duration" );
  960. tin = tout;
  961. }
  962. }
  963. }
  964. /**
  965. * $(RED Deprecated. It will be removed in December 2012. Please use the
  966. * version which takes a $(D Duration) instead.)
  967. *
  968. * Suspends the calling thread for at least the supplied period. This may
  969. * result in multiple OS calls if period is greater than the maximum sleep
  970. * duration supported by the operating system.
  971. *
  972. * Params:
  973. * period = The minimum duration the calling thread should be suspended,
  974. * in 100 nanosecond intervals.
  975. *
  976. * In:
  977. * period must be non-negative.
  978. *
  979. * Example:
  980. * ------------------------------------------------------------------------
  981. *
  982. * Thread.sleep( 500_000 ); // sleep for 50 milliseconds
  983. * Thread.sleep( 50_000_000 ); // sleep for 5 seconds
  984. *
  985. * ------------------------------------------------------------------------
  986. */
  987. deprecated("Please use the overload of sleep which takes a Duration.")
  988. static void sleep( long period )
  989. in
  990. {
  991. assert( period >= 0 );
  992. }
  993. body
  994. {
  995. sleep( dur!"hnsecs"( period ) );
  996. }
  997. /**
  998. * Forces a context switch to occur away from the calling thread.
  999. */
  1000. static void yield()
  1001. {
  1002. version( Windows )
  1003. SwitchToThread();
  1004. else version( Posix )
  1005. sched_yield();
  1006. }
  1007. ///////////////////////////////////////////////////////////////////////////
  1008. // Thread Accessors
  1009. ///////////////////////////////////////////////////////////////////////////
  1010. /**
  1011. * Provides a reference to the calling thread.
  1012. *
  1013. * Returns:
  1014. * The thread object representing the calling thread. The result of
  1015. * deleting this object is undefined. If the current thread is not
  1016. * attached to the runtime, a null reference is returned.
  1017. */
  1018. static Thread getThis()
  1019. {
  1020. // NOTE: This function may not be called until thread_init has
  1021. // completed. See thread_suspendAll for more information
  1022. // on why this might occur.
  1023. version( Windows )
  1024. {
  1025. auto t = cast(Thread) TlsGetValue( sm_this );
  1026. // NOTE: If this thread was attached via thread_attachByAddr then
  1027. // this TLS lookup won't initially be set, so when the TLS
  1028. // lookup fails, try an exhaustive search.
  1029. if( t is null )
  1030. {
  1031. t = thread_findByAddr( GetCurrentThreadId() );
  1032. setThis( t );
  1033. }
  1034. return t;
  1035. }
  1036. else version( Posix )
  1037. {
  1038. auto t = cast(Thread) pthread_getspecific( sm_this );
  1039. // NOTE: See the comment near thread_findByAddr() for why the
  1040. // secondary thread_findByAddr lookup can't be done on
  1041. // Posix. However, because thread_attachByAddr() is for
  1042. // Windows only, the secondary lookup is pointless anyway.
  1043. return t;
  1044. }
  1045. }
  1046. /**
  1047. * Provides a list of all threads currently being tracked by the system.
  1048. *
  1049. * Returns:
  1050. * An array containing references to all threads currently being
  1051. * tracked by the system. The result of deleting any contained
  1052. * objects is undefined.
  1053. */
  1054. static Thread[] getAll()
  1055. {
  1056. synchronized( slock )
  1057. {
  1058. size_t pos = 0;
  1059. Thread[] buf = new Thread[sm_tlen];
  1060. foreach( Thread t; Thread )
  1061. {
  1062. buf[pos++] = t;
  1063. }
  1064. return buf;
  1065. }
  1066. }
  1067. /**
  1068. * Operates on all threads currently being tracked by the system. The
  1069. * result of deleting any Thread object is undefined.
  1070. *
  1071. * Params:
  1072. * dg = The supplied code as a delegate.
  1073. *
  1074. * Returns:
  1075. * Zero if all elemented are visited, nonzero if not.
  1076. */
  1077. static int opApply( scope int delegate( ref Thread ) dg )
  1078. {
  1079. synchronized( slock )
  1080. {
  1081. int ret = 0;
  1082. for( Thread t = sm_tbeg; t; t = t.next )
  1083. {
  1084. ret = dg( t );
  1085. if( ret )
  1086. break;
  1087. }
  1088. return ret;
  1089. }
  1090. }
  1091. ///////////////////////////////////////////////////////////////////////////
  1092. // Static Initalizer
  1093. ///////////////////////////////////////////////////////////////////////////
  1094. /**
  1095. * This initializer is used to set thread constants. All functional
  1096. * initialization occurs within thread_init().
  1097. */
  1098. shared static this()
  1099. {
  1100. version( Windows )
  1101. {
  1102. PRIORITY_MIN = -15;
  1103. PRIORITY_MAX = 15;
  1104. }
  1105. else version( Posix )
  1106. {
  1107. int policy;
  1108. sched_param param;
  1109. pthread_t self = pthread_self();
  1110. int status = pthread_getschedparam( self, &policy, &param );
  1111. assert( status == 0 );
  1112. PRIORITY_MIN = sched_get_priority_min( policy );
  1113. assert( PRIORITY_MIN != -1 );
  1114. PRIORITY_MAX = sched_get_priority_max( policy );
  1115. assert( PRIORITY_MAX != -1 );
  1116. }
  1117. }
  1118. ///////////////////////////////////////////////////////////////////////////
  1119. // Stuff That Should Go Away
  1120. ///////////////////////////////////////////////////////////////////////////
  1121. private:
  1122. //
  1123. // Initializes a thread object which has no associated executable function.
  1124. // This is used for the main thread initialized in thread_init().
  1125. //
  1126. this()
  1127. {
  1128. m_call = Call.NO;
  1129. m_curr = &m_main;
  1130. version (LDC_NoTlsBracketSyms) {} else
  1131. version (OSX)
  1132. {
  1133. //printf("test2 %p %p\n", _tls_data_array[0].ptr, &_tls_data_array[1][length]);
  1134. //printf("test2 %p %p\n", &_tls_beg, &_tls_end);
  1135. // NOTE: OSX does not support TLS, so we do it ourselves. The TLS
  1136. // data output by the compiler is bracketed by _tls_data_array2],
  1137. // so make a copy of it for each thread.
  1138. const sz0 = (_tls_data_array[0].length + 15) & ~cast(size_t)15;
  1139. const sz2 = sz0 + _tls_data_array[1].length;
  1140. auto p = malloc( sz2 );
  1141. assert( p );
  1142. m_tls = p[0 .. sz2];
  1143. memcpy( p, _tls_data_array[0].ptr, _tls_data_array[0].length );
  1144. memcpy( p + sz0, _tls_data_array[1].ptr, _tls_data_array[1].length );
  1145. // The free must happen at program end, if anywhere.
  1146. }
  1147. else
  1148. {
  1149. auto pstart = cast(void*) &_tlsstart;
  1150. auto pend = cast(void*) &_tlsend;
  1151. m_tls = pstart[0 .. pend - pstart];
  1152. }
  1153. }
  1154. //
  1155. // Thread entry point. Invokes the function or delegate passed on
  1156. // construction (if any).
  1157. //
  1158. final void run()
  1159. {
  1160. switch( m_call )
  1161. {
  1162. case Call.FN:
  1163. m_fn();
  1164. break;
  1165. case Call.DG:
  1166. m_dg();
  1167. break;
  1168. default:
  1169. break;
  1170. }
  1171. }
  1172. private:
  1173. //
  1174. // The type of routine passed on thread construction.
  1175. //
  1176. enum Call
  1177. {
  1178. NO,
  1179. FN,
  1180. DG
  1181. }
  1182. //
  1183. // Standard types
  1184. //
  1185. version( Windows )
  1186. {
  1187. alias uint TLSKey;
  1188. alias uint ThreadAddr;
  1189. }
  1190. else version( Posix )
  1191. {
  1192. alias pthread_key_t TLSKey;
  1193. alias pthread_t ThreadAddr;
  1194. }
  1195. //
  1196. // Local storage
  1197. //
  1198. __gshared TLSKey sm_this;
  1199. //
  1200. // Main process thread
  1201. //
  1202. __gshared Thread sm_main;
  1203. //
  1204. // Standard thread data
  1205. //
  1206. version( Windows )
  1207. {
  1208. HANDLE m_hndl;
  1209. }
  1210. else version( OSX )
  1211. {
  1212. mach_port_t m_tmach;
  1213. }
  1214. ThreadAddr m_addr;
  1215. Call m_call;
  1216. string m_name;
  1217. union
  1218. {
  1219. void function() m_fn;
  1220. void delegate() m_dg;
  1221. }
  1222. size_t m_sz;
  1223. version( Posix )
  1224. {
  1225. bool m_isRunning;
  1226. }
  1227. bool m_isDaemon;
  1228. bool m_isInCriticalRegion;
  1229. Throwable m_unhandled;
  1230. private:
  1231. ///////////////////////////////////////////////////////////////////////////
  1232. // Storage of Active Thread
  1233. ///////////////////////////////////////////////////////////////////////////
  1234. //
  1235. // Sets a thread-local reference to the current thread object.
  1236. //
  1237. static void setThis( Thread t )
  1238. {
  1239. version( Windows )
  1240. {
  1241. TlsSetValue( sm_this, cast(void*) t );
  1242. }
  1243. else version( Posix )
  1244. {
  1245. pthread_setspecific( sm_this, cast(void*) t );
  1246. }
  1247. }
  1248. private:
  1249. ///////////////////////////////////////////////////////////////////////////
  1250. // Thread Context and GC Scanning Support
  1251. ///////////////////////////////////////////////////////////////////////////
  1252. final void pushContext( Context* c )
  1253. in
  1254. {
  1255. assert( !c.within );
  1256. }
  1257. body
  1258. {
  1259. c.within = m_curr;
  1260. m_curr = c;
  1261. }
  1262. final void popContext()
  1263. in
  1264. {
  1265. assert( m_curr && m_curr.within );
  1266. }
  1267. body
  1268. {
  1269. Context* c = m_curr;
  1270. m_curr = c.within;
  1271. c.within = null;
  1272. }
  1273. final Context* topContext()
  1274. in
  1275. {
  1276. assert( m_curr );
  1277. }
  1278. body
  1279. {
  1280. return m_curr;
  1281. }
  1282. static struct Context
  1283. {
  1284. void* bstack,
  1285. tstack;
  1286. Context* within;
  1287. Context* next,
  1288. prev;
  1289. }
  1290. Context m_main;
  1291. Context* m_curr;
  1292. bool m_lock;
  1293. void[] m_tls; // spans implicit thread local storage
  1294. rt.tlsgc.Data* m_tlsgcdata;
  1295. version( Windows )
  1296. {
  1297. version( X86 )
  1298. {
  1299. uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax
  1300. }
  1301. else version( X86_64 )
  1302. {
  1303. ulong[16] m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax
  1304. // r8,r9,r10,r11,r12,r13,r14,r15
  1305. }
  1306. else
  1307. {
  1308. static assert(false, "Architecture not supported." );
  1309. }
  1310. }
  1311. else version( OSX )
  1312. {
  1313. version( X86 )
  1314. {
  1315. uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax
  1316. }
  1317. else version( X86_64 )
  1318. {
  1319. ulong[16] m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax
  1320. // r8,r9,r10,r11,r12,r13,r14,r15
  1321. }
  1322. else
  1323. {
  1324. static assert(false, "Architecture not supported." );
  1325. }
  1326. }
  1327. private:
  1328. ///////////////////////////////////////////////////////////////////////////
  1329. // GC Scanning Support
  1330. ///////////////////////////////////////////////////////////////////////////
  1331. // NOTE: The GC scanning process works like so:
  1332. //
  1333. // 1. Suspend all threads.
  1334. // 2. Scan the stacks of all suspended threads for roots.
  1335. // 3. Resume all threads.
  1336. //
  1337. // Step 1 and 3 require a list of all threads in the system, while
  1338. // step 2 requires a list of all thread stacks (each represented by
  1339. // a Context struct). Traditionally, there was one stack per thread
  1340. // and the Context structs were not necessary. However, Fibers have
  1341. // changed things so that each thread has its own 'main' stack plus
  1342. // an arbitrary number of nested stacks (normally referenced via
  1343. // m_curr). Also, there may be 'free-floating' stacks in the system,
  1344. // which are Fibers that are not currently executing on any specific
  1345. // thread but are still being processed and still contain valid
  1346. // roots.
  1347. //
  1348. // To support all of this, the Context struct has been created to
  1349. // represent a stack range, and a global list of Context structs has
  1350. // been added to enable scanning of these stack ranges. The lifetime
  1351. // (and presence in the Context list) of a thread's 'main' stack will
  1352. // be equivalent to the thread's lifetime. So the Ccontext will be
  1353. // added to the list on thread entry, and removed from the list on
  1354. // thread exit (which is essentially the same as the presence of a
  1355. // Thread object in its own global list). The lifetime of a Fiber's
  1356. // context, however, will be tied to the lifetime of the Fiber object
  1357. // itself, and Fibers are expected to add/remove their Context struct
  1358. // on construction/deletion.
  1359. //
  1360. // All use of the global lists should synchronize on this lock.
  1361. //
  1362. @property static Mutex slock()
  1363. {
  1364. __gshared Mutex m;
  1365. __gshared byte[__traits(classInstanceSize, Mutex)] ms;
  1366. if (m is null)
  1367. {
  1368. // Initialization doesn't need to be synchronized because
  1369. // creating a thread will lock this mutex.
  1370. ms[] = Mutex.classinfo.init[];
  1371. m = cast(Mutex)ms.ptr;
  1372. m.__ctor();
  1373. extern(C) void destroy() { m.__dtor(); }
  1374. atexit(&destroy);
  1375. }
  1376. return m;
  1377. }
  1378. __gshared Context* sm_cbeg;
  1379. __gshared size_t sm_clen;
  1380. __gshared Thread sm_tbeg;
  1381. __gshared size_t sm_tlen;
  1382. //
  1383. // Used for ordering threads in the global thread list.
  1384. //
  1385. Thread prev;
  1386. Thread next;
  1387. ///////////////////////////////////////////////////////////////////////////
  1388. // Global Context List Operations
  1389. ///////////////////////////////////////////////////////////////////////////
  1390. //
  1391. // Add a context to the global context list.
  1392. //
  1393. static void add( Context* c )
  1394. in
  1395. {
  1396. assert( c );
  1397. assert( !c.next && !c.prev );
  1398. }
  1399. body
  1400. {
  1401. // NOTE: This loop is necessary to avoid a race between newly created
  1402. // threads and the GC. If a collection starts between the time
  1403. // Thread.start is called and the new thread calls Thread.add,
  1404. // the thread will have its stack scanned without first having
  1405. // been properly suspended. Testing has shown this to sometimes
  1406. // cause a deadlock.
  1407. while( true )
  1408. {
  1409. synchronized( slock )
  1410. {
  1411. if( !suspendDepth )
  1412. {
  1413. if( sm_cbeg )
  1414. {
  1415. c.next = sm_cbeg;
  1416. sm_cbeg.prev = c;
  1417. }
  1418. sm_cbeg = c;
  1419. ++sm_clen;
  1420. return;
  1421. }
  1422. }
  1423. yield();
  1424. }
  1425. }
  1426. //
  1427. // Remove a context from the global context list.
  1428. //
  1429. static void remove( Context* c )
  1430. in
  1431. {
  1432. assert( c );
  1433. assert( c.next || c.prev );
  1434. }
  1435. body
  1436. {
  1437. synchronized( slock )
  1438. {
  1439. if( c.prev )
  1440. c.prev.next = c.next;
  1441. if( c.next )
  1442. c.next.prev = c.prev;
  1443. if( sm_cbeg == c )
  1444. sm_cbeg = c.next;
  1445. --sm_clen;
  1446. }
  1447. // NOTE: Don't null out c.next or c.prev because opApply currently
  1448. // follows c.next after removing a node. This could be easily
  1449. // addressed by simply returning the next node from this
  1450. // function, however, a context should never be re-added to the
  1451. // list anyway and having next and prev be non-null is a good way
  1452. // to ensure that.
  1453. }
  1454. ///////////////////////////////////////////////////////////////////////////
  1455. // Global Thread List Operations
  1456. ///////////////////////////////////////////////////////////////////////////
  1457. //
  1458. // Add a thread to the global thread list.
  1459. //
  1460. static void add( Thread t )
  1461. in
  1462. {
  1463. assert( t );
  1464. assert( !t.next && !t.prev );
  1465. //assert( t.isRunning );
  1466. }
  1467. body
  1468. {
  1469. // NOTE: This loop is necessary to avoid a race between newly created
  1470. // threads and the GC. If a collection starts between the time
  1471. // Thread.start is called and the new thread calls Thread.add,
  1472. // the thread could manipulate global state while the collection
  1473. // is running, and by being…