-Implement @code{thread_join(struct thread *)} in
-@file{threads/thread.c}. There is already a prototype for it in
-@file{threads/thread.h}, which you should not change. This function
-causes the currently running thread to block until thread passed as an
-argument exits. If A is the running thread and B is the argument,
-then we say that ``A joins B'' in this case.
+Implement @code{thread_join(tid_t)} in @file{threads/thread.c}. There
+is already a prototype for it in @file{threads/thread.h}, which you
+should not change. This function causes the currently running thread
+to block until the thread whose thread id is passed as an argument
+exits. If A is the running thread and B is the argument, then we say
+that ``A joins B'' in this case.
+
+Incidentally, we don't use @code{struct thread *} as
+@file{thread_join()}'s parameter type because a thread pointer is not
+unique over time. That is, when a thread dies, its memory may be,
+whether immediately or much later, reused for another thread. If
+thread A over time had two children B and C that were stored at the
+same address, then @code{thread_join(@r{B})} and
+@code{thread_join(@r{C})} would be ambiguous. Introducing a thread id
+or @dfn{tid}, represented by type @code{tid_t}, that is intentionally
+unique over time solves the problem. The provided code uses an
+@code{int} for @code{tid_t}, but you may decide you prefer to use some
+other type.