Reputation: 21
My question is regarding the PC register value of which is giving to the created thread.
if I cread a new process with fork()
the PC value will be copied from the father proccess to the child proccess as the PC value is the next command in the code.
However if I create a new thread as following
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg)
with:
err = pthread_create(&thready, NULL, &doSomeThing, NULL);
I simply give an order for the thread to run with a procedure yet i don't understand from where the created thread gets it's PC value? it's not the father PC for sure. How does the PC value set to the first line of doSomeThing code?
Upvotes: 1
Views: 91
Reputation: 36391
(Roughly) It's PC is set to the address of the function you gave. In real it is set to some stub that calls your function. In that stub there is some call to a system routine that sets everything needed to support your thread in the system. How the PC is exactly set is very specific to the kernel and hardware. If you feel comfortable with system code, you can browse the Linux kernel sources to look how this is really done.
For example the glibc 2.0 has a start_thread
function that takes the address of the struct pthread the system built (that routine is the stub). In that function there is a call to some macro CALL_THREAD_FCT(thread_struct_address)
which purpose is to start running your function. Its definition for i386 platform is :
#define CALL_THREAD_FCT ( descr ) \
({ void *__res; \
int __ignore1, __ignore2; \
asm volatile ("pushl %%eax\n\t" \
"pushl %%eax\n\t" \
"pushl %%eax\n\t" \
"pushl %%gs:%P4\n\t" \
"call *%%gs:%P3\n\t" \
"addl $16, %%esp" \
: "=a" (__res), "=c" (__ignore1), "=d" (__ignore2) \
: "i" (offsetof (struct pthread, start_routine)), \
"i" (offsetof (struct pthread, arg))); \
__res; })
See http://fossies.org/dox/glibc-2.20/pthread__create_8c_source.html for example.
Upvotes: 2