PCL
Helper Macros for Synchronized Status Monitoring of Image Processing Threads

Macros

#define INIT_THREAD_MONITOR()    size_type ___n___ = 0, ___n1___ = 0;
 Declares and initializes local variables used for synchronization of thread status monitoring. More...
 
#define UPDATE_THREAD_MONITOR(N)
 Synchronized status monitoring of a set of image processing threads. More...
 
#define UPDATE_THREAD_MONITOR_CHUNK(N, chunkSize)
 Synchronized status monitoring of a set of image processing threads. More...
 

Detailed Description

Macro Definition Documentation

◆ INIT_THREAD_MONITOR

#define INIT_THREAD_MONITOR ( )     size_type ___n___ = 0, ___n1___ = 0;

This macro is intended to be used at the beginning of a reimplemented Thread::Run() member function. It declares and initializes some counters required to update a status monitoring count with thread synchronization in the UPDATE_THREAD_MONITOR macro.

For an example of code using these macros, see UPDATE_THREAD_MONITOR().

Definition at line 1226 of file AbstractImage.h.

◆ UPDATE_THREAD_MONITOR

#define UPDATE_THREAD_MONITOR (   N)
Value:
if ( ++___n1___ == (N) ) \
{ \
if ( this->m_data.numThreads > 1 ) \
{ \
if ( this->TryIsAborted() ) \
return; \
___n___ += (N); \
if ( this->m_data.total > 0 ) \
if ( this->m_data.mutex.TryLock() ) \
{ \
this->m_data.count += ___n___; \
this->m_data.mutex.Unlock(); \
___n___ = 0; \
} \
} \
else \
{ \
if ( this->m_data.total > 0 ) \
this->m_data.status += (N); \
else \
++this->m_data.status; \
} \
___n1___ = 0; \
}
Parameters
NNumber of accumulated monitoring counts before performing a a synchronized update of the ThreadData monitoring count. A larger value will reduce the frequency of monitor updates. A value of 64K (65536), equivalent to the number of pixels in a square of 256x256 pixels, is quite appropriate for threads that process individual pixels.

This macro increments a status monitoring count in a ThreadData member of an image processing thread, with thread synchronization. It must be used within a reimplemented Thread::Run() member function.

The thread class where this macro is used must have a data member declared as follows:

AbstractImage::ThreadData& m_data;

where AbstractImage::ThreadData can be replaced with a suitable derived class, e.g. when the thread requires additional data items.

The m_data member is a reference to a structure providing the necessary objects to perform the synchronized status monitoring task for a set of concurrent threads. For more information on synchronized thread monitoring, see the AbstractImage::RunThreads() member function.

To use this macro, the INIT_THREAD_MONITOR macro must also be used at the begining of the reimplemented Thread::Run() function.

Here is a brief example pseudocode:

class FooThreadData : public AbstractImage::ThreadData
{
... constructor and additional data members here
};
class FooThread : public Thread
{
public:
... constructor and other member functions here
void Run() override
{
for ( int i = m_startRow, i < m_endRow; ++i )
{
for ( int j = 0; j < width; ++j )
{
... process a single pixel here
// Update monitor every 64K processed pixels.
}
}
}
private:
FooThreadData& m_data;
int m_startRow;
int m_endRow;
... other data members here
};
... the code that initializes and runs the threads:
FooThreadData data;
... initialize thread data here
ReferenceArray<FooThread> threads;
... create and construct the threads here
AbstractImage::RunThreads( threads, data );
threads.Destroy();
#define INIT_THREAD_MONITOR()
Declares and initializes local variables used for synchronization of thread status monitoring.
#define UPDATE_THREAD_MONITOR(N)
Synchronized status monitoring of a set of image processing threads.

For a similar macro that allows incrementing the status monitor by steps larger than one unit, see UPDATE_THREAD_MONITOR_CHUNK().

Definition at line 1314 of file AbstractImage.h.

◆ UPDATE_THREAD_MONITOR_CHUNK

#define UPDATE_THREAD_MONITOR_CHUNK (   N,
  chunkSize 
)
Value:
if ( (___n1___ += (chunkSize)) == (N) ) \
{ \
if ( this->m_data.numThreads > 1 ) \
{ \
if ( this->TryIsAborted() ) \
return; \
___n___ += (N); \
if ( this->m_data.total > 0 ) \
if ( this->m_data.mutex.TryLock() ) \
{ \
this->m_data.count += ___n___; \
this->m_data.mutex.Unlock(); \
___n___ = 0; \
} \
} \
else \
{ \
if ( this->m_data.total > 0 ) \
this->m_data.status += (N); \
else \
++this->m_data.status; \
} \
___n1___ = 0; \
}

This macro is identical to UPDATE_THREAD_MONITOR(), but it updates the status monitoring count by successive steps of the specified chunkSize.

Typically, this macro is used in situations where the status monitor cannot be incremented by single units, due to the complexity of the monitored code or to excessive overhead of monitoring count. The difference between this macro and UPDATE_THREAD_MONITOR() can be easily understood with the following two examples. In these examples, we show a reimplemented Thread::Run() member function in an image processing thread:

Example of code using UPDATE_THREAD_MONITOR_CHUNK():

void Run() override
{
for ( int i = m_startRow, i < m_endRow; ++i )
{
for ( int j = 0; j < width; ++j )
{
... process a row of pixels here.
}
// Update every 64K processed pixels, once for each processed row.
}
}
#define UPDATE_THREAD_MONITOR_CHUNK(N, chunkSize)
Synchronized status monitoring of a set of image processing threads.

Example of code using UPDATE_THREAD_MONITOR():

void Run() override
{
for ( int i = m_startRow, i < m_endRow; ++i )
{
for ( int j = 0; j < width; ++j )
{
... process a single pixel here.
// Update monitor every 64K processed pixels.
}
}
}

Definition at line 1395 of file AbstractImage.h.