Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Jan 2013 23:16:41 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Trent Nelson <trent@snakebite.org>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Getting the current thread ID without a syscall?
Message-ID:  <20130115211641.GC2522@kib.kiev.ua>
In-Reply-To: <20130115205403.GA52904@snakebite.org>
References:  <20130115205403.GA52904@snakebite.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--2/5bycvrmDh4d1IB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Jan 15, 2013 at 03:54:03PM -0500, Trent Nelson wrote:
> Howdy,
>=20
>     I have an unusual requirement: I need to get the current thread ID
>     in as few instructions as possible.  On Windows, I managed to come
>     up with this glorious hack:
>=20
> #ifdef WITH_INTRINSICS
> #   ifdef MS_WINDOWS
> #       include <intrin.h>
> #       if defined(MS_WIN64)
> #           pragma intrinsic(__readgsdword)
> #           define _Py_get_current_process_id() (__readgsdword(0x40))
> #           define _Py_get_current_thread_id()  (__readgsdword(0x48))
> #       elif defined(MS_WIN32)
> #           pragma intrinsic(__readfsdword)
> #           define _Py_get_current_process_id() (__readfsdword(0x20))
> #           define _Py_get_current_thread_id()  (__readfsdword(0x24))
>=20
>     That exploits the fact that Windows uses the FS/GS registers to
>     store thread/process metadata.  Could I use a similar approach on
>     FreeBSD to get the thread ID without the need for syscalls?
The layout of the per-thread structure used by libthr is private and
is not guaranteed to be stable even on the stable branches.

Yes, you could obtain the tid this way, but note explicitely that using
it makes your application not binary compatible with any version of
the FreeBSD except the one you compiled on.

You could read the _thread_off_tid integer variable and use the value
as offset from the %fs base to the long containing the unique thread id.
But don't use this in anything except the private code.

>=20
>     (I technically don't need the thread ID, I just need to get some
>      form of unique identifier for the current thread such that I can
>      compare it to a known global value that's been set to the "main
>      thread", in order to determine if I'm currently that thread or not.
>      As long as it's unique for each thread, and static for the lifetime
>      of the thread, that's fine.)
>=20
>     The "am I the main thread?" comparison is made every ~50-100 opcodes,
>     which is why it needs to have the lowest overhead possible.
On newer CPUs in amd64 mode, there is getfsbase instruction which reads
the %fs register base. System guarantees that %fs base is unique among
live threads.

--2/5bycvrmDh4d1IB
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (FreeBSD)

iQIcBAEBAgAGBQJQ9cc4AAoJEJDCuSvBvK1BT0sP/39TH2lCuBjWweGlT7Ms7nqg
SXmm98UC+jqIblMdCwxg4Nyh9ffaDCJHswOtUxXWKCjR9hNSdArb9EWgXhrD6qNW
dYeMpSo+8lLJlTlsg40sYuyo3ykH2GBr9dzz9uFW2j+6WEo4bzhWRunRmTOu8pdY
I38cCKmzUqO7211TJpUKOBNWzpmSi5YRGPZ4alW/JHp883irMy03oOyCJit+zvmK
2u+TqA/XWT+p4ZbksCn1BKovjjG3z92lhgnDHpTUXmMkMrIvNNzqpDwtL8eA23JQ
WZpamo0JTM7o2ZKAR/8suem+nFz5HO3BNRYLxYdKU3KfKBaqdk7c2p0u8MYvW+Za
C8K7Ehxf75RrP86qNZT3+gic5GrZPV1/qbKd5T36S6Kw3sZQi/S/5UdbFGxPScDu
7iOBmWvh2RRRqTLUp3bWwYDTgK73vjQzHHgIKZIPVCkYK6Ic5Mf0Uf0PvFpuaO0q
nGiq8XY+h/I4LfHJmVqowVR9kErIjDP3rTH8zbsNdmBuxNi3KsJMNrVmZ3Vs/HOw
HaXZ2u89a2SRE56UHAesDIBLP38s2aQkXC23K/iGXMRIs9oPKbInziV35cggPTFC
nL/HDrPX8GITJgMmuwrg5ZDnmD3PlwKTPRBZ4bVw1nQIRSjskxDFJjB/vBdFrIne
IMhpi4p4+JdEXt7mjJpy
=0wRN
-----END PGP SIGNATURE-----

--2/5bycvrmDh4d1IB--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130115211641.GC2522>