I'm trying to understand how an OS figures out what thread is a current one (for example, when the thread calls gettid() or GetCurrentThreadId()). Since a process address space is shared between all threads, keeping a thread id there is not an option. It must be something unique to each thread (i.e. stored in its context). If I was an OS developer, I would store it in some internal CPU register readable only in kernel mode. I googled a lot but haven't found any similar question (as if it was super obvious).
So how is it implemented in real operating systems like Linux or Windows?
I believe this has already been very well explained in this question: how kernel distinguishes between thread and process
If you want to find out more, you can also google for the kernel task structure and see what info is stored about each type of processes running in the user space