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