754 lines
32 KiB
C++
754 lines
32 KiB
C++
// ____ ______ __
|
|
// / __ \ / ____// /
|
|
// / /_/ // / / /
|
|
// / ____// /___ / /___ 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
|