How does getpid work?
The kernel does job scheduling and provides system calls.
When a process is running, the kernel schedules its runtime - especially it assigns a PID to it - such information is stored inside the kernel address space, in data structures (e.g. inside a task struct).
Thus, when a process calls the getpid()
system call, the kernel just has to look in the task structure of the calling (i.e. currently running) process.
When a system call is executed, there is a privilege switch, i.e. the executed code is allowed to execute more instructions and access data forbidden to userland code.
There is however no process context switch so the kernel code is still running in the calling process context. That means the kernel does not need to search which process is calling it, it already knows it. The getpid system call code simply retrieve the process id from a pointer to an internal structure that contains its own process/thread specific information. This structure is operating system implementation dependent.
For example with Illumos (OpenSolaris), the structure is named proc: http://src.illumos.org/source/xref/illumos-gate/usr/src/uts/common/sys/proc.h#131
In a single CPU system, there is a global variable that points to the proc structure of the running process or the current thread. The proc structure contains the process id.
In a multi CPU system, there is either a similar pointer for every CPU or the MMU context is used to set up such a global variable for the syscall.
int64_t
getpid(void)
{
rval_t r;
proc_t *p;
p = ttoproc(curthread);
r.r_val1 = p->p_pid;
In this example, curthread is the global variable that is used.