[fpc-devel] Feature announcement: Extension of TThread's interface

Sven Barth pascaldragon at googlemail.com
Thu Dec 27 17:23:17 CET 2012

Hello Free Pascal community!

I'm pleased to announce the extension of TThread's interface to bring it 
more on par with current Delphi versions.


Note: in the following list "class" means that the property or method is 
a class property or method and thus can be called without a specific 
TThread instance.

New properties:

- Finished:
     Returns whether the thread has finished it's execution whereas it 
does not depend on whether the thread finished itself or an exception 
- CurrentThread (class):
     Returns a TThread instance of the current thread even if the thread 
wasn't originally started through a TThread instance. This is useful if 
you have some thread aware procedure and function which then needs 
access to the TThread instance to do a Synchronize or Queue call. For 
external threads a TThread instance is created on the fly and freed at 
the end of the application (see also Future Developments).
- ExternalThread:
     Returns whether the thread was not started through a TThread 
instance (or one of its descendants), but was started from an external 
source. Examples when this is true is for threads created by 
BeginThread, for the main thread and threads created by libraries. See 
also CurrentThread.
- ProcessorCount (class):
     Returns the count of CPU cores detected by the RTL. This is based 
on the new global property System.GetCPUCount which needs to be 
implemented per target. Currently only a default implementation exists 
which returns "1".
- IsSingleProcessor (class):
    Returns whether the application is running on a single processor system.

New methods:

- GetTickCount (class, deprecated):
     Returns the value of SysUtils.GetTickCount.
- GetTickCount64 (class):
     Returns the value of SysUtils.GetTickCount64.
- Yield (class):
     Calls System.ThreadSwitch to give another thread (maybe even from 
another process) the change to do its work.
- CheckTerminated (class):
     Returns the value of TThread.Terminated of the current thread if 
the thread was created using TThread or raises an 
EThreadExternalException otherwise.
- SetReturnValue (class):
     Allows to set the value returned by TThread.WaitFor for the current 
thread if the thread was created using TThread or raises an 
EThreadExternalException otherwise.
- SpinWait (class):
     Does a busy wait for the given amount of iterations (useful to burn 
just a few CPU cycles).
- CreateAnonymousThread (class):
     Creates a new TThread instance based on a global procedure. The 
thread is started suspended and with FreeOnTerminate set. Use Start on 
the returned TThread instance to start the thread's execution.
- GetSystemTimes (class):
     This fills a TThread.TSystemTimes record with the time the process 
has spend in different states. This method is platform specific and by 
default just zeros the record.
- NameThreadForDebugging (class):
     This gives the thread with the given thread ID (or the current 
thread if the ID is -1) the given name. This way the thread can be 
easily identified when debugging. This method is platform specific and 
by default it does nothing.
- Queue (class):
     The given method pointer is added to a queue that is processed by 
CheckSynchronize and therefore executed inside the main thread. Unlike 
Synchronize this is not a blocking call. If the thread instance is Nil 
the thread is determined using TThread.CurrentThread. See also 
- Queue (protected):
     The same as the class method Queue, but with the difference that 
always the current TThread instance (Self) is used.
- RemoveQueuedEvents (class):
     If a TThread instance is given all queued methods (excluding 
Synchronize ones) of that thread are removed from the queue processed by 
CheckSynchronize. If no thread is given, but a method pointer all queued 
entries (excluding Synchronize ones) with that method are removed no 
matter which thread added them. If both the thread and the method is 
given the thread takes precedence.


This function now processes a complete queue of thread events (queued by 
either TThread.Synchronize or TThread.Queue) unlike before where only a 
single event was handled. Like before if an Exception happens inside a 
method added by Synchronize the exception is passed back to the calling 
method. For methods added by Queue the exception is raised (after the 
queued entry was removed from the queue).

For platform developers:

Unlike implementing directly TThread's constructor and destructor new 
methods SysCreate and SysDestroy were added which must be implemented 
for platform specific initialization/finialization of a thread.

All platform maintainers should check whether their platforms still 
compile and - if it supports multi threading - still runs correctly. At 
least Unix and Windows platforms do compile and Unix platforms do run.

Future developments:

Currently a usage of TThread.CurrentThread inside an external thread 
will create a TThread instance that exists till the end of the program. 
Using notification mechanism provided by the threading implementation 
(TLS entry on Windows and thread destroy callbacks for pthreads) one can 
make the extension that such instances are freed once the corresponding 
external thread terminates. For other platforms the collector provided 
in the following bug report could be used: 
http://bugs.freepascal.org/view.php?id=17300 (comment 47406)

The methods NameThreadForDebugging and GetSystemTimes need to be 
implemented for those platforms that support it.

Once anonymous procedures are supported the argument for 
CreateAnonymousThread will be adjusted and corresponding overloads for 
Synchronize and Queue will be added.

Maybe in the future a look at extending the language with keywords that 
were introduced for Oxygene can be done (see 
http://wiki.freepascal.org/OpenMP_support#Proposal_3 )


More information about the fpc-devel mailing list