1c7561b931e249acf3768ead77638545b0ccaa8f1njn 2c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--------------------------------------------------------------------*/ 3c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--- The thread state. m_threadstate.c ---*/ 4c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--------------------------------------------------------------------*/ 5c7561b931e249acf3768ead77638545b0ccaa8f1njn 6c7561b931e249acf3768ead77638545b0ccaa8f1njn/* 7c7561b931e249acf3768ead77638545b0ccaa8f1njn This file is part of Valgrind, a dynamic binary instrumentation 8c7561b931e249acf3768ead77638545b0ccaa8f1njn framework. 9c7561b931e249acf3768ead77638545b0ccaa8f1njn 10b3a1e4bffbdbbf38304f216af405009868f43628sewardj Copyright (C) 2000-2015 Julian Seward 11c7561b931e249acf3768ead77638545b0ccaa8f1njn jseward@acm.org 12c7561b931e249acf3768ead77638545b0ccaa8f1njn 13c7561b931e249acf3768ead77638545b0ccaa8f1njn This program is free software; you can redistribute it and/or 14c7561b931e249acf3768ead77638545b0ccaa8f1njn modify it under the terms of the GNU General Public License as 15c7561b931e249acf3768ead77638545b0ccaa8f1njn published by the Free Software Foundation; either version 2 of the 16c7561b931e249acf3768ead77638545b0ccaa8f1njn License, or (at your option) any later version. 17c7561b931e249acf3768ead77638545b0ccaa8f1njn 18c7561b931e249acf3768ead77638545b0ccaa8f1njn This program is distributed in the hope that it will be useful, but 19c7561b931e249acf3768ead77638545b0ccaa8f1njn WITHOUT ANY WARRANTY; without even the implied warranty of 20c7561b931e249acf3768ead77638545b0ccaa8f1njn MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21c7561b931e249acf3768ead77638545b0ccaa8f1njn General Public License for more details. 22c7561b931e249acf3768ead77638545b0ccaa8f1njn 23c7561b931e249acf3768ead77638545b0ccaa8f1njn You should have received a copy of the GNU General Public License 24c7561b931e249acf3768ead77638545b0ccaa8f1njn along with this program; if not, write to the Free Software 25c7561b931e249acf3768ead77638545b0ccaa8f1njn Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26c7561b931e249acf3768ead77638545b0ccaa8f1njn 02111-1307, USA. 27c7561b931e249acf3768ead77638545b0ccaa8f1njn 28c7561b931e249acf3768ead77638545b0ccaa8f1njn The GNU General Public License is contained in the file COPYING. 29c7561b931e249acf3768ead77638545b0ccaa8f1njn*/ 30c7561b931e249acf3768ead77638545b0ccaa8f1njn 31c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_basics.h" 324cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h" 33c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_threadstate.h" 341e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian#include "pub_core_mallocfree.h" // VG_(malloc) 35c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_libcassert.h" 36c91f58449e6fc2a4ce0851639a342c4277612fbbflorian#include "pub_core_inner.h" 3727233e99d0964be703299c7f83396f1864d7b5d0bart#if defined(ENABLE_INNER_CLIENT_REQUEST) 3827233e99d0964be703299c7f83396f1864d7b5d0bart#include "helgrind/helgrind.h" 3927233e99d0964be703299c7f83396f1864d7b5d0bart#endif 40c7561b931e249acf3768ead77638545b0ccaa8f1njn 41c7561b931e249acf3768ead77638545b0ccaa8f1njn/*------------------------------------------------------------*/ 42c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--- Data structures. ---*/ 43c7561b931e249acf3768ead77638545b0ccaa8f1njn/*------------------------------------------------------------*/ 44c7561b931e249acf3768ead77638545b0ccaa8f1njn 45c7561b931e249acf3768ead77638545b0ccaa8f1njnThreadId VG_(running_tid) = VG_INVALID_THREADID; 46c7561b931e249acf3768ead77638545b0ccaa8f1njn 471e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florianThreadState *VG_(threads); 481e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florianUInt VG_N_THREADS; 49c7561b931e249acf3768ead77638545b0ccaa8f1njn 50c7561b931e249acf3768ead77638545b0ccaa8f1njn/*------------------------------------------------------------*/ 51c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--- Operations. ---*/ 52c7561b931e249acf3768ead77638545b0ccaa8f1njn/*------------------------------------------------------------*/ 53c7561b931e249acf3768ead77638545b0ccaa8f1njn 5427233e99d0964be703299c7f83396f1864d7b5d0bartvoid VG_(init_Threads)(void) 5527233e99d0964be703299c7f83396f1864d7b5d0bart{ 5627233e99d0964be703299c7f83396f1864d7b5d0bart ThreadId tid; 571e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian 584e4ded74e620334a719286db7b5bf86fa7bcbcaephilippe VG_(threads) = VG_(arena_memalign) (VG_AR_CORE, "init_Threads", 594e4ded74e620334a719286db7b5bf86fa7bcbcaephilippe LibVEX_GUEST_STATE_ALIGN, 604e4ded74e620334a719286db7b5bf86fa7bcbcaephilippe VG_N_THREADS * sizeof VG_(threads)[0]); 6127233e99d0964be703299c7f83396f1864d7b5d0bart 6292e2c648864a53081be2f8d843c31b18a2252808bart for (tid = 1; tid < VG_N_THREADS; tid++) { 6392e2c648864a53081be2f8d843c31b18a2252808bart INNER_REQUEST( 6492e2c648864a53081be2f8d843c31b18a2252808bart ANNOTATE_BENIGN_RACE_SIZED(&VG_(threads)[tid].status, 6592e2c648864a53081be2f8d843c31b18a2252808bart sizeof(VG_(threads)[tid].status), "")); 6692e2c648864a53081be2f8d843c31b18a2252808bart INNER_REQUEST( 6792e2c648864a53081be2f8d843c31b18a2252808bart ANNOTATE_BENIGN_RACE_SIZED(&VG_(threads)[tid].os_state.exitcode, 6892e2c648864a53081be2f8d843c31b18a2252808bart sizeof(VG_(threads)[tid].os_state.exitcode), 6992e2c648864a53081be2f8d843c31b18a2252808bart "")); 7092e2c648864a53081be2f8d843c31b18a2252808bart } 7127233e99d0964be703299c7f83396f1864d7b5d0bart} 7227233e99d0964be703299c7f83396f1864d7b5d0bart 73c7561b931e249acf3768ead77638545b0ccaa8f1njnconst HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status ) 74c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 75c7561b931e249acf3768ead77638545b0ccaa8f1njn switch (status) { 76c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_Empty: return "VgTs_Empty"; 77c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_Init: return "VgTs_Init"; 78c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_Runnable: return "VgTs_Runnable"; 79c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_WaitSys: return "VgTs_WaitSys"; 80c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_Yielding: return "VgTs_Yielding"; 81c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_Zombie: return "VgTs_Zombie"; 82c7561b931e249acf3768ead77638545b0ccaa8f1njn default: return "VgTs_???"; 83c7561b931e249acf3768ead77638545b0ccaa8f1njn } 84c7561b931e249acf3768ead77638545b0ccaa8f1njn} 85c7561b931e249acf3768ead77638545b0ccaa8f1njn 86b8ba0310d94b421f6522f1a816f85653e795f5d8philippeconst HChar* VG_(name_of_VgSchedReturnCode) ( VgSchedReturnCode retcode ) 87b8ba0310d94b421f6522f1a816f85653e795f5d8philippe{ 88b8ba0310d94b421f6522f1a816f85653e795f5d8philippe switch (retcode) { 89b8ba0310d94b421f6522f1a816f85653e795f5d8philippe case VgSrc_None: return "VgSrc_None"; 90b8ba0310d94b421f6522f1a816f85653e795f5d8philippe case VgSrc_ExitThread: return "VgSrc_ExitThread"; 91b8ba0310d94b421f6522f1a816f85653e795f5d8philippe case VgSrc_ExitProcess: return "VgSrc_ExitProcess"; 92b8ba0310d94b421f6522f1a816f85653e795f5d8philippe case VgSrc_FatalSig: return "VgSrc_FatalSig"; 93b8ba0310d94b421f6522f1a816f85653e795f5d8philippe default: return "VgSrc_???"; 94b8ba0310d94b421f6522f1a816f85653e795f5d8philippe } 95b8ba0310d94b421f6522f1a816f85653e795f5d8philippe} 96b8ba0310d94b421f6522f1a816f85653e795f5d8philippe 97c7561b931e249acf3768ead77638545b0ccaa8f1njnThreadState *VG_(get_ThreadState)(ThreadId tid) 98c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 99c7561b931e249acf3768ead77638545b0ccaa8f1njn vg_assert(tid >= 0 && tid < VG_N_THREADS); 10013ac35b96f354b790c5aaface07d78988734201dsewardj vg_assert(VG_(threads)[tid].tid == tid); 101c7561b931e249acf3768ead77638545b0ccaa8f1njn return &VG_(threads)[tid]; 102c7561b931e249acf3768ead77638545b0ccaa8f1njn} 103c7561b931e249acf3768ead77638545b0ccaa8f1njn 104c7561b931e249acf3768ead77638545b0ccaa8f1njnBool VG_(is_valid_tid) ( ThreadId tid ) 105c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 106c7561b931e249acf3768ead77638545b0ccaa8f1njn /* tid is unsigned, hence no < 0 test. */ 107c7561b931e249acf3768ead77638545b0ccaa8f1njn if (tid == 0) return False; 108c7561b931e249acf3768ead77638545b0ccaa8f1njn if (tid >= VG_N_THREADS) return False; 109c7561b931e249acf3768ead77638545b0ccaa8f1njn if (VG_(threads)[tid].status == VgTs_Empty) return False; 110c7561b931e249acf3768ead77638545b0ccaa8f1njn return True; 111c7561b931e249acf3768ead77638545b0ccaa8f1njn} 112c7561b931e249acf3768ead77638545b0ccaa8f1njn 113c7561b931e249acf3768ead77638545b0ccaa8f1njn// This function is for tools to call. 114c7561b931e249acf3768ead77638545b0ccaa8f1njnThreadId VG_(get_running_tid)(void) 115c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 116c7561b931e249acf3768ead77638545b0ccaa8f1njn return VG_(running_tid); 117c7561b931e249acf3768ead77638545b0ccaa8f1njn} 118c7561b931e249acf3768ead77638545b0ccaa8f1njn 119c7561b931e249acf3768ead77638545b0ccaa8f1njnBool VG_(is_running_thread)(ThreadId tid) 120c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 121c7561b931e249acf3768ead77638545b0ccaa8f1njn ThreadState *tst = VG_(get_ThreadState)(tid); 122c7561b931e249acf3768ead77638545b0ccaa8f1njn 123c7561b931e249acf3768ead77638545b0ccaa8f1njn return 124c7561b931e249acf3768ead77638545b0ccaa8f1njn// tst->os_state.lwpid == VG_(gettid)() && // check we're this tid 125c7561b931e249acf3768ead77638545b0ccaa8f1njn VG_(running_tid) == tid && // and that we've got the lock 126c7561b931e249acf3768ead77638545b0ccaa8f1njn tst->status == VgTs_Runnable; // and we're runnable 127c7561b931e249acf3768ead77638545b0ccaa8f1njn} 128c7561b931e249acf3768ead77638545b0ccaa8f1njn 129c7561b931e249acf3768ead77638545b0ccaa8f1njn/* Return true if the thread is still alive but in the process of exiting. */ 130c7561b931e249acf3768ead77638545b0ccaa8f1njninline Bool VG_(is_exiting)(ThreadId tid) 131c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 132c7561b931e249acf3768ead77638545b0ccaa8f1njn vg_assert(VG_(is_valid_tid)(tid)); 133c7561b931e249acf3768ead77638545b0ccaa8f1njn return VG_(threads)[tid].exitreason != VgSrc_None; 134c7561b931e249acf3768ead77638545b0ccaa8f1njn} 135c7561b931e249acf3768ead77638545b0ccaa8f1njn 136c7561b931e249acf3768ead77638545b0ccaa8f1njn/* Return the number of non-dead Threads */ 137c7561b931e249acf3768ead77638545b0ccaa8f1njnInt VG_(count_living_threads)(void) 138c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 139c7561b931e249acf3768ead77638545b0ccaa8f1njn Int count = 0; 140c7561b931e249acf3768ead77638545b0ccaa8f1njn ThreadId tid; 141c7561b931e249acf3768ead77638545b0ccaa8f1njn 142c7561b931e249acf3768ead77638545b0ccaa8f1njn for(tid = 1; tid < VG_N_THREADS; tid++) 143c7561b931e249acf3768ead77638545b0ccaa8f1njn if (VG_(threads)[tid].status != VgTs_Empty && 144c7561b931e249acf3768ead77638545b0ccaa8f1njn VG_(threads)[tid].status != VgTs_Zombie) 145c7561b931e249acf3768ead77638545b0ccaa8f1njn count++; 146c7561b931e249acf3768ead77638545b0ccaa8f1njn 147c7561b931e249acf3768ead77638545b0ccaa8f1njn return count; 148c7561b931e249acf3768ead77638545b0ccaa8f1njn} 149c7561b931e249acf3768ead77638545b0ccaa8f1njn 150d8a725e012a2af94bf265043a08d09c83b89b403sewardj/* Return the number of threads in VgTs_Runnable state */ 151d8a725e012a2af94bf265043a08d09c83b89b403sewardjInt VG_(count_runnable_threads)(void) 152d8a725e012a2af94bf265043a08d09c83b89b403sewardj{ 153d8a725e012a2af94bf265043a08d09c83b89b403sewardj Int count = 0; 154d8a725e012a2af94bf265043a08d09c83b89b403sewardj ThreadId tid; 155d8a725e012a2af94bf265043a08d09c83b89b403sewardj 156d8a725e012a2af94bf265043a08d09c83b89b403sewardj for(tid = 1; tid < VG_N_THREADS; tid++) 157d8a725e012a2af94bf265043a08d09c83b89b403sewardj if (VG_(threads)[tid].status == VgTs_Runnable) 158d8a725e012a2af94bf265043a08d09c83b89b403sewardj count++; 159d8a725e012a2af94bf265043a08d09c83b89b403sewardj 160d8a725e012a2af94bf265043a08d09c83b89b403sewardj return count; 161d8a725e012a2af94bf265043a08d09c83b89b403sewardj} 162d8a725e012a2af94bf265043a08d09c83b89b403sewardj 163c7561b931e249acf3768ead77638545b0ccaa8f1njn/* Given an LWP id (ie, real kernel thread id), find the corresponding 164c7561b931e249acf3768ead77638545b0ccaa8f1njn ThreadId */ 1654278172aee9a9db96cc2f9aff9158e3164fa113csewardjThreadId VG_(lwpid_to_vgtid)(Int lwp) 166c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 167c7561b931e249acf3768ead77638545b0ccaa8f1njn ThreadId tid; 168c7561b931e249acf3768ead77638545b0ccaa8f1njn 169c7561b931e249acf3768ead77638545b0ccaa8f1njn for(tid = 1; tid < VG_N_THREADS; tid++) 170d8a725e012a2af94bf265043a08d09c83b89b403sewardj if (VG_(threads)[tid].status != VgTs_Empty 171d8a725e012a2af94bf265043a08d09c83b89b403sewardj && VG_(threads)[tid].os_state.lwpid == lwp) 172c7561b931e249acf3768ead77638545b0ccaa8f1njn return tid; 173c7561b931e249acf3768ead77638545b0ccaa8f1njn 174c7561b931e249acf3768ead77638545b0ccaa8f1njn return VG_INVALID_THREADID; 175c7561b931e249acf3768ead77638545b0ccaa8f1njn} 176c7561b931e249acf3768ead77638545b0ccaa8f1njn 177c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--------------------------------------------------------------------*/ 178c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--- end ---*/ 179c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--------------------------------------------------------------------*/ 180