Cross-platform function to get the current thread ID
Cross-platform function to get the current thread ID
A similar function like the Win32 GetCurrentThread() would be ideal for syncronizing data structures which use the Thread ID returned by CreateThread and functions called from within the thread itself. I find this particular API function is indispensable when working with threads and would love to see PureBasic support something similar for cross-platform compatibility as well.
Re: Cross-platform function to get the current thread ID
I too need this! It would be great if we could use, for example, PB's ThreadId() with a -1 parameter or something
but at the moment it seems ThreadId() can only be used with threads we create with CreateThread() ?
does anyone know if there's a way? my Linux and Mac books wont arrive for at least another week!
but at the moment it seems ThreadId() can only be used with threads we create with CreateThread() ?
does anyone know if there's a way? my Linux and Mac books wont arrive for at least another week!
Re: Cross-platform function to get the current thread ID
On OSX you can useand it will report different values for different threads but as far as I can tell it doesn't match the value the PureBasic ThreadID procedure returns 
Edit:
After a bit more trying, on OSX PureBasic seems to use the value corresponding to pthread_self_() for ThreadID.[/i]
Code: Select all
Debug CocoaMessage(0, 0, "NSThread currentThread")

Edit:
After a bit more trying, on OSX PureBasic seems to use the value corresponding to pthread_self_() for ThreadID.
Code: Select all
Debug pthread_self_()
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
BUG in ThreadId() for Windows? (works fine in Linux and OSX)
thankyou very much again wilbert!!! Without your help the shackles would still be on. Hopefully my Mac and Linux books arrive soon lol
It turns out Linux also uses pthread_self() ... im slowly "getting" Mac and Linux heehee

And its working well ... again a possible candidate for "ThreadId(-1)" or some new #PB_ThreadId_Current constant or something
But it seems there's a bug or unexplained result for PB's ThreadId() in WINDOWS (tested in XP-32 and 10-64) ...
[EDIT] Its not a bug, its just returning the thread HANDLE not the ID. wilbert found out we can use GetThreadId_(ThreadId(hPBThread)) in later versions of Windows, or we can just call GetCurrentThreadId_() from within the thread[/EDIT]
Also I check in Ollydbg but PB's ThreadId() in Windows never calls GetCurrentThread_/GetCurrentThreadId_ ... its very small code that only calls RtlEnterCriticalSection, WaitForSingleObject, and RtlLeaveCriticalSection but im not sure what its doing.

(Ignore the Handle= value in OSX+Linux, i just wanted to see if GetCurrentThread_() was what ThreadId() is returning in Windows - it isn't)
This test simply creates a worker thread and retrieves the current thread ID from inside the worker thread so it can be reported and compared to the output of ThreadId(hWorkerThread)
Ill wait for feedback or possibly Fred might notice this post, before possibly making a Bug report thread
ps. am I weird for thinking that it's strange that Mac's Cocoa uses strings instead of numeric constants like WinAPI? and from a readability perspective i find #NSThread_currentThread just as easy to read as "NSThread currentThread" lol
It turns out Linux also uses pthread_self() ... im slowly "getting" Mac and Linux heehee


And its working well ... again a possible candidate for "ThreadId(-1)" or some new #PB_ThreadId_Current constant or something

But it seems there's a bug or unexplained result for PB's ThreadId() in WINDOWS (tested in XP-32 and 10-64) ...
[EDIT] Its not a bug, its just returning the thread HANDLE not the ID. wilbert found out we can use GetThreadId_(ThreadId(hPBThread)) in later versions of Windows, or we can just call GetCurrentThreadId_() from within the thread[/EDIT]
Also I check in Ollydbg but PB's ThreadId() in Windows never calls GetCurrentThread_/GetCurrentThreadId_ ... its very small code that only calls RtlEnterCriticalSection, WaitForSingleObject, and RtlLeaveCriticalSection but im not sure what its doing.

(Ignore the Handle= value in OSX+Linux, i just wanted to see if GetCurrentThread_() was what ThreadId() is returning in Windows - it isn't)
This test simply creates a worker thread and retrieves the current thread ID from inside the worker thread so it can be reported and compared to the output of ThreadId(hWorkerThread)
Code: Select all
EnableExplicit
Global TestThreadId.l, TestThreadHandle.l, sTitle.s
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_MacOS
ImportC ""
pthread_self.l()
EndImport
CompilerCase #PB_OS_Linux
ImportC ""
pthread_self.l()
EndImport
CompilerEndSelect
Procedure.l GetCurrentThreadId() ;just added the sTitle lines for testing
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
sTitle = "Windows, OSVersion()=" + Str(OSVersion())
ProcedureReturn GetCurrentThreadId_()
CompilerCase #PB_OS_MacOS
sTitle = "OSX, OSVersion()=" + Str(OSVersion())
ProcedureReturn pthread_self_()
CompilerCase #PB_OS_Linux
sTitle = "Linux, OSVersion()=" + Str(OSVersion())
ProcedureReturn pthread_self_()
CompilerEndSelect
EndProcedure
Procedure TestThread(*threadParam)
TestThreadId = GetCurrentThreadId()
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
TestThreadHandle = GetCurrentThread_()
CompilerEndIf
Delay(500) ;to give the primary thread time to call ThreadId(workerthread)
EndProcedure
Define hThread.l, PBThreadId.l
hThread = CreateThread(@TestThread(),0)
Delay(100) ;probably not needed
PBThreadId = ThreadID(hThread)
WaitThread(hThread)
MessageRequester("THREADID - " + sTitle,"Primary: ThreadId=0x" + Hex(GetCurrentThreadId(), #PB_Long) + #CRLF$ +
"Worker: API ThreadId_ =0x" + Hex(TestThreadId, #PB_Long) + " Handle=0x" + Hex(TestThreadHandle, #PB_Long) + #CRLF$ +
"Worker: PBs ThreadID()=0x" + Hex(PBThreadId, #PB_Long) )
ps. am I weird for thinking that it's strange that Mac's Cocoa uses strings instead of numeric constants like WinAPI? and from a readability perspective i find #NSThread_currentThread just as easy to read as "NSThread currentThread" lol

Last edited by Keya on Tue Sep 01, 2015 12:34 pm, edited 3 times in total.
Re: Cross-platform function to get the current thread ID
It looks like on Windows you need to use the API function GetThreadId to get the same values.
I'm not sure what you mean exactly with your remark about strings on OSX.
NSThread currentThread is not a constant but a class function.

Code: Select all
Import ""
GetThreadId(hThread)
EndImport
myThread = CreateThread(@TestThread(),0)
ThreadId = GetThreadId(ThreadID(myThread))
NSThread currentThread is not a constant but a class function.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: Cross-platform function to get the current thread ID
Good catch! Yes in Windows it's returning a Handle, not ID. I verified by checking both the Threads and Handles windows in Ollydbg.wilbert wrote:It looks like on Windows you need to use the API function GetThreadId
But this is a different handle to GetCurrentThread_() which confused me initially.
GetThreadId doesnt exist on XP tho, but its not really an issue in this case because GetCurrentThreadId_() is available
So in conclusion ... ThreadId() in Windows returns the Thread Handle/hThread.
whereas in Linux and OSX it returns the Thread ID. Would be good to mention this in the helpfile, or change ThreadID to correctly return GetCurrentThreadId_, and add another PB function GetThreadHandle.
For example: Debug CocoaMessage(0, 0, "NSThread currentThread")I'm not sure what you mean exactly with your remark about strings on OSX.
NSThread currentThread is not a constant but a class function.
Where "NSThread currentThread" is a string and not constant like #NSThread_currentThread
Or is this something along the lines of an OSX version of GetProcAddress(LoadLibrary("NSThread"), "currentThread") ? which would make perfect sense being strings
Last edited by Keya on Tue Sep 01, 2015 12:17 pm, edited 1 time in total.
Re: Cross-platform function to get the current thread ID
On the lowest level, OSX uses the C functions listed in the "Objective-C Runtime Reference" (you can Google it) to work with Cocoa objects.
One of the most used functions is objc_msgSend to send a message to an object or class.
When the first Cocoa based version of PureBasic was released (PB 5.00) those functions were the only way to communicate with Cocoa objects.
You need quite a bit of code this way to do even simple things and it is complicated to return structures like a point or rectangle this way with PureBasic.
After PB 5.00 was released, some of us users (like me) were experimenting with this.
Since interacting with the objects PB creates is pretty important to set some platform specific things I wanted an easier solution so I started working on a userlib.
It was named oMsg ; an Objective C based user library which internally uses the NSInvocation class to interact with Cocoa objects and did also some things like PB string conversion to NSString for you.
Because quite a few users don't like to use user libraries (afraid support will suddenly end) and it would have been better to have a standard solution, I asked Fred to add the command to PureBasic itself.
After some of his feedback, he eventually added the final version of the oMsg command to PureBasic 5.10 (which I'm still thankful for) renamed as CocoaMessage to fit the way other procedures are named.
If you will study the NSInvocation class, you will understand that CocoaMessage works more or less like an interpreter (maybe the strings make a bit more sense now).
As a result of this, CocoaMessage is very flexible in what you can do with it without using any ImportC statements.
It's not super fast but fast enough for most purposes. For a time critical thing which uses a lot of calls, you can still revert to the low level functions (when you would compile an Objective-C source with XCode, you would see it uses those low level functions).
One of the most used functions is objc_msgSend to send a message to an object or class.
When the first Cocoa based version of PureBasic was released (PB 5.00) those functions were the only way to communicate with Cocoa objects.
You need quite a bit of code this way to do even simple things and it is complicated to return structures like a point or rectangle this way with PureBasic.
After PB 5.00 was released, some of us users (like me) were experimenting with this.
Since interacting with the objects PB creates is pretty important to set some platform specific things I wanted an easier solution so I started working on a userlib.
It was named oMsg ; an Objective C based user library which internally uses the NSInvocation class to interact with Cocoa objects and did also some things like PB string conversion to NSString for you.
Because quite a few users don't like to use user libraries (afraid support will suddenly end) and it would have been better to have a standard solution, I asked Fred to add the command to PureBasic itself.
After some of his feedback, he eventually added the final version of the oMsg command to PureBasic 5.10 (which I'm still thankful for) renamed as CocoaMessage to fit the way other procedures are named.
If you will study the NSInvocation class, you will understand that CocoaMessage works more or less like an interpreter (maybe the strings make a bit more sense now).
As a result of this, CocoaMessage is very flexible in what you can do with it without using any ImportC statements.
It's not super fast but fast enough for most purposes. For a time critical thing which uses a lot of calls, you can still revert to the low level functions (when you would compile an Objective-C source with XCode, you would see it uses those low level functions).
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: Cross-platform function to get the current thread ID
oh my gosh i had no idea! Thankyou for the clarification, that makes a lot of sense 
and megabig THANKYOU to you for all your hard work with oMsg and thankyou to Fred for giving it a proper home within PB - it removes the shackles and opens up a heck of a lot of doors!!!

I've also got plenty to read now about OSX API/Objective C while i want for my books to arrive heehee

and megabig THANKYOU to you for all your hard work with oMsg and thankyou to Fred for giving it a proper home within PB - it removes the shackles and opens up a heck of a lot of doors!!!



I've also got plenty to read now about OSX API/Objective C while i want for my books to arrive heehee
