1130803Smarcel/* Inferior process information for the remote server for GDB.
2130803Smarcel   Copyright 2002
3130803Smarcel   Free Software Foundation, Inc.
4130803Smarcel
5130803Smarcel   Contributed by MontaVista Software.
6130803Smarcel
7130803Smarcel   This file is part of GDB.
8130803Smarcel
9130803Smarcel   This program is free software; you can redistribute it and/or modify
10130803Smarcel   it under the terms of the GNU General Public License as published by
11130803Smarcel   the Free Software Foundation; either version 2 of the License, or
12130803Smarcel   (at your option) any later version.
13130803Smarcel
14130803Smarcel   This program is distributed in the hope that it will be useful,
15130803Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
16130803Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17130803Smarcel   GNU General Public License for more details.
18130803Smarcel
19130803Smarcel   You should have received a copy of the GNU General Public License
20130803Smarcel   along with this program; if not, write to the Free Software
21130803Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
22130803Smarcel   Boston, MA 02111-1307, USA.  */
23130803Smarcel
24130803Smarcel#include <stdlib.h>
25130803Smarcel
26130803Smarcel#include "server.h"
27130803Smarcel
28130803Smarcelstruct thread_info
29130803Smarcel{
30130803Smarcel  struct inferior_list_entry entry;
31130803Smarcel  void *target_data;
32130803Smarcel  void *regcache_data;
33130803Smarcel};
34130803Smarcel
35130803Smarcelstruct inferior_list all_threads;
36130803Smarcel
37130803Smarcelstruct thread_info *current_inferior;
38130803Smarcel
39130803Smarcel#define get_thread(inf) ((struct thread_info *)(inf))
40130803Smarcel
41130803Smarcelvoid
42130803Smarceladd_inferior_to_list (struct inferior_list *list,
43130803Smarcel		      struct inferior_list_entry *new_inferior)
44130803Smarcel{
45130803Smarcel  new_inferior->next = NULL;
46130803Smarcel  if (list->tail != NULL)
47130803Smarcel    list->tail->next = new_inferior;
48130803Smarcel  else
49130803Smarcel    list->head = new_inferior;
50130803Smarcel  list->tail = new_inferior;
51130803Smarcel}
52130803Smarcel
53130803Smarcelvoid
54130803Smarcelfor_each_inferior (struct inferior_list *list,
55130803Smarcel		   void (*action) (struct inferior_list_entry *))
56130803Smarcel{
57130803Smarcel  struct inferior_list_entry *cur = list->head, *next;
58130803Smarcel
59130803Smarcel  while (cur != NULL)
60130803Smarcel    {
61130803Smarcel      next = cur->next;
62130803Smarcel      (*action) (cur);
63130803Smarcel      cur = next;
64130803Smarcel    }
65130803Smarcel}
66130803Smarcel
67130803Smarcelvoid
68130803Smarcelchange_inferior_id (struct inferior_list *list,
69130803Smarcel		    int new_id)
70130803Smarcel{
71130803Smarcel  if (list->head != list->tail)
72130803Smarcel    error ("tried to change thread ID after multiple threads are created");
73130803Smarcel
74130803Smarcel  list->head->id = new_id;
75130803Smarcel}
76130803Smarcel
77130803Smarcelvoid
78130803Smarcelremove_inferior (struct inferior_list *list,
79130803Smarcel		 struct inferior_list_entry *entry)
80130803Smarcel{
81130803Smarcel  struct inferior_list_entry **cur;
82130803Smarcel
83130803Smarcel  if (list->head == entry)
84130803Smarcel    {
85130803Smarcel      list->head = entry->next;
86130803Smarcel      if (list->tail == entry)
87130803Smarcel	list->tail = list->head;
88130803Smarcel      return;
89130803Smarcel    }
90130803Smarcel
91130803Smarcel  cur = &list->head;
92130803Smarcel  while (*cur && (*cur)->next != entry)
93130803Smarcel    cur = &(*cur)->next;
94130803Smarcel
95130803Smarcel  if (*cur == NULL)
96130803Smarcel    return;
97130803Smarcel
98130803Smarcel  (*cur)->next = entry->next;
99130803Smarcel
100130803Smarcel  if (list->tail == entry)
101130803Smarcel    list->tail = *cur;
102130803Smarcel}
103130803Smarcel
104130803Smarcelvoid
105130803Smarceladd_thread (int thread_id, void *target_data)
106130803Smarcel{
107130803Smarcel  struct thread_info *new_thread
108130803Smarcel    = (struct thread_info *) malloc (sizeof (*new_thread));
109130803Smarcel
110130803Smarcel  memset (new_thread, 0, sizeof (*new_thread));
111130803Smarcel
112130803Smarcel  new_thread->entry.id = thread_id;
113130803Smarcel
114130803Smarcel  add_inferior_to_list (&all_threads, & new_thread->entry);
115130803Smarcel
116130803Smarcel  if (current_inferior == NULL)
117130803Smarcel    current_inferior = new_thread;
118130803Smarcel
119130803Smarcel  new_thread->target_data = target_data;
120130803Smarcel  set_inferior_regcache_data (new_thread, new_register_cache ());
121130803Smarcel}
122130803Smarcel
123130803Smarcelstatic void
124130803Smarcelfree_one_thread (struct inferior_list_entry *inf)
125130803Smarcel{
126130803Smarcel  struct thread_info *thread = get_thread (inf);
127130803Smarcel  free_register_cache (inferior_regcache_data (thread));
128130803Smarcel  free (thread);
129130803Smarcel}
130130803Smarcel
131130803Smarcelvoid
132130803Smarcelremove_thread (struct thread_info *thread)
133130803Smarcel{
134130803Smarcel  remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
135130803Smarcel  free_one_thread (&thread->entry);
136130803Smarcel}
137130803Smarcel
138130803Smarcelvoid
139130803Smarcelclear_inferiors (void)
140130803Smarcel{
141130803Smarcel  for_each_inferior (&all_threads, free_one_thread);
142130803Smarcel
143130803Smarcel  all_threads.head = all_threads.tail = NULL;
144130803Smarcel}
145130803Smarcel
146130803Smarcelstruct inferior_list_entry *
147130803Smarcelfind_inferior (struct inferior_list *list,
148130803Smarcel	       int (*func) (struct inferior_list_entry *, void *), void *arg)
149130803Smarcel{
150130803Smarcel  struct inferior_list_entry *inf = list->head;
151130803Smarcel
152130803Smarcel  while (inf != NULL)
153130803Smarcel    {
154130803Smarcel      if ((*func) (inf, arg))
155130803Smarcel	return inf;
156130803Smarcel      inf = inf->next;
157130803Smarcel    }
158130803Smarcel
159130803Smarcel  return NULL;
160130803Smarcel}
161130803Smarcel
162130803Smarcelstruct inferior_list_entry *
163130803Smarcelfind_inferior_id (struct inferior_list *list, int id)
164130803Smarcel{
165130803Smarcel  struct inferior_list_entry *inf = list->head;
166130803Smarcel
167130803Smarcel  while (inf != NULL)
168130803Smarcel    {
169130803Smarcel      if (inf->id == id)
170130803Smarcel	return inf;
171130803Smarcel      inf = inf->next;
172130803Smarcel    }
173130803Smarcel
174130803Smarcel  return NULL;
175130803Smarcel}
176130803Smarcel
177130803Smarcelvoid *
178130803Smarcelinferior_target_data (struct thread_info *inferior)
179130803Smarcel{
180130803Smarcel  return inferior->target_data;
181130803Smarcel}
182130803Smarcel
183130803Smarcelvoid
184130803Smarcelset_inferior_target_data (struct thread_info *inferior, void *data)
185130803Smarcel{
186130803Smarcel  inferior->target_data = data;
187130803Smarcel}
188130803Smarcel
189130803Smarcelvoid *
190130803Smarcelinferior_regcache_data (struct thread_info *inferior)
191130803Smarcel{
192130803Smarcel  return inferior->regcache_data;
193130803Smarcel}
194130803Smarcel
195130803Smarcelvoid
196130803Smarcelset_inferior_regcache_data (struct thread_info *inferior, void *data)
197130803Smarcel{
198130803Smarcel  inferior->regcache_data = data;
199130803Smarcel}
200