Sun Aug 1 22:58:18 1993 Stu Grossman (grossman at cygnus.com)
[deliverable/binutils-gdb.git] / gdb / thread.c
CommitLineData
25286543
SG
1/* for separate threads within the inferior process, for GDB.
2 Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
3
4GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5WARRANTY. No author or distributor accepts responsibility to anyone
6for the consequences of using it or for whether it serves any
7particular purpose or works at all, unless he says so in writing.
8Refer to the GDB General Public License for full details.
9
10Everyone is granted permission to copy, modify and redistribute GDB,
11but only under the conditions described in the GDB General Public
12License. A copy of this license is supposed to have been given to you
13along with GDB so you can know your rights and responsibilities. It
14should be in a file named COPYING. Among other things, the copyright
15notice and this notice must be preserved on all copies.
16
17In other words, go ahead and share GDB, but don't try to stop
18anyone else from sharing it farther. Help stamp out software hoarding!
19*/
20
21#include "defs.h"
22#include "symtab.h"
23#include "frame.h"
24#include "inferior.h"
25#include "environ.h"
26#include "value.h"
27#include "target.h"
28#include "thread.h"
29
30#include <sys/types.h>
31#include <signal.h>
32
33/*#include "lynxos-core.h"*/
34
35struct thread_info
36{
37 struct thread_info *next;
38 int pid; /* Actual process id */
39 int num; /* Convenient handle */
40};
41
42static struct thread_info *thread_list = NULL;
43static int highest_thread_num;
44
45static void thread_info PARAMS ((void));
46
47static void thread_command PARAMS ((char * tidstr, int from_tty));
48
49static void prune_threads PARAMS ((void));
50
51static void thread_switch PARAMS ((int pid));
52
53void
54init_thread_list ()
55{
56 struct thread_info *tp, *tpnext;
57
58 if (!thread_list)
59 return;
60
61 for (tp = thread_list; tp; tp = tpnext)
62 {
63 tpnext = tp->next;
64 free (tp);
65 }
66
67 thread_list = NULL;
68 highest_thread_num = 0;
69}
70
71void
72add_thread (pid)
73 int pid;
74{
75 struct thread_info *tp;
76
77 tp = xmalloc (sizeof (struct thread_info));
78
79 tp->pid = pid;
80 tp->num = ++highest_thread_num;
81 tp->next = thread_list;
82 thread_list = tp;
83}
84
85static struct thread_info *
86find_thread_id (num)
87 int num;
88{
89 struct thread_info *tp;
90
91 for (tp = thread_list; tp; tp = tp->next)
92 if (tp->num == num)
93 return tp;
94
95 return NULL;
96}
97
98int
99in_thread_list (pid)
100 int pid;
101{
102 struct thread_info *tp;
103
104 for (tp = thread_list; tp; tp = tp->next)
105 if (tp->pid == pid)
106 return 1;
107
108 return 0; /* Never heard of 'im */
109}
110
111#if 0
112void
113bfd_get_core_threads (abfd)
114 bfd *abfd;
115{
116 int i;
117
118 inferior_pid = BUILDPID (inferior_pid, core_thread (abfd)->pid);
119 for (i = 0; i < core_pss (abfd).threadcnt; i++)
120 add_thread (core_thread (abfd)[i].pid);
121}
122#endif
123
124static void
125prune_threads ()
126{
127 struct thread_info *tp, *tpprev;
128
129 tpprev = 0;
130
131 for (tp = thread_list; tp; tp = tp->next)
132 if (tp->pid == -1)
133 {
134 if (tpprev)
135 tpprev->next = tp->next;
136 else
137 thread_list = NULL;
138
139 free (tp);
140 }
141 else
142 tpprev = tp;
143}
144
145/* Print information about currently known threads */
146
147static void
148info_threads_command (arg, from_tty)
149 char *arg;
150 int from_tty;
151{
152 struct thread_info *tp;
153 int current_pid = inferior_pid;
154
155 for (tp = thread_list; tp; tp = tp->next)
156 {
157 if (target_has_execution
158 && kill (tp->pid, 0) == -1)
159 {
160 tp->pid == -1; /* Mark it as dead */
161 continue;
162 }
163
164 if (tp->pid == current_pid)
165 printf_filtered ("* ");
166 else
167 printf_filtered (" ");
168
169 printf_filtered ("%d %s ", tp->num, target_pid_to_str (tp->pid));
170
171 thread_switch (tp->pid);
172 print_stack_frame (selected_frame, -1, 0);
173 }
174
175 thread_switch (current_pid);
176 prune_threads ();
177}
178
179/* Switch from one thread to another. */
180
181void
182thread_switch (pid)
183 int pid;
184{
185 if (pid == inferior_pid)
186 return;
187
188 inferior_pid = pid;
189 pc_changed = 0;
190 flush_cached_frames ();
191 registers_changed ();
192 stop_pc = read_pc();
193 set_current_frame (create_new_frame (read_fp (), stop_pc));
194 stop_frame_address = FRAME_FP (get_current_frame ());
195 select_frame (get_current_frame (), 0);
196}
197
198static void
199thread_command (tidstr, from_tty)
200 char *tidstr;
201 int from_tty;
202{
203 int num;
204 struct thread_info *tp;
205
206 if (!tidstr)
207 error ("Please specify a thread ID. Use the \"info threads\" command to\n\
208see the IDs of currently known threads.");
209
210
211 num = atoi (tidstr);
212
213 tp = find_thread_id (num);
214
215 if (!tp)
216 error ("Thread ID %d not known. Use the \"info threads\" command to\n\
217see the IDs of currently known threads.", num);
218
219 thread_switch (tp->pid);
220
221 printf_filtered ("[Switching to %s]\n", target_pid_to_str (inferior_pid));
222 print_stack_frame (selected_frame, selected_frame_level, 1);
223}
224
225void
226_initialize_thread ()
227{
228 add_info ("threads", info_threads_command,
229 "IDs of currently known threads.");
230 add_com ("thread", class_info, thread_command,
231 "Use this command to switch between threads.\n\
232The new thread ID must be currently known.");
233}
This page took 0.035493 seconds and 4 git commands to generate.