//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.Threading;

#if !WASM
namespace CommonHelpers {
#else
namespace CommonHelpers.WASM {
#endif

//**************************************************************************************************
/// <summary>
/// </summary>
public static partial class HThread {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static Thread CurrentThread => Thread.CurrentThread;

//--------------------------------------------------------------------------------------------------

public static void Sleep(TimeSpan timeSpan)
{
   Thread.Sleep( timeSpan );
}

public static void Sleep(int durationInMilliseconds)
{
   Thread.Sleep( durationInMilliseconds );
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="HAssertionFailedException" />
public static HFakeException Hang()
{
   Thread.Sleep( Timeout.Infinite );
   throw HAssertionFailure.DEAD_BRANCH();
}

//==================================================================================================

/// <exception cref="ArgumentNullException" />
/// <exception cref="ThreadStateException" />
/// <exception cref="ThreadInterruptedException" />
[HMemoryBarrier]
public static void Join(Thread thread)
{
   HArgChecking.VerifyNotNull( thread ); thread.Join(); Thread.MemoryBarrier();
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ThreadStateException" />
/// <exception cref="ThreadInterruptedException" />
[HMemoryBarrier]
public static bool Join(Thread thread,int millisecondsTimeout)
{
   HArgChecking.VerifyNotNull( thread );
   bool joined = thread.Join( millisecondsTimeout );
   if ( joined ) Thread.MemoryBarrier();
   return joined;
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ThreadStateException" />
/// <exception cref="ThreadInterruptedException" />
[HMemoryBarrier]
public static bool Join(Thread thread,TimeSpan timeout)
{
   HArgChecking.VerifyNotNull( thread );
   bool joined = thread.Join( timeout );
   if ( joined ) Thread.MemoryBarrier();
   return joined;
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="ArgumentNullException" />
/// <exception cref="ThreadStateException" />
/// <exception cref="ThreadInterruptedException" />
[HMemoryBarrier]
public static void SetNullAndJoin([HInterlockedAccess] ref Thread thread)
{
   Join( HInterlocked.NullExchange(ref thread) );
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ThreadStateException" />
/// <exception cref="ThreadInterruptedException" />
[HMemoryBarrier]
public static bool SetNullAndJoin([HInterlockedAccess] ref Thread thread,int millisecondsTimeout)
{
   return Join( HInterlocked.NullExchange(ref thread), millisecondsTimeout );
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ThreadStateException" />
/// <exception cref="ThreadInterruptedException" />
[HMemoryBarrier]
public static bool SetNullAndJoin([HInterlockedAccess] ref Thread thread,TimeSpan timeout)
{
   return Join( HInterlocked.NullExchange(ref thread), timeout );
}

//==================================================================================================

/// <exception cref="ArgumentNullException" />
/// <exception cref="ThreadStateException" />
/// <exception cref="OutOfMemoryException" />
[HMemoryBarrier]
public static void Start(Thread thread)
{
   HArgChecking.VerifyNotNull( thread ); Thread.MemoryBarrier(); thread.Start();
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ThreadStateException" />
/// <exception cref="OutOfMemoryException" />
[HMemoryBarrier]
public static void Start(Thread thread,object parameter)
{
   HArgChecking.VerifyNotNull( thread ); Thread.MemoryBarrier(); thread.Start( parameter );
}

//==================================================================================================

static HThread()
{
   CommonHelpers_Core.Access();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HThread
//**************************************************************************************************

} // CommonHelpers (.WASM)
