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
10ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   Copyright (C) 2000-2017 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
50ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott HughesThreadState *VG_(inner_threads);
51ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes
52c7561b931e249acf3768ead77638545b0ccaa8f1njn/*------------------------------------------------------------*/
53c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--- Operations.                                          ---*/
54c7561b931e249acf3768ead77638545b0ccaa8f1njn/*------------------------------------------------------------*/
55c7561b931e249acf3768ead77638545b0ccaa8f1njn
5627233e99d0964be703299c7f83396f1864d7b5d0bartvoid VG_(init_Threads)(void)
5727233e99d0964be703299c7f83396f1864d7b5d0bart{
5827233e99d0964be703299c7f83396f1864d7b5d0bart   ThreadId tid;
591e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian
604e4ded74e620334a719286db7b5bf86fa7bcbcaephilippe   VG_(threads) = VG_(arena_memalign) (VG_AR_CORE, "init_Threads",
614e4ded74e620334a719286db7b5bf86fa7bcbcaephilippe                                       LibVEX_GUEST_STATE_ALIGN,
624e4ded74e620334a719286db7b5bf86fa7bcbcaephilippe                                       VG_N_THREADS * sizeof VG_(threads)[0]);
6327233e99d0964be703299c7f83396f1864d7b5d0bart
6492e2c648864a53081be2f8d843c31b18a2252808bart   for (tid = 1; tid < VG_N_THREADS; tid++) {
6592e2c648864a53081be2f8d843c31b18a2252808bart      INNER_REQUEST(
6692e2c648864a53081be2f8d843c31b18a2252808bart         ANNOTATE_BENIGN_RACE_SIZED(&VG_(threads)[tid].status,
6792e2c648864a53081be2f8d843c31b18a2252808bart                                    sizeof(VG_(threads)[tid].status), ""));
6892e2c648864a53081be2f8d843c31b18a2252808bart      INNER_REQUEST(
6992e2c648864a53081be2f8d843c31b18a2252808bart         ANNOTATE_BENIGN_RACE_SIZED(&VG_(threads)[tid].os_state.exitcode,
7092e2c648864a53081be2f8d843c31b18a2252808bart                                    sizeof(VG_(threads)[tid].os_state.exitcode),
7192e2c648864a53081be2f8d843c31b18a2252808bart                                    ""));
7292e2c648864a53081be2f8d843c31b18a2252808bart   }
73ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   INNER_REQUEST(VALGRIND_INNER_THREADS(VG_(threads)));
7427233e99d0964be703299c7f83396f1864d7b5d0bart}
7527233e99d0964be703299c7f83396f1864d7b5d0bart
76c7561b931e249acf3768ead77638545b0ccaa8f1njnconst HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status )
77c7561b931e249acf3768ead77638545b0ccaa8f1njn{
78c7561b931e249acf3768ead77638545b0ccaa8f1njn   switch (status) {
79c7561b931e249acf3768ead77638545b0ccaa8f1njn   case VgTs_Empty:     return "VgTs_Empty";
80c7561b931e249acf3768ead77638545b0ccaa8f1njn   case VgTs_Init:      return "VgTs_Init";
81c7561b931e249acf3768ead77638545b0ccaa8f1njn   case VgTs_Runnable:  return "VgTs_Runnable";
82c7561b931e249acf3768ead77638545b0ccaa8f1njn   case VgTs_WaitSys:   return "VgTs_WaitSys";
83c7561b931e249acf3768ead77638545b0ccaa8f1njn   case VgTs_Yielding:  return "VgTs_Yielding";
84c7561b931e249acf3768ead77638545b0ccaa8f1njn   case VgTs_Zombie:    return "VgTs_Zombie";
85c7561b931e249acf3768ead77638545b0ccaa8f1njn   default:             return "VgTs_???";
86c7561b931e249acf3768ead77638545b0ccaa8f1njn  }
87c7561b931e249acf3768ead77638545b0ccaa8f1njn}
88c7561b931e249acf3768ead77638545b0ccaa8f1njn
89b8ba0310d94b421f6522f1a816f85653e795f5d8philippeconst HChar* VG_(name_of_VgSchedReturnCode) ( VgSchedReturnCode retcode )
90b8ba0310d94b421f6522f1a816f85653e795f5d8philippe{
91b8ba0310d94b421f6522f1a816f85653e795f5d8philippe   switch (retcode) {
92b8ba0310d94b421f6522f1a816f85653e795f5d8philippe   case VgSrc_None:        return "VgSrc_None";
93b8ba0310d94b421f6522f1a816f85653e795f5d8philippe   case VgSrc_ExitThread:  return "VgSrc_ExitThread";
94b8ba0310d94b421f6522f1a816f85653e795f5d8philippe   case VgSrc_ExitProcess: return "VgSrc_ExitProcess";
95b8ba0310d94b421f6522f1a816f85653e795f5d8philippe   case VgSrc_FatalSig:    return "VgSrc_FatalSig";
96b8ba0310d94b421f6522f1a816f85653e795f5d8philippe   default:                return "VgSrc_???";
97b8ba0310d94b421f6522f1a816f85653e795f5d8philippe  }
98b8ba0310d94b421f6522f1a816f85653e795f5d8philippe}
99b8ba0310d94b421f6522f1a816f85653e795f5d8philippe
100c7561b931e249acf3768ead77638545b0ccaa8f1njnThreadState *VG_(get_ThreadState)(ThreadId tid)
101c7561b931e249acf3768ead77638545b0ccaa8f1njn{
102c7561b931e249acf3768ead77638545b0ccaa8f1njn   vg_assert(tid >= 0 && tid < VG_N_THREADS);
10313ac35b96f354b790c5aaface07d78988734201dsewardj   vg_assert(VG_(threads)[tid].tid == tid);
104c7561b931e249acf3768ead77638545b0ccaa8f1njn   return &VG_(threads)[tid];
105c7561b931e249acf3768ead77638545b0ccaa8f1njn}
106c7561b931e249acf3768ead77638545b0ccaa8f1njn
107c7561b931e249acf3768ead77638545b0ccaa8f1njnBool VG_(is_valid_tid) ( ThreadId tid )
108c7561b931e249acf3768ead77638545b0ccaa8f1njn{
109c7561b931e249acf3768ead77638545b0ccaa8f1njn   /* tid is unsigned, hence no < 0 test. */
110c7561b931e249acf3768ead77638545b0ccaa8f1njn   if (tid == 0) return False;
111c7561b931e249acf3768ead77638545b0ccaa8f1njn   if (tid >= VG_N_THREADS) return False;
112c7561b931e249acf3768ead77638545b0ccaa8f1njn   if (VG_(threads)[tid].status == VgTs_Empty) return False;
113c7561b931e249acf3768ead77638545b0ccaa8f1njn   return True;
114c7561b931e249acf3768ead77638545b0ccaa8f1njn}
115c7561b931e249acf3768ead77638545b0ccaa8f1njn
116c7561b931e249acf3768ead77638545b0ccaa8f1njn// This function is for tools to call.
117c7561b931e249acf3768ead77638545b0ccaa8f1njnThreadId VG_(get_running_tid)(void)
118c7561b931e249acf3768ead77638545b0ccaa8f1njn{
119c7561b931e249acf3768ead77638545b0ccaa8f1njn   return VG_(running_tid);
120c7561b931e249acf3768ead77638545b0ccaa8f1njn}
121c7561b931e249acf3768ead77638545b0ccaa8f1njn
122c7561b931e249acf3768ead77638545b0ccaa8f1njnBool VG_(is_running_thread)(ThreadId tid)
123c7561b931e249acf3768ead77638545b0ccaa8f1njn{
124c7561b931e249acf3768ead77638545b0ccaa8f1njn   ThreadState *tst = VG_(get_ThreadState)(tid);
125c7561b931e249acf3768ead77638545b0ccaa8f1njn
126c7561b931e249acf3768ead77638545b0ccaa8f1njn   return
127c7561b931e249acf3768ead77638545b0ccaa8f1njn//      tst->os_state.lwpid == VG_(gettid)() &&	// check we're this tid
128c7561b931e249acf3768ead77638545b0ccaa8f1njn      VG_(running_tid) == tid	           &&	// and that we've got the lock
129c7561b931e249acf3768ead77638545b0ccaa8f1njn      tst->status == VgTs_Runnable;		// and we're runnable
130c7561b931e249acf3768ead77638545b0ccaa8f1njn}
131c7561b931e249acf3768ead77638545b0ccaa8f1njn
132c7561b931e249acf3768ead77638545b0ccaa8f1njn/* Return true if the thread is still alive but in the process of exiting. */
133c7561b931e249acf3768ead77638545b0ccaa8f1njninline Bool VG_(is_exiting)(ThreadId tid)
134c7561b931e249acf3768ead77638545b0ccaa8f1njn{
135c7561b931e249acf3768ead77638545b0ccaa8f1njn   vg_assert(VG_(is_valid_tid)(tid));
136c7561b931e249acf3768ead77638545b0ccaa8f1njn   return VG_(threads)[tid].exitreason != VgSrc_None;
137c7561b931e249acf3768ead77638545b0ccaa8f1njn}
138c7561b931e249acf3768ead77638545b0ccaa8f1njn
139c7561b931e249acf3768ead77638545b0ccaa8f1njn/* Return the number of non-dead Threads */
140c7561b931e249acf3768ead77638545b0ccaa8f1njnInt VG_(count_living_threads)(void)
141c7561b931e249acf3768ead77638545b0ccaa8f1njn{
142c7561b931e249acf3768ead77638545b0ccaa8f1njn   Int count = 0;
143c7561b931e249acf3768ead77638545b0ccaa8f1njn   ThreadId tid;
144c7561b931e249acf3768ead77638545b0ccaa8f1njn
145c7561b931e249acf3768ead77638545b0ccaa8f1njn   for(tid = 1; tid < VG_N_THREADS; tid++)
146c7561b931e249acf3768ead77638545b0ccaa8f1njn      if (VG_(threads)[tid].status != VgTs_Empty &&
147c7561b931e249acf3768ead77638545b0ccaa8f1njn	  VG_(threads)[tid].status != VgTs_Zombie)
148c7561b931e249acf3768ead77638545b0ccaa8f1njn	 count++;
149c7561b931e249acf3768ead77638545b0ccaa8f1njn
150c7561b931e249acf3768ead77638545b0ccaa8f1njn   return count;
151c7561b931e249acf3768ead77638545b0ccaa8f1njn}
152c7561b931e249acf3768ead77638545b0ccaa8f1njn
153d8a725e012a2af94bf265043a08d09c83b89b403sewardj/* Return the number of threads in VgTs_Runnable state */
154d8a725e012a2af94bf265043a08d09c83b89b403sewardjInt VG_(count_runnable_threads)(void)
155d8a725e012a2af94bf265043a08d09c83b89b403sewardj{
156d8a725e012a2af94bf265043a08d09c83b89b403sewardj   Int count = 0;
157d8a725e012a2af94bf265043a08d09c83b89b403sewardj   ThreadId tid;
158d8a725e012a2af94bf265043a08d09c83b89b403sewardj
159d8a725e012a2af94bf265043a08d09c83b89b403sewardj   for(tid = 1; tid < VG_N_THREADS; tid++)
160d8a725e012a2af94bf265043a08d09c83b89b403sewardj      if (VG_(threads)[tid].status == VgTs_Runnable)
161d8a725e012a2af94bf265043a08d09c83b89b403sewardj	 count++;
162d8a725e012a2af94bf265043a08d09c83b89b403sewardj
163d8a725e012a2af94bf265043a08d09c83b89b403sewardj   return count;
164d8a725e012a2af94bf265043a08d09c83b89b403sewardj}
165d8a725e012a2af94bf265043a08d09c83b89b403sewardj
166c7561b931e249acf3768ead77638545b0ccaa8f1njn/* Given an LWP id (ie, real kernel thread id), find the corresponding
167c7561b931e249acf3768ead77638545b0ccaa8f1njn   ThreadId */
1684278172aee9a9db96cc2f9aff9158e3164fa113csewardjThreadId VG_(lwpid_to_vgtid)(Int lwp)
169c7561b931e249acf3768ead77638545b0ccaa8f1njn{
170c7561b931e249acf3768ead77638545b0ccaa8f1njn   ThreadId tid;
171c7561b931e249acf3768ead77638545b0ccaa8f1njn
172c7561b931e249acf3768ead77638545b0ccaa8f1njn   for(tid = 1; tid < VG_N_THREADS; tid++)
173d8a725e012a2af94bf265043a08d09c83b89b403sewardj      if (VG_(threads)[tid].status != VgTs_Empty
174d8a725e012a2af94bf265043a08d09c83b89b403sewardj          && VG_(threads)[tid].os_state.lwpid == lwp)
175c7561b931e249acf3768ead77638545b0ccaa8f1njn	 return tid;
176c7561b931e249acf3768ead77638545b0ccaa8f1njn
177c7561b931e249acf3768ead77638545b0ccaa8f1njn   return VG_INVALID_THREADID;
178c7561b931e249acf3768ead77638545b0ccaa8f1njn}
179c7561b931e249acf3768ead77638545b0ccaa8f1njn
180c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--------------------------------------------------------------------*/
181c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--- end                                                          ---*/
182c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--------------------------------------------------------------------*/
183