]> git.llucax.com Git - software/druntime.git/blobdiff - src/common/core/thread.d
Removed stdc directory. This was moved to core/stdc.
[software/druntime.git] / src / common / core / thread.d
index d359b2097fc297190306d31ec35c0de7d05a1868..ef8984b63b9a4dcba6c72b9394e04e79ee4997a4 100644 (file)
@@ -84,8 +84,8 @@ version( Windows )
 {
     private
     {
-        import stdc.stdint : uintptr_t; // for _beginthreadex decl below
-        import sys.windows.windows;
+        import core.stdc.stdint : uintptr_t; // for _beginthreadex decl below
+        import core.sys.windows.windows;
 
         const DWORD TLS_OUT_OF_INDEXES  = 0xFFFFFFFF;
 
@@ -151,11 +151,13 @@ else version( Posix )
 {
     private
     {
-        import stdc.posix.semaphore;
-        import stdc.posix.pthread;
-        import stdc.posix.signal;
-        import stdc.posix.time;
-        import stdc.errno;
+        import core.sys.posix.semaphore;
+        import core.sys.posix.pthread;
+        import core.sys.posix.signal;
+        import core.sys.posix.time;
+        import core.stdc.errno;
+
+        extern (C) int getErrno();
 
         version( GNU )
         {
@@ -198,8 +200,20 @@ else version( Posix )
             //       implementation actually requires default initialization
             //       then pthread_cleanup should be restructured to maintain
             //       the current lack of a link dependency.
+            version( linux )
+            {
+                pthread_cleanup cleanup = void;
+                cleanup.push( &thread_cleanupHandler, cast(void*) obj );
+            }
+            else version( darwin )
+            {
             pthread_cleanup cleanup = void;
             cleanup.push( &thread_cleanupHandler, cast(void*) obj );
+            }
+            else
+            {
+                pthread_cleanup_push( &thread_cleanupHandler, cast(void*) obj );
+            }
 
             // NOTE: For some reason this does not always work for threads.
             //obj.m_main.bstack = getStackBottom();
@@ -777,63 +791,88 @@ class Thread
 
 
     /**
-     * Suspends the calling thread for at least the supplied time, up to a
-     * maximum of (uint.max - 1) milliseconds.
+     * Suspends the calling thread for at least the supplied period.  This may
+     * result in multiple OS calls if period is greater than the maximum sleep
+     * duration supported by the operating system.
      *
      * Params:
      *  period = The minimum duration the calling thread should be suspended,
-     *           in seconds.  Sub-second durations are specified as fractional
-     *           values.
+     *           in 100 nanosecond intervals.
      *
      * In:
-     *  period must be less than (uint.max - 1) milliseconds.
+     *  period must be non-negative.
      *
      * Example:
      * ------------------------------------------------------------------------
      *
-     * Thread.sleep( 0.05 ); // sleep for 50 milliseconds
-     * Thread.sleep( 5 );    // sleep for 5 seconds
+     * Thread.sleep( 500 );        // sleep for 50 milliseconds
+     * Thread.sleep( 50_000_000 ); // sleep for 5 seconds
      *
      * ------------------------------------------------------------------------
      */
-    static void sleep( double period )
+    static void sleep( long period )
     in
     {
-        // NOTE: The fractional value added to period is to correct fp error.
-        assert( period * 1000 + 0.1 < uint.max - 1 );
+        assert( period >= 0 );
     }
     body
     {
         version( Win32 )
         {
-            Sleep( cast(uint)( period * 1000 + 0.1 ) );
+            enum : uint
+            {
+                TICKS_PER_MILLI  = 10_000,
+                MAX_SLEEP_MILLIS = uint.max - 1
+            }
+
+            period = period < TICKS_PER_MILLI ?
+                        1 :
+                        period / TICKS_PER_MILLI;
+            while( period > MAX_SLEEP_MILLIS )
+            {
+                Sleep( MAX_SLEEP_MILLIS );
+                period -= MAX_SLEEP_MILLIS;
+            }
+            Sleep( cast(uint) period );
         }
         else version( Posix )
         {
             timespec tin  = void;
             timespec tout = void;
 
-            period += 0.000_000_000_1;
-
-            if( tin.tv_sec.max < period )
+            enum : uint
             {
-                tin.tv_sec  = tin.tv_sec.max;
-                tin.tv_nsec = 0;
+                NANOS_PER_TICK   = 100,
+                TICKS_PER_SECOND = 10_000_000,
             }
-            else
+            enum : typeof(period)
             {
-                tin.tv_sec  = cast(typeof(tin.tv_sec))  period;
-                tin.tv_nsec = cast(typeof(tin.tv_nsec)) ((period % 1.0) * 1_000_000_000);
+                MAX_SLEEP_TICKS = cast(typeof(period)) tin.tv_sec.max * TICKS_PER_SECOND
             }
 
-            while( true )
+            do
             {
-                if( !nanosleep( &tin, &tout ) )
-                    return;
-                if( getErrno() != EINTR )
-                    throw new ThreadException( "Unable to sleep for specified duration" );
-                tin = tout;
-            }
+                if( period > MAX_SLEEP_TICKS )
+                {
+                    tin.tv_sec = tin.tv_sec.max;
+                    tin.tv_nsec = 0;
+                }
+                else
+                {
+                    tin.tv_sec = cast(typeof(tin.tv_sec)) (period / TICKS_PER_SECOND);
+                    tin.tv_nsec = cast(typeof(tin.tv_nsec)) (period % TICKS_PER_SECOND) * NANOS_PER_TICK;
+                }
+                while( true )
+                {
+                    if( !nanosleep( &tin, &tout ) )
+                        return;
+                    if( getErrno() != EINTR )
+                        throw new ThreadException( "Unable to sleep for the specified duration" );
+                    tin = tout;
+                }
+                period -= (cast(typeof(period)) tin.tv_sec) * TICKS_PER_SECOND;
+                period -= (cast(typeof(period)) tin.tv_nsec) / NANOS_PER_TICK;
+            } while( period > 0 );
         }
     }
 
@@ -2218,9 +2257,9 @@ private
 
     version( Posix )
     {
-        import stdc.posix.unistd;   // for sysconf
-        import stdc.posix.sys.mman; // for mmap
-        import stdc.posix.stdlib;   // for malloc, valloc, free
+        import core.sys.posix.unistd;   // for sysconf
+        import core.sys.posix.sys.mman; // for mmap
+        import core.sys.posix.stdlib;   // for malloc, valloc, free
 
         version( AsmX86_Win32 ) {} else
         version( AsmX86_Posix ) {} else
@@ -2232,7 +2271,7 @@ private
             //       a version identifier.  Please note that this is considered
             //       an obsolescent feature according to the POSIX spec, so a
             //       custom solution is still preferred.
-            import stdc.posix.ucontext;
+            import core.sys.posix.ucontext;
         }
     }