Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-12

Feature announcement: Extension of TThread's interface

4 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Sven Barth

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.

Extensions:

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 happened.
- 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 CheckSynchronize.
- 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.

CheckSynchronize:

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 )

Regards,
Sven

Reply by email

Graeme Geldenhuys
to Sven Barth
Sven Barth wrote
I'm pleased to announce the extension of TThread's interface to bring it more on par...

Very nicely done Sven. There is some really handy functionality now.

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

Is this platform API functionality eg: Win32 or Linux kernel (from your comment, I assume so), or is it debugger functionality (eg: DWARF info) that needs to be extended.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Marco van de Voort
to Graeme Geldenhuys

In our previous episode, Graeme Geldenhuys said:

Show quoted text 6 lines
> The methods NameThreadForDebugging need to be > implemented for those platforms that support it. Is this platform API functionality eg: Win32 or Linux kernel (from your comment, I assume so), or is it debugger functionality (eg: DWARF info) that needs to be extended.

Afaik on Windows it is a possibility for a program to name its threads via a winapi call, for which debuggers can register themselves.

Hard to imitate without a OS supported debugger api.

Reply by email

Sven Barth
to Graeme Geldenhuys: Very nicely done Sven. There is some really handy functionality now. Is this platform API…
Graeme Geldenhuys wrote 6 lines
On 27/12/12 16:23, Sven Barth wrote: > > I'm pleased to announce the extension of TThread's interface to bring it > more on par... Very nicely done Sven. There is some really handy functionality now.

It was mostly done for Delphi compatibility :P (with the exception of GetTickCount64)

Show quoted text 8 lines
> The methods NameThreadForDebugging need to be > implemented for those platforms that support it. Is this platform API functionality eg: Win32 or Linux kernel (from your comment, I assume so), or is it debugger functionality (eg: DWARF info) that needs to be extended.

It's a platform API.

On Windows you raise a SEH Exception using a special exception code and content and on PThreads based systems you call a specific pthreads function (with an additional call on Mac OS X systems).

Then the debugger is (at least in theory) able to use that name.

Regards,
Sven

Reply by email