* * If there is a thread descriptor with the same tid, it must be from a dead * thread. Remove it now. * *****************************************************************************/
| 920 | * |
| 921 | *****************************************************************************/ |
| 922 | void |
| 923 | ThreadList::addToActiveList(Thread *th) |
| 924 | { |
| 925 | int tid; |
| 926 | Thread *thread; |
| 927 | Thread *next_thread; |
| 928 | |
| 929 | lock_threads(); |
| 930 | |
| 931 | // CONTEXT: After fork(), we called: |
| 932 | // ... -> initializeMtcpEngine() -> ThreadList::init() -> initThread() |
| 933 | // -> addToActiveList() |
| 934 | // NOTE: After a call to fork(), only the calling thread continues to live. |
| 935 | // Before initializeMtcpEngine() called init(), it called: |
| 936 | // ... -> initializeMtcpEngine() -> ThreadSync::initMotherOfAll() -> |
| 937 | // -> ThreadSync::initThread() |
| 938 | // Logically, we would have set 'curThread = NULL;; inside |
| 939 | // ThreadSync::initThread(), but it's inconvenient since curThread |
| 940 | // is static (file-private). |
| 941 | // So, initThread() created the new thread descriptor. We make sure |
| 942 | // to set curThread to th, the new descriptor, now, in case it wasn't |
| 943 | // done yet. |
| 944 | // We had also set curThread to NULL in ThreadList::init(). This also |
| 945 | // makes logical sense, but only because a call to fork() allows |
| 946 | // only the calling thread (caller of ThreadList::init()) to live on. |
| 947 | // So, that solution seems less general. So, we'll handle it here, too: |
| 948 | curThread = th; |
| 949 | |
| 950 | tid = curThread->tid; |
| 951 | JASSERT(tid != 0); |
| 952 | |
| 953 | // First remove duplicate descriptors. |
| 954 | for (thread = activeThreads; thread != NULL; thread = next_thread) { |
| 955 | next_thread = thread->next; |
| 956 | if (thread != curThread && thread->tid == tid) { |
| 957 | JTRACE("Removing duplicate thread descriptor") (thread->tid); |
| 958 | |
| 959 | // There will be at most one duplicate descriptor. |
| 960 | threadIsDead(thread); |
| 961 | continue; |
| 962 | } |
| 963 | |
| 964 | // FIXME: This causes segfault on second restart. Why? |
| 965 | // JASSERT(thread != curThread)(thread) |
| 966 | // .Text("adding curThread, but it's already on activeThreads"); |
| 967 | |
| 968 | /* NOTE: ST_ZOMBIE is used only for the sake of efficiency. We |
| 969 | * test threads in state ST_ZOMBIE using tgkill to remove them |
| 970 | * early (before reaching a checkpoint) so that the |
| 971 | * threadrdescriptor list does not grow too long. |
| 972 | */ |
| 973 | if (thread->exiting) { |
| 974 | /* if no thread with this tid, then we can remove zombie descriptor */ |
| 975 | if (-1 == THREAD_TGKILL(motherpid, thread->tid, 0)) { |
| 976 | JTRACE("Killing zombie thread") (thread->tid); |
| 977 | threadIsDead(thread); |
| 978 | } |
| 979 | } |
nothing calls this directly
no test coverage detected