pthread_join is probably internally implemented as a wait for a semaphore which is triggered when the thread exits, either when it calls pthread_exit or when its main function exits.
In any case, the source code for glibc is available, try google code search (I saw some informative stuff in there)