//     ____   ______ __
//    / __ \ / ____// /
//   / /_/ // /    / /
//  / ____// /___ / /___   PixInsight Class Library
// /_/     \____//_____/   PCL 2.4.23
// ----------------------------------------------------------------------------
// pcl/Thread.h - Released 2022-03-12T18:59:29Z
// ----------------------------------------------------------------------------
// This file is part of the PixInsight Class Library (PCL).
// PCL is a multiplatform C++ framework for development of PixInsight modules.
//
// Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved.
//
// Redistribution and use in both source and binary forms, with or without
// modification, is permitted provided that the following conditions are met:
//
// 1. All redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
// 2. All redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
//    of their contributors, may be used to endorse or promote products derived
//    from this software without specific prior written permission. For written
//    permission, please contact info@pixinsight.com.
//
// 4. All products derived from this software, in any form whatsoever, must
//    reproduce the following acknowledgment in the end-user documentation
//    and/or other materials provided with the product:
//
//    "This product is based on software from the PixInsight project, developed
//    by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
//
//    Alternatively, if that is where third-party acknowledgments normally
//    appear, this acknowledgment must be reproduced in the product itself.
//
// THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
// INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
// DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// ----------------------------------------------------------------------------

#ifndef __PCL_Thread_h
#define __PCL_Thread_h

/// \file pcl/Thread.h

#include <pcl/Defs.h>

#include <pcl/String.h>
#include <pcl/UIObject.h>

namespace pcl
{

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

/*!
 * \defgroup thread_support Thread Support Classes and Functions
 */

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

/*!
 * \namespace pcl::ThreadPriority
 * \brief     Thread scheduling priorities.
 *
 * <table border="1" cellpadding="4" cellspacing="0">
 * <tr><td>ThreadPriority::Inherit</td>      <td>Inherit the caller's thread priority. This is the default value.</td></tr>
 * <tr><td>ThreadPriority::Idle</td>         <td>Schedule when no other threads are busy.</td></tr>
 * <tr><td>ThreadPriority::Lowest</td>       <td>Schedule more often than \e idle priority, but less than \e low priority.</td></tr>
 * <tr><td>ThreadPriority::Low</td>          <td>Schedule more often than \e lowest priority, but less than \e normal priority.</td></tr>
 * <tr><td>ThreadPriority::Normal</td>       <td>Standard thread priority.</td></tr>
 * <tr><td>ThreadPriority::High</td>         <td>Schedule more often than \e normal priority, but less than \e highest priority.</td></tr>
 * <tr><td>ThreadPriority::Highest</td>      <td>Schedule more often than \e high priority, but less than \e time-critical priority.</td></tr>
 * <tr><td>ThreadPriority::TimeCritical</td> <td>Schedule as often as possible, taking precedence over any other threads.</td></tr>
 * <tr><td>ThreadPriority::DefaultMax</td>   <td>Default maximum priority. This is a platform-dependent, maximum thread priority recommended for processing modules.</td></tr>
 * </table>
 *
 * Note that not all platforms and operating systems handle thread scheduling
 * priorities in the same way. In general, modules should use the default
 * maximum thread priority by specifying ThreadPriority::DefaultMax instead of
 * hard-coded priority values. Time-critical priority should be reserved for
 * performance-critical, very brief and fast tasks exclusively, and should only
 * be used when it is \e really necessary. This is particularly important on
 * Windows platforms.
 *
 * \ingroup thread_support
 */
namespace ThreadPriority
{
   enum value_type
   {
      Inherit,       // Inherit caller's thread priority.
      Idle,          // Schedule when no other threads are busy.
      Lowest,
      Low,
      Normal,        // Standard thread priority
      High,
      Highest,
      TimeCritical,  // Schedule as often as possible, taking precedence over any other threads.
#ifdef __PCL_WINDOWS
      DefaultMax = Normal // On Windows, anything above Normal is the same as TimeCritical ...
#else
      DefaultMax = Highest
#endif
   };
}

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

/*!
 * \class Thread
 * \brief Client-side interface to a PixInsight thread.
 *
 * ### TODO: Write a detailed description for %Thread
 *
 * \ingroup thread_support
 */
class PCL_CLASS Thread : public UIObject
{
public:

   /*!
    * Represents a thread priority.
    */
   typedef ThreadPriority::value_type  priority;

   /*!
    * Constructs a %Thread object.
    */
   Thread();

   /*!
    * Destroys a %Thread object.
    */
   virtual ~Thread()
   {
   }

   /*!
    * Ensures that the server-side object managed by this instance is uniquely
    * referenced.
    *
    * Since threads are unique objects by nature, calling this member function
    * has no effect.
    */
   void EnsureUnique() override
   {
      // Threads are unique objects by definition.
   }

   /*!
    * Returns a reference to a null %Thread instance.
    *
    * A null %Thread does not correspond to an existing thread in the core
    * PixInsight application.
    */
   static Thread& Null();

   /*!
    * Starts thread execution with the specified scheduling \a priority and CPU
    * affinity to the specified \a processor.
    *
    * After calling this member function, the PixInsight core application will
    * create a new execution thread from which the Run() virtual member
    * function will be invoked for this %Thread instance.
    *
    * By default, the calling thread's scheduling priority is inherited by
    * newly created threads. In general, to maximize performance in a way well
    * adapted to the running platform, ThreadPriority::DefaultMax should be
    * specified as the value of the \a priority parameter.
    *
    * By default, threads have no specific CPU affinity. By specifying a valid
    * \a processor index, a thread can be scheduled to run on a specific
    * logical processor. When the specified \a processor is >= 0, the internal
    * thread dispatcher will set the corresponding CPU affinity when this
    * thread is executed, just before calling its Run() virtual member
    * function. This is usually a more convenient way to control thread
    * affinity than the SetAffinity() member function, because it allows
    * setting CPU affinity before a thread starts execution.
    *
    * \note Currently, thread affinity can only be set on Linux and Windows
    * platforms. On FreeBSD and Mac OS X, specifying a processor with this
    * function has no effect. We hope to overcome this limitation in a future
    * version of PCL.
    *
    * \note Since version 1.8.0 of the PixInsight core application, nested
    * parallelism is fully supported. This means that multiple threads can be
    * run by calling Thread::Start() from either the root thread or any running
    * %Thread object. In versions prior to 1.8.0, a thread could only be run
    * from the root thread.
    */
   void Start( priority = ThreadPriority::Inherit, int processor = -1 );

   /*!
    * Returns a set of processor indices corresponding to this thread's
    * \e CPU \e affinity.
    *
    * The affinity of a thread defines the set of logical processors on which
    * the thread is eligible to run. %Thread affinity allows to improve
    * execution speed by restricting each thread to run on a separate
    * processor. This prevents the performance cost caused by the cache
    * invalidation that occurs when a process ceases to execute on one
    * processor and then restarts execution on a different one (e.g. the
    * infamous <em>ping-pong effect</em>).
    *
    * If this thread is not running, this function returns the affinity of the
    * calling thread.
    *
    * \note Currently, this function only works on Linux. On FreeBSD, Mac OS X
    * and Windows platforms, this function always returns an empty array. We
    * hope to overcome this limitation in a future version of PCL.
    */
   Array<int> Affinity() const;

   /*!
    * Sets the affinity of this thread to the specified set of \a processors.
    *
    * Each element on the specified \a processors array is a zero-based index
    * corresponding to an existing logical processor. The first processor has
    * index zero and the last one has index n-1, where n is the total number of
    * logical processors on the host machine. Logical processors include
    * physical processors and processor cores, as well as logical processors on
    * systems with hyper-threading technology.
    *
    * Returns true iff the operation was performed correctly. In general, this
    * function returns false if this thread is not running, or if the specified
    * set contains nonexistent processor indices. It can also return false if
    * the calling process does not have the necessary privileges, altough this
    * should not happen under normal conditions.
    *
    * \note The CPU affinity of the calling thread cannot be changed with this
    * function. If this thread is not running, this function returns false and
    * does nothing.
    *
    * \note Currently, thread affinity can only be set on Linux and Windows
    * platforms. On FreeBSD and Mac OS X, calling this function has no effect.
    * We hope to overcome this limitation in a future version of PCL.
    */
   bool SetAffinity( const Array<int>& processors );

   /*!
    * Sets the CPU affinity of this thread to the specified \a processor.
    *
    * The specified \a processor is a zero-based index corresponding to an
    * existing logical processor. The first processor has index zero and the
    * last one has index n-1, where n is the total number of logical processors
    * on the host machine. Logical processors include physical processors and
    * processor cores, as well as logical processors on systems with
    * hyper-threading technology.
    *
    * Returns true iff the operation was performed correctly. In general, this
    * function returns false if this thread is not running, or if the specified
    * processor does not exist. It can also return false if the calling process
    * does not have the necessary privileges, altough this should not happen
    * under normal conditions.
    *
    * \note The CPU affinity of the calling thread cannot be changed with this
    * function. If this thread is not running, this function returns false and
    * does nothing.
    *
    * \note Currently, thread affinity can only be set on Linux and Windows
    * platforms. On FreeBSD and Mac OS X, calling this function has no effect.
    * We hope to overcome this limitation in a future version of PCL.
    */
   bool SetAffinity( int processor );

   /*!
    * Forces immediate termination of thread execution.
    *
    * \warning Calling this function is dangerous because it causes the
    * immediate termination of a running thread without giving it a chance to
    * perform any cleanup. For example, open files will not be closed, locked
    * objects will not be unlocked, and shared static variables may be left at
    * invalid states, with unpredictable results.
    *
    * \warning <b>Calling this member function is strongly discouraged - Use it
    * at your own risk</b>
    */
   void Kill(); // ### Dangerous - Use at your own risk! ###

   /*!
    * Returns true iff this thread is running.
    */
   bool IsActive() const;

   /*!
    * Returns this thread's priority.
    */
   priority Priority() const;

   /*!
    * Sets this thread's priority.
    */
   void SetPriority( priority );

   /*!
    * Resets this thread's priority to the default value, which inherits the
    * calling thread's priority.
    */
   void ResetPriority()
   {
      SetPriority( ThreadPriority::Inherit );
   }

   /*!
    * Suspends execution of the calling thread until this thread terminates
    * execution. If this thread is not running, this function returns
    * immediately.
    *
    * \warning If this thread does not return from its Run() member function,
    * for example because this thread hangs or enters an infinite loop, the
    * thread that calls this function will remain suspended forever (crashed).
    */
   void Wait();

   /*!
    * Suspends execution of the calling thread until one of the following
    * conditions is met:
    *
    * \li This thread terminates execution, or this thread is not running.
    * \li The specified time interval \a ms in milliseconds has elapsed.
    *
    * This member function returns true if this thread has finished execution
    * before the specified time \a ms in milliseconds has elapsed. It also
    * returns true if this thread is not running.
    *
    * \note Unlike Wait(), this function cannot crash the calling thread if
    * this thread is crashed, unless a huge amount of time is specified as the
    * function argument.
    */
   bool Wait( unsigned ms );

   /*!
    * Suspends execution of this thread during the specified time interval
    * \a ms in milliseconds.
    */
   void Sleep( unsigned ms );

   /*
    * Returns a reference to the current thread (the thread from which this
    * member function is invoked), or Thread::Null() if the current thread is
    * either (a) a thread not being controlled by the PixInsight API, or (b) a
    * thread that has been created by another module.
   static Thread& CurrentThread();
    */

   /*!
    * This member function returns true if and only if it is called from the
    * <em>root thread</em>. The root thread is the thread where the graphical
    * user interface is running on the PixInsight core application.
    *
    * \note Since version 1.8.0 of the PixInsight core application, nested
    * parallelism is fully supported. This means that multiple threads can be
    * run by calling Thread::Start() from either the root thread or any running
    * %Thread object. In versions prior to 1.8.0, a thread could only be run
    * from the root thread.
    */
   static bool IsRootThread();

   /*!
    * Returns the total number of running %Thread objects.
    *
    * \note This function knows nothing about threads out of PCL control, so it
    * will return zero if no %Thread instance is currently active, even if
    * there are other native threads being executed.
    */
   static int NumberOfRunningThreads();

   /*!
    * %Thread execution routine.
    *
    * This member function is invoked by the PixInsight core application upon
    * execution start, just after calling the Start() member function. During
    * execution of this routine, it is said that this is a <em>running
    * thread</em>.
    *
    * Derived classes must reimplement this member function to provide specific
    * thread functionality.
    *
    * \note There is no problem at all in calling this member function
    * directly. This may be useful, for example, if the same code must be
    * executed in a single thread (without calling Start()) and as
    * multithreaded code.
    */
   virtual void Run()
   {
      // Reimplement this function to provide your thread's functionality.
   }

   /*!
    * Returns the current status of this thread. The thread status is a 32-bit
    * unsigned integer number that can be set for an active thread by calling
    * its SetStatus() member function.
    *
    * %Thread status is primarily intended as an efficient mechanism to send
    * custom messages to running threads, for thread synchronization or other
    * control purposes.
    *
    * \note This member function is thread-safe. It can be safely called for a
    * running thread.
    *
    * \note This member function blocks the caller's execution until the thread
    * status can be retrieved. Hence, the operation performed by this function
    * is expensive in terms of thread synchronization. For a non-blocking
    * version of this function see the documentation for TryGetStatus().
    */
   uint32 Status() const;

   /*!
    * Attempts to get the current status of this thread without blocking the
    * caller's execution.
    *
    * Returns true iff the thread status could be retrieved and stored in the
    * specified \a status variable.
    *
    * Returns false if the status couldn't be read. In this case the value of
    * the \a status variable won't be changed.
    *
    * \note This member function is thread-safe. It can be safely called for a
    * running thread.
    *
    * \note This is a non-blocking fast version of the Status() member
    * function. It should be used when acquiring the thread's status is not
    * strictly necessary to continue thread execution.
    */
   bool TryGetStatus( uint32& status ) const;

   /*!
    * Sets the current status of a running thread. See the documentation of
    * Thread::Status() for more information.
    *
    * \note Calling this function for an inactive thread has no effect. The
    * thread status can only be set for a running thread.
    *
    * \note If the high-order bit of \a status is set, an abort message will be
    * sent to the running thread. See the Abort() member function for more
    * information.
    *
    * \note This member function is thread-safe. It can be safely called for a
    * running thread, even from other running threads.
    */
   void SetStatus( uint32 status );

   /*!
    * Sends an abort message to a running thread.
    *
    * If the thread calls Module->ProcessEvents() after an abort message has
    * been sent, or if it uses some of the standard status monitoring classes
    * (such as StandardStatus for example), a ProcessAborted exception will be
    * thrown automatically in the thread. The exception will be thrown in the
    * (reimplemented) Thread::Run() member function, where it should be caught
    * and used to terminate thread execution by returning from Run(). This
    * mechanism can be used to synchronize and stop running threads in a
    * controlled and thread-safe way.
    *
    * \note A thread abort message means that the high-order bit of a running
    * thread's status has been set. This member function simply sets the thread
    * status to 0x80000000. To effectively abort the thread, it should call
    * Module->ProcessEvents(), as described above, and should stop its
    * execution after catching a ProcessAborted exception.
    *
    * \note This member function is thread-safe. It can be safely called for a
    * running thread, even from other running threads.
    */
   void Abort()
   {
      SetStatus( 0x80000000 );
   }

   /*!
    * Returns true iff this thread has been aborted. A thread has been aborted
    * if it has received an abort message by a previous call to Abort(), or by
    * setting the high-order bit of its thread status word.
    *
    * \note This member function is thread-safe. It can be safely called for a
    * running thread.
    *
    * \note This function calls Status() to read the current thread's status.
    * Consequently, it blocks the caller's execution and has the same
    * performance problems. For a non-blocking alternative, see TryIsAborted().
    */
   bool IsAborted() const
   {
      return (Status() & 0x80000000) != 0;
   }

   /*!
    * Returns true iff this thread has been aborted, and the current thread's
    * status could be retrieved without blocking the caller's execution.
    *
    * \note This member function is thread-safe. It can be safely called for a
    * running thread.
    *
    * \note This is a non-blocking fast version of the IsAborted() member
    * function. It should be used when acquiring the thread's status is not
    * strictly necessary to continue thread execution.
    */
   bool TryIsAborted() const
   {
      uint32 status;
      return TryGetStatus( status ) && (status & 0x80000000) != 0;
   }

   /*!
    * Returns the console output text currently accumulated in this thread.
    *
    * When a %Thread object is running (that is, when its IsActive() member
    * function returns true), no operation on the graphical user interface is
    * permitted from the thread. This includes console text output.
    *
    * When a running thread writes text to the console, for example by calling
    * Console::Write() or Console::WriteLn(), the text is not sent to the
    * console (which in fact would raise an Error exception), but it is instead
    * appended to the thread's <em>console output text</em>. The accumulated
    * output text can be sent to the console once the thread has finished
    * execution, or it can be retrieved by calling this member function.
    */
   String ConsoleOutputText() const;

   /*!
    * Returns true iff this thread has any accumulated console output text that
    * still has not been flushed or cleared.
    *
    * For information on thread console output, refer to the documentation for
    * the ConsoleOutputText() member function.
    */
   bool HasConsoleOutputText() const
   {
      return !ConsoleOutputText().IsEmpty();
   }

   /*!
    * Erases the accumulated console output text in this thread.
    *
    * For information on thread console output, refer to the documentation for
    * the ConsoleOutputText() member function.
    */
   void ClearConsoleOutputText();

   /*!
    * Sends any accumulated console output text in this thread to the console.
    *
    * After writing the accumulated text to the console, this member function
    * clears it, so that repeated calls to this function will have no effect.
    *
    * For information on thread console output, refer to the documentation for
    * the ConsoleOutputText() member function.
    *
    * \note This member function must only be called from the root thread.
    * Calling it from a running %Thread object has no effect.
    */
   void FlushConsoleOutputText();

   /*!
    * Returns the maximum number of threads that can be used concurrently to
    * process a set of items.
    *
    * \param count   Number of <em>processing units</em>. A processing unit can
    *             be a single pixel, a row of pixels, or any suitable item,
    *             according to the task being performed by the caller.
    *
    * \param overheadLimit    %Thread overhead limit in processing units. The
    *             function returns a maximum number of threads such that no
    *             thread would have to process less processing units than this
    *             value. The default overhead limit is one processing unit.
    *
    * This function takes into account the number of existing processors in
    * the system, as well as the maximum number of processors currently allowed
    * for external processes by the core application, and the number of threads
    * currently active. The following global variables are taken into account
    * (see the PixInsightSettings class for more information about global
    * variables on the PixInsight platform):
    *
    * <table border="1" cellpadding="4" cellspacing="0">
    * <tr><td>Process/EnableParallelProcessing</td>
    *     <td>If this global flag is false, it means that parallel processing
    *     has been globally disabled for the entire platform, so this function
    *     will always return one, irrespective of the number of existing
    *     processors.</td></tr>
    *
    * <tr><td>Process/EnableParallelModuleProcessing</td>
    *     <td>If this global flag is false, it means that parallel processing
    *     has been disabled for all installed modules, so this function will
    *     always return one, as in the previous case.</td></tr>
    *
    * <tr><td>Process/MaxProcessors</td>
    *     <td>This global integer variable is the maximum number of processors
    *     allowed for installed modules, which is always less than or equal to
    *     the number of existing processors in the system. This function will
    *     never return a number of threads greater than the value of this
    *     variable.</td></tr>
    * </table>
    *
    * The <em>number of processors</em> term refers to the number of existing
    * <em>logical processors</em> in the system. These include all physical
    * processors in multiprocessor systems, as well as all existing processor
    * cores in multicore processors, and virtual processors in systems with
    * HyperThreading or equivalent technology.
    *
    * Since version 1.8.0 of the PixInsight core application, nested
    * parallelism is fully supported. This means that multiple threads can be
    * executed concurrently from a running thread. This function will take into
    * account the number of already running threads, as provided by the
    * Thread::NumberOfRunningThreads() static member function, to help prevent
    * exceeding the maximum number of threads allowed by the platform (see the
    * global variables in the table above). In any event, the calling module is
    * entirely responsible to comply with these restrictions.
    *
    * \note A module must never try to run more threads concurrently than the
    * amount returned by this function. Failure to follow this rule will
    * invalidate a module for certification.
    */
   static int NumberOfThreads( size_type count, size_type overheadLimit = 1u );

   /*!
    * Returns a list of per-thread counts optimized for parallel processing of
    * a set of items.
    *
    * \param count   Number of <em>processing units</em>. A processing unit can
    *             be a single pixel, a row of pixels, or any suitable item,
    *             according to the task being performed by the caller.
    *
    * \param overheadLimit    %Thread overhead limit in processing units. The
    *             function returns a list with a maximum length such that no
    *             thread would have to process less processing units than this
    *             value. The default overhead limit is one processing unit.
    *
    * \param maxThreads    Maximum number of threads to use. The length of the
    *             returned list will be at most either this value, or the
    *             maximum number of threads currently allowed for the calling
    *             process, whichever is less. The default value of this
    *             parameter does not impose a practical limit.
    *
    * This function takes into account the number of existing logical
    * processors in the system, as well as the maximum number of processors
    * currently allowed for external processes by the PixInsight core
    * application, and the number of threads currently active. See the
    * NumberOfThreads() static member function for more information on thread
    * execution and the global settings governing their use in PixInsight.
    *
    * This function returns a dynamic array of unsigned integers, where each
    * element is the number of items that the corresponding thread should
    * process in order to make an optimal usage of the processor resources
    * currently available. The length of the returned array is the maximum
    * number of threads that the calling process should execute concurrently to
    * process the specified number of items, with the specified overhead limit
    * and maximum number of processors.
    *
    * In the current implementation of this function, the returned array tends
    * to spread the total work load uniformly across the threads available.
    * Future implementations may consider additional factors, including the
    * possibility of using new global settings specific for thread execution
    * optimization. For this reason, under normal conditions a module should
    * always use the result of calling this function to define a thread
    * execution schedule. See also OptimalThreadLoadsAligned() for a variant of
    * this function with prescribed item alignment.
    *
    * \note A module must never try to run more threads concurrently than the
    * length of the array returned by this function. Failure to follow this
    * rule will invalidate a module for certification.
    *
    * \sa OptimalThreadLoadsAligned()
    */
   static Array<size_type> OptimalThreadLoads( size_type count,
                                               size_type overheadLimit = 1u,
                                               int maxThreads = PCL_MAX_PROCESSORS );

   /*!
    * Returns a list of per-thread counts optimized for parallel processing of
    * a contiguous set of items stored with a prescribed alignment.
    *
    * \param count   Number of <em>processing units</em>. A processing unit can
    *             be a single pixel, a row of pixels, or any suitable item,
    *             according to the task being performed by the caller. For
    *             optimal performance, the size in bytes of a processing unit
    *             should be even, assuming that the task will be applied to a
    *             contiguous list of \a count items.
    *
    * \param align   Item alignment. The function will return a list of counts,
    *             where all counts but the last one are guaranteed to be
    *             integer multiples of this parameter. The default value is 16.
    *
    * \param overheadLimit    %Thread overhead limit in processing units. The
    *             function returns a list with a maximum length such that no
    *             thread would have to process less processing units than this
    *             value. The default overhead limit is one processing unit.
    *
    * \param maxThreads    Maximum number of threads to use. The length of the
    *             returned list will be at most either this value, or the
    *             maximum number of threads currently allowed for the calling
    *             process (whichever is less), or maybe a smaller length, if
    *             necessary to enforce the specified alignment. The default
    *             value of this parameter does not impose a practical limit.
    *
    * Other than the prescribed alignment, this function is equivalent to its
    * unaligned counterpart OptimalThreadLoads().
    *
    * \sa OptimalThreadLoads()
    */
   static Array<size_type> OptimalThreadLoadsAligned( size_type count,
                                                      int align = 16,
                                                      size_type overheadLimit = 1u,
                                                      int maxThreads = PCL_MAX_PROCESSORS );
private:

   int m_processorIndex = -1;

   Thread( void* h ) : UIObject( h )
   {
   }

   void* CloneHandle() const override;

protected:

   virtual bool IsStealth() const
   {
      return false;
   }

   friend class ThreadDispatcher;
};

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

/*!
 * Suspends the calling thread from execution until the specified time \a ms in
 * milliseconds has elapsed, or until a signal is delivered to the calling
 * thread that terminates the process or causes activation of a signal-catching
 * routine.
 * \ingroup thread_support
 */
void PCL_FUNC Sleep( unsigned ms );

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

} // pcl

#endif   // __PCL_Thread_h

// ----------------------------------------------------------------------------
// EOF pcl/Thread.h - Released 2022-03-12T18:59:29Z
