156160Sru/* Inferior process information for the remote server for GDB.
2146515Sru   Copyright 2002
321495Sjmacd   Free Software Foundation, Inc.
4146515Sru
5114472Sru   Contributed by MontaVista Software.
621495Sjmacd
721495Sjmacd   This file is part of GDB.
821495Sjmacd
921495Sjmacd   This program is free software; you can redistribute it and/or modify
1021495Sjmacd   it under the terms of the GNU General Public License as published by
1121495Sjmacd   the Free Software Foundation; either version 2 of the License, or
1221495Sjmacd   (at your option) any later version.
1321495Sjmacd
1421495Sjmacd   This program is distributed in the hope that it will be useful,
1521495Sjmacd   but WITHOUT ANY WARRANTY; without even the implied warranty of
1621495Sjmacd   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1721495Sjmacd   GNU General Public License for more details.
1821495Sjmacd
1921495Sjmacd   You should have received a copy of the GNU General Public License
2021495Sjmacd   along with this program; if not, write to the Free Software
2121495Sjmacd   Foundation, Inc., 59 Temple Place - Suite 330,
2221495Sjmacd   Boston, MA 02111-1307, USA.  */
2342660Smarkm
2442660Smarkm#include <stdlib.h>
2521495Sjmacd
2621495Sjmacd#include "server.h"
2721495Sjmacd
2821495Sjmacdstruct thread_info
29146515Sru{
30146515Sru  struct inferior_list_entry entry;
31146515Sru  void *target_data;
3221495Sjmacd  void *regcache_data;
33146515Sru};
34146515Sru
35146515Srustruct inferior_list all_threads;
3642660Smarkm
3742660Smarkmstruct thread_info *current_inferior;
3821495Sjmacd
3921495Sjmacd#define get_thread(inf) ((struct thread_info *)(inf))
4021495Sjmacd
4121495Sjmacdvoid
4221495Sjmacdadd_inferior_to_list (struct inferior_list *list,
4321495Sjmacd		      struct inferior_list_entry *new_inferior)
4421495Sjmacd{
4542660Smarkm  new_inferior->next = NULL;
4656160Sru  if (list->tail != NULL)
4756160Sru    list->tail->next = new_inferior;
4856160Sru  else
4956160Sru    list->head = new_inferior;
5056160Sru  list->tail = new_inferior;
5156160Sru}
5256160Sru
5356160Sruvoid
5421495Sjmacdfor_each_inferior (struct inferior_list *list,
5521495Sjmacd		   void (*action) (struct inferior_list_entry *))
5621495Sjmacd{
5756160Sru  struct inferior_list_entry *cur = list->head, *next;
5856160Sru
5956160Sru  while (cur != NULL)
6021495Sjmacd    {
6121495Sjmacd      next = cur->next;
6256160Sru      (*action) (cur);
6356160Sru      cur = next;
6456160Sru    }
6556160Sru}
6621495Sjmacd
6721495Sjmacdvoid
6821495Sjmacdchange_inferior_id (struct inferior_list *list,
6921495Sjmacd		    int new_id)
7021495Sjmacd{
7121495Sjmacd  if (list->head != list->tail)
7221495Sjmacd    error ("tried to change thread ID after multiple threads are created");
7321495Sjmacd
7421495Sjmacd  list->head->id = new_id;
7521495Sjmacd}
7621495Sjmacd
7721495Sjmacdvoid
7821495Sjmacdremove_inferior (struct inferior_list *list,
7921495Sjmacd		 struct inferior_list_entry *entry)
8021495Sjmacd{
8121495Sjmacd  struct inferior_list_entry **cur;
8221495Sjmacd
83146515Sru  if (list->head == entry)
8421495Sjmacd    {
8521495Sjmacd      list->head = entry->next;
8621495Sjmacd      if (list->tail == entry)
8721495Sjmacd	list->tail = list->head;
8821495Sjmacd      return;
8921495Sjmacd    }
9021495Sjmacd
9121495Sjmacd  cur = &list->head;
9221495Sjmacd  while (*cur && (*cur)->next != entry)
9321495Sjmacd    cur = &(*cur)->next;
9421495Sjmacd
9521495Sjmacd  if (*cur == NULL)
9621495Sjmacd    return;
9721495Sjmacd
9821495Sjmacd  (*cur)->next = entry->next;
9942660Smarkm
10021495Sjmacd  if (list->tail == entry)
10121495Sjmacd    list->tail = *cur;
10242660Smarkm}
10342660Smarkm
10456160Sruvoid
10556160Sruadd_thread (int thread_id, void *target_data)
10621495Sjmacd{
10742660Smarkm  struct thread_info *new_thread
10842660Smarkm    = (struct thread_info *) malloc (sizeof (*new_thread));
10956160Sru
11042660Smarkm  memset (new_thread, 0, sizeof (*new_thread));
11156160Sru
11242660Smarkm  new_thread->entry.id = thread_id;
11342660Smarkm
11442660Smarkm  add_inferior_to_list (&all_threads, & new_thread->entry);
11542660Smarkm
11642660Smarkm  if (current_inferior == NULL)
11721495Sjmacd    current_inferior = new_thread;
11856160Sru
11956160Sru  new_thread->target_data = target_data;
12042660Smarkm  set_inferior_regcache_data (new_thread, new_register_cache ());
12142660Smarkm}
12242660Smarkm
12342660Smarkmstatic void
12421495Sjmacdfree_one_thread (struct inferior_list_entry *inf)
12542660Smarkm{
12621495Sjmacd  struct thread_info *thread = get_thread (inf);
12742660Smarkm  free_register_cache (inferior_regcache_data (thread));
12821495Sjmacd  free (thread);
12942660Smarkm}
13042660Smarkm
13142660Smarkmvoid
13242660Smarkmremove_thread (struct thread_info *thread)
13321495Sjmacd{
13442660Smarkm  remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
13542660Smarkm  free_one_thread (&thread->entry);
13656160Sru}
13756160Sru
13856160Sruvoid
13942660Smarkmclear_inferiors (void)
14021495Sjmacd{
14142660Smarkm  for_each_inferior (&all_threads, free_one_thread);
14221495Sjmacd
14321495Sjmacd  all_threads.head = all_threads.tail = NULL;
14442660Smarkm}
14542660Smarkm
146146515Srustruct inferior_list_entry *
14742660Smarkmfind_inferior (struct inferior_list *list,
14842660Smarkm	       int (*func) (struct inferior_list_entry *, void *), void *arg)
14942660Smarkm{
15042660Smarkm  struct inferior_list_entry *inf = list->head;
15142660Smarkm
15242660Smarkm  while (inf != NULL)
15342660Smarkm    {
15421495Sjmacd      if ((*func) (inf, arg))
15521495Sjmacd	return inf;
15621495Sjmacd      inf = inf->next;
15721495Sjmacd    }
15821495Sjmacd
15921495Sjmacd  return NULL;
16021495Sjmacd}
16121495Sjmacd
162146515Srustruct inferior_list_entry *
16321495Sjmacdfind_inferior_id (struct inferior_list *list, int id)
16421495Sjmacd{
16521495Sjmacd  struct inferior_list_entry *inf = list->head;
16621495Sjmacd
16721495Sjmacd  while (inf != NULL)
16893139Sru    {
16993139Sru      if (inf->id == id)
17093139Sru	return inf;
17193139Sru      inf = inf->next;
17293139Sru    }
17321495Sjmacd
17421495Sjmacd  return NULL;
17542660Smarkm}
17621495Sjmacd
17721495Sjmacdvoid *
17821495Sjmacdinferior_target_data (struct thread_info *inferior)
17921495Sjmacd{
18021495Sjmacd  return inferior->target_data;
18121495Sjmacd}
18242660Smarkm
18342660Smarkmvoid
18421495Sjmacdset_inferior_target_data (struct thread_info *inferior, void *data)
18542660Smarkm{
18642660Smarkm  inferior->target_data = data;
18742660Smarkm}
18842660Smarkm
18921495Sjmacdvoid *
19021495Sjmacdinferior_regcache_data (struct thread_info *inferior)
19121495Sjmacd{
19256160Sru  return inferior->regcache_data;
19342660Smarkm}
19421495Sjmacd
19521495Sjmacdvoid
19621495Sjmacdset_inferior_regcache_data (struct thread_info *inferior, void *data)
19721495Sjmacd{
19821495Sjmacd  inferior->regcache_data = data;
19921495Sjmacd}
20021495Sjmacd