Sign in Join

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

Mailing lists / fpc-pascal / 2013-02

GetCurrentThreadID under FreeBSD vs Linux

7 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Graeme Geldenhuys

Hi,

Under Linux and Windows I have the following code which works fine.

var
  LThreadID: string;
begin
  FmtStr(LThreadID, '%.4d', [GetCurrentThreadID]);

Under FreeBSD (64-bit) that failed with a EConvertError in the unit tests and the compiler gave a message of 'Invalid argument index in format "%.4d"'

Navigating the code to see how TThreadID is defined, I found this for FreeBSD.

  TThreadRec = record end;
  TThreadID  = ^TThreadRec;

So TThreadID is just a pointer to a record structure. Apparently getting a "real" thread ID/number is not as easy as under Linux. [Info from Google searches]. Under FreeBSD it seems that naming each thread with a string value is a more supported solution.

I'm not so fussed about the exact ID per thread, so the pointer value will be fine. Windows uses a THandle and Linux uses a PtrUInt as the types for TThreadID.

So would it be safe if I did the following in my code? For the Windows,
Linux and FreeBSD (LThreadID, '%.4d', [PtrUInt(GetCurrentThreadID)]);

I've tested the PtrUInt() cast under FreeBSD, Linux and Windows, and it seems to work fine.

BTW:
This code is only used to supply a thread id/value to a logging function (file, GUI, console etc) to help with debugging, or at least show which thread wrote what debug log entries. So it's not critical code.

Regards,
- Graeme -

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

Hello,

I had the exact same issue when writing debug info in my code. Easy to solve I think. Just define a macro at the top of the unit like this:

    {$macro on}
    {$define Debug_ThreadSelf:= ptruint(GetCurrentThreadID)}

And then change all FmtStr lines to something like

    FmtStr(LThreadID, '%.4d', [Debug_ThreadSelf]);

And if you don't like macro's, just change all FmtStr lines into

    FmtStr(LThreadID, '%.4d', [ptruint(GetCurrentThreadID)]);

It can be that `ptruint` is defined in `unixtype`, but I don't know for sure.

Once upon a time, on 02/08/2013 03:40 PM to be precise, Graeme Geldenhuys said:

Show quoted text 49 lines
Hi, Under Linux and Windows I have the following code which works fine. var LThreadID: string; begin FmtStr(LThreadID, '%.4d', [GetCurrentThreadID]); Under FreeBSD (64-bit) that failed with a EConvertError in the unit tests and the compiler gave a message of 'Invalid argument index in format "%.4d"' Navigating the code to see how TThreadID is defined, I found this for FreeBSD. TThreadRec = record end; TThreadID = ^TThreadRec; So TThreadID is just a pointer to a record structure. Apparently getting a "real" thread ID/number is not as easy as under Linux. [Info from Google searches]. Under FreeBSD it seems that naming each thread with a string value is a more supported solution. I'm not so fussed about the exact ID per thread, so the pointer value will be fine. Windows uses a THandle and Linux uses a PtrUInt as the types for TThreadID. So would it be safe if I did the following in my code? For the Windows, Linux and FreeBSD platforms at least. FmtStr(LThreadID, '%.4d', [PtrUInt(GetCurrentThreadID)]); I've tested the PtrUInt() cast under FreeBSD, Linux and Windows, and it seems to work fine. BTW: This code is only used to supply a thread id/value to a logging function (file, GUI, console etc) to help with debugging, or at least show which thread wrote what debug log entries. So it's not critical code. Regards, - Graeme -
Ewald
Sven Barth
to Ewald
"Ewald" wrote
It can be that `ptruint` is defined in `unixtype`, but I don't know for sure.

"PtrUInt" (and "PtrInt") are declared in unit "System".

Regards,
Sven

Marco van de Voort
to Graeme Geldenhuys: Under Linux and Windows I have the following code which works fine. var LThreadID: string;

In our previous episode, Graeme Geldenhuys said:

Show quoted text 6 lines
Under Linux and Windows I have the following code which works fine. var LThreadID: string; begin FmtStr(LThreadID, '%.4d', [GetCurrentThreadID]);

Threadids are probably opague under Posix. So while it works, it is not correct on Linux. You add implementation specific details (that it is an integer type) that might change at any time.

Under FreeBSD (64-bit) that failed with a EConvertError in the unit tests and the compiler gave a message of 'Invalid argument index in format "%.4d"'

That's correct.

Show quoted text 7 lines
Navigating the code to see how TThreadID is defined, I found this for FreeBSD. TThreadRec = record end; TThreadID = ^TThreadRec; So TThreadID is just a pointer to a record structure

This is a common construct to define opague types.

Apparently gettinga a "real" thread ID/number is not as easy as under Linux.

There is no thread id. See in GDB, you will probably see a pointer value, not a nice increasing sequential number like e.g. PID.

[Info from Google searches]. Under FreeBSD it seems that naming each thread with a string value is a more supported solution.

Note that under Windows threads can be named on API level too. VS and Delphi (2010+ iirc) will show such threads in the debugger with a familiar name.

So would it be safe if I did the following in my code? For the Windows, Linux and FreeBSD platforms at least. FmtStr(LThreadID, '%.4d', [PtrUInt(GetCurrentThreadID)]);

I think while it is safe. Might throw warnings on some systems though (signed vs unsigned conversions, if threadid is signed; or so)

Show quoted text 7 lines
I've tested the PtrUInt() cast under FreeBSD, Linux and Windows, and it seems to work fine. BTW: This code is only used to supply a thread id/value to a logging function (file, GUI, console etc) to help with debugging, or at least show which thread wrote what debug log entries. So it's not critical code.

I would simply name the threads using a string, and forget the whole threadid business. If only that the 64-bit pointer values can get unwieldy large and hard to read.

Graeme Geldenhuys
to Marco van de Voort
Marco van de Voort wrote 9 lines
> Navigating the code to see how TThreadID is defined, I found this for > FreeBSD. > > TThreadRec = record end; > TThreadID = ^TThreadRec; > > So TThreadID is just a pointer to a record structure This is a common construct to define opague types.

Sorry if my message wasn't clear. I fully understand that, and wasn't implying that FPC (FreeBSD) was wrong here. After my previous FreeBSD messages and feedback, I knew where to look for the info, and the man pages clearly said it is an opaque type.

Show quoted text 5 lines
> [Info from Google searches]. Under FreeBSD it seems that naming each > thread with a string value is a more supported solution. Note that under Windows threads can be named on API level too. VS and Delphi (2010+ iirc) will show such threads in the debugger with a familiar name.

As far as I know (I could be wrong though) Linux can't name threads. And again, the code I'm working on in tiOPF is cross platform and cross compiler.

As I said, the Thread ID info is only used for debugging and not something critical. There must just be some value differentiating between various threads, when they output to the logger.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/
Graeme Geldenhuys
to Ewald: I had the exact same issue when writing debug info in my code. Easy to solve I think.…
Ewald wrote
{$macro on} {$define Debug_ThreadSelf:= ptruint(GetCurrentThreadID)}

I must confess I haven't used macros in FPC. Also the code I'm working with is cross platform and cross compiler. I don't know if Delphi supports such macros. Quick search in Delphi 7 help (lowest Delphi we support) doesn't list $macro anywhere.

FmtStr(LThreadID, '%.4d', [ptruint(GetCurrentThreadID)]); It can be that `ptruint` is defined in `unixtype`, but I don't know for sure.

OK, then what I did would suffice for now. Thanks for the feedback.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/
Sven Barth
to Graeme Geldenhuys
Graeme Geldenhuys wrote 8 lines
On 2013-02-08 17:08, Ewald wrote: > {$macro on} > {$define Debug_ThreadSelf:= ptruint(GetCurrentThreadID)} I must confess I haven't used macros in FPC. Also the code I'm working with is cross platform and cross compiler. I don't know if Delphi supports such macros. Quick search in Delphi 7 help (lowest Delphi we support) doesn't list $macro anywhere.

Delphi doesn't support Macros.

Regards,
Sven