-1

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?

raiks
  • 1,270
  • 1
  • 15
  • 12
  • 2
    The TEB (Thread Environment Block) is a basic part of the runtime environment. The FS register stores a pointer to it. Gritty implementation details that you are not supposed to have to worry about. – Hans Passant Mar 22 '18 at 12:31
  • You could put it in some struct at the top of the thread stack. – Martin James Mar 22 '18 at 13:22
  • @HansPassant this should have been an answer because it really explains, thanks. – raiks Mar 22 '18 at 14:39
  • @MartinJames I am trying to imagine your scenario. You probably meant stack bottom, not top (the top will contain arguments for the `gettid()`). The OS could place a `threadId` in the stack bottom in theory when scheduling a thread (it knows the `threadId` at this point), but the problem is that the stack pointer (SP/ESP/RSP) in `x86` contains the address of the stack top and the info to figure out the stack bottom is not stored elsewhere in registers. Correct me if I'm wrong. – raiks Mar 22 '18 at 14:45

3 Answers3

0

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

Alex C
  • 923
  • 9
  • 23
  • I checked answers in the question you mentioned (and also the similar ones). There is a lot of "pid"/"tid" juggling and quite elaborate information on how those are stored in the kernel. However, none of them answers my question which is quite specific. Try to imagine yourself a kernel - what would you do if you are called by a thread and need to figure out who's calling you? :) – raiks Mar 22 '18 at 12:24
  • This "call" is done by means of software interrupts or traps. When the userspace application performs a system call, it fills in a register with the syscall num and performs a soft interrupt. The interrupt routine then triggers the kernel code to handle the syscall, which looks inside the task_struct that is currently marked as being executed to find out the pid/tid, niceness, priority etc of the running process. The current running task is updated with a new one when a context switch occurs - task's instruction pointer is passed for execution to the cpu. – Alex C Mar 22 '18 at 15:14
  • Well, I understand how a syscall is generally made. I also understand how an OS figures out what process is currently active (there can be only 1 address space active at a time - RAM is a shared resource). However, N-core systems, there can be multiple threads belonging to one process progressing at exactly the same time. Now imagine that one of them calls the gettid(). Getting PID is easy, but what about TID? So far I can't see how it can be done without employing an internal CPU register for storing the threadID or calling getcpu() from inside the gettid() and consulting the scheduler. – raiks Mar 23 '18 at 10:17
  • The task_struct also includes a field which specifies on which cpu it was executing currently. Also, each cpu has it's own run queue, you can check kernel/sched.c for the implementation. – Alex C Mar 23 '18 at 15:05
0

You are looking for Thread Control Block(TCB).

It is a data structure that holds information about threads.

A light reading material can be found here about the topic: https://www.cs.duke.edu/courses/fall09/cps110/slides/threads2.3.ppt

But I would recommend getting a copy of Modern Operating Systems by Andrew S. Tanenbaum if you are interested in OS.

Chapter 2 Section 2.2 Threads:

Implementing Threads in User Space - "When threads are managed in user space, each process needs its own private thread table to keep track of the threads in that process."

Implementing threads in the Kernel - "The kernel has a thread table that keeps track of all the threads in the system."

Just an edit you might also want to read "SCHEDULING". In a general manner you can say kernel decides which thread/process should be using the CPU.Thus kernel knows which thread/process made a system call. I am not going into detail because it depends on which OS we are talking about.

ero
  • 26
  • 1
  • 3
0

The answer to your question is entirely system specific. However, most processors know nothing about threads. They only support processes. Threads are generally implemented by created separate processes that share the same address space.

When you do a system service call to get a thread ID it is going to be implemented in the same general fashion as system service to get the process id. Imagine how a get process ID function could work in a system that does not support threads. And to keep it simple, let's assume a single processor.

You are going to have some kind of data structure to represent the current process and the kernel is going to have some means of identifying the current process (e.g. a pointer in the kernel address space to that process). On some processors there is a current task register that points to a structure defined by the processor specification. An operating system can usually add its own data to the end of this structure.

So now I want to upgrade this operating system to support threads. To that I must have a data structure that describes the thread. In that structures I have a pointer to a structure that defines the process.

Then get thread ID works the same way get process ID worked before. But now Get Process ID has an additional step that I have to translate the thread to the process to get its id (which may even be included in the thread block).

user3344003
  • 20,574
  • 3
  • 26
  • 62