First cut at sanitization, doc files, &c for gas/binutils releases
[deliverable/binutils-gdb.git] / gdb / thread.c
CommitLineData
da0baf42
SG
1/* Multi-process/thread control for GDB, the GNU debugger.
2 Copyright 1986, 1987, 1988, 1993
3
4 Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
5 Free Software Foundation, Inc.
6
7This file is part of GDB.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25286543
SG
22
23#include "defs.h"
24#include "symtab.h"
25#include "frame.h"
26#include "inferior.h"
27#include "environ.h"
28#include "value.h"
29#include "target.h"
30#include "thread.h"
46c28185 31#include "command.h"
25286543
SG
32
33#include <sys/types.h>
34#include <signal.h>
35
36/*#include "lynxos-core.h"*/
37
38struct thread_info
39{
40 struct thread_info *next;
41 int pid; /* Actual process id */
42 int num; /* Convenient handle */
43};
44
45static struct thread_info *thread_list = NULL;
46static int highest_thread_num;
47
25286543
SG
48static void thread_command PARAMS ((char * tidstr, int from_tty));
49
50static void prune_threads PARAMS ((void));
51
52static void thread_switch PARAMS ((int pid));
53
de43d7d0
SG
54static struct thread_info * find_thread_id PARAMS ((int num));
55
25286543
SG
56void
57init_thread_list ()
58{
59 struct thread_info *tp, *tpnext;
60
61 if (!thread_list)
62 return;
63
64 for (tp = thread_list; tp; tp = tpnext)
65 {
66 tpnext = tp->next;
67 free (tp);
68 }
69
70 thread_list = NULL;
71 highest_thread_num = 0;
72}
73
74void
75add_thread (pid)
76 int pid;
77{
78 struct thread_info *tp;
79
3082244d 80 tp = (struct thread_info *) xmalloc (sizeof (struct thread_info));
25286543
SG
81
82 tp->pid = pid;
83 tp->num = ++highest_thread_num;
84 tp->next = thread_list;
85 thread_list = tp;
86}
87
88static struct thread_info *
89find_thread_id (num)
90 int num;
91{
92 struct thread_info *tp;
93
94 for (tp = thread_list; tp; tp = tp->next)
95 if (tp->num == num)
96 return tp;
97
98 return NULL;
99}
100
de43d7d0
SG
101int
102valid_thread_id (num)
103 int num;
104{
105 struct thread_info *tp;
106
107 for (tp = thread_list; tp; tp = tp->next)
108 if (tp->num == num)
109 return 1;
110
111 return 0;
112}
113
114int
115pid_to_thread_id (pid)
116 int pid;
117{
118 struct thread_info *tp;
119
120 for (tp = thread_list; tp; tp = tp->next)
121 if (tp->pid == pid)
122 return tp->num;
123
124 return 0;
125}
126
25286543
SG
127int
128in_thread_list (pid)
129 int pid;
130{
131 struct thread_info *tp;
132
133 for (tp = thread_list; tp; tp = tp->next)
134 if (tp->pid == pid)
135 return 1;
136
137 return 0; /* Never heard of 'im */
138}
139
25286543
SG
140static void
141prune_threads ()
142{
143 struct thread_info *tp, *tpprev;
144
145 tpprev = 0;
146
147 for (tp = thread_list; tp; tp = tp->next)
148 if (tp->pid == -1)
149 {
150 if (tpprev)
151 tpprev->next = tp->next;
152 else
153 thread_list = NULL;
154
155 free (tp);
156 }
157 else
158 tpprev = tp;
159}
160
161/* Print information about currently known threads */
162
163static void
164info_threads_command (arg, from_tty)
165 char *arg;
166 int from_tty;
167{
168 struct thread_info *tp;
169 int current_pid = inferior_pid;
170
171 for (tp = thread_list; tp; tp = tp->next)
172 {
173 if (target_has_execution
174 && kill (tp->pid, 0) == -1)
175 {
46c28185 176 tp->pid = -1; /* Mark it as dead */
25286543
SG
177 continue;
178 }
179
180 if (tp->pid == current_pid)
181 printf_filtered ("* ");
182 else
183 printf_filtered (" ");
184
185 printf_filtered ("%d %s ", tp->num, target_pid_to_str (tp->pid));
186
187 thread_switch (tp->pid);
188 print_stack_frame (selected_frame, -1, 0);
189 }
190
191 thread_switch (current_pid);
192 prune_threads ();
193}
194
195/* Switch from one thread to another. */
196
3082244d 197static void
25286543
SG
198thread_switch (pid)
199 int pid;
200{
201 if (pid == inferior_pid)
202 return;
203
204 inferior_pid = pid;
25286543
SG
205 flush_cached_frames ();
206 registers_changed ();
207 stop_pc = read_pc();
208 set_current_frame (create_new_frame (read_fp (), stop_pc));
209 stop_frame_address = FRAME_FP (get_current_frame ());
210 select_frame (get_current_frame (), 0);
211}
212
213static void
214thread_command (tidstr, from_tty)
215 char *tidstr;
216 int from_tty;
217{
218 int num;
219 struct thread_info *tp;
220
221 if (!tidstr)
222 error ("Please specify a thread ID. Use the \"info threads\" command to\n\
223see the IDs of currently known threads.");
224
225
226 num = atoi (tidstr);
227
228 tp = find_thread_id (num);
229
230 if (!tp)
231 error ("Thread ID %d not known. Use the \"info threads\" command to\n\
232see the IDs of currently known threads.", num);
233
234 thread_switch (tp->pid);
235
236 printf_filtered ("[Switching to %s]\n", target_pid_to_str (inferior_pid));
237 print_stack_frame (selected_frame, selected_frame_level, 1);
238}
239
240void
241_initialize_thread ()
242{
243 add_info ("threads", info_threads_command,
244 "IDs of currently known threads.");
245 add_com ("thread", class_info, thread_command,
246 "Use this command to switch between threads.\n\
247The new thread ID must be currently known.");
248}
This page took 0.082493 seconds and 4 git commands to generate.