This commit was generated by cvs2svn to track changes on a CVS vendor
[deliverable/binutils-gdb.git] / gdb / gdbserver / inferiors.c
index f8cbd04d63b17e320df79c97ea5229b3bc8928ec..6fa665f951571bb0bb13f672fd2235b38674b27b 100644 (file)
@@ -1,5 +1,5 @@
 /* Inferior process information for the remote server for GDB.
-   Copyright 2002
+   Copyright (C) 2002, 2005
    Free Software Foundation, Inc.
 
    Contributed by MontaVista Software.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include <stdlib.h>
 
 #include "server.h"
 
-struct inferior_info
+struct thread_info
 {
-  int pid;
+  struct inferior_list_entry entry;
   void *target_data;
-  struct inferior_info *next;
+  void *regcache_data;
+  unsigned int gdb_id;
 };
 
-static struct inferior_info *inferiors;
-struct inferior_info *current_inferior;
-int signal_pid;
+struct inferior_list all_threads;
+
+struct thread_info *current_inferior;
+
+#define get_thread(inf) ((struct thread_info *)(inf))
+
+void
+add_inferior_to_list (struct inferior_list *list,
+                     struct inferior_list_entry *new_inferior)
+{
+  new_inferior->next = NULL;
+  if (list->tail != NULL)
+    list->tail->next = new_inferior;
+  else
+    list->head = new_inferior;
+  list->tail = new_inferior;
+}
+
+void
+for_each_inferior (struct inferior_list *list,
+                  void (*action) (struct inferior_list_entry *))
+{
+  struct inferior_list_entry *cur = list->head, *next;
+
+  while (cur != NULL)
+    {
+      next = cur->next;
+      (*action) (cur);
+      cur = next;
+    }
+}
 
 void
-add_inferior (int pid)
+change_inferior_id (struct inferior_list *list,
+                   unsigned long new_id)
 {
-  struct inferior_info *new_inferior
-    = (struct inferior_info *) malloc (sizeof (*new_inferior));
+  if (list->head != list->tail)
+    error ("tried to change thread ID after multiple threads are created");
 
-  memset (new_inferior, 0, sizeof (*new_inferior));
+  list->head->id = new_id;
+}
 
-  new_inferior->pid = pid;
+void
+remove_inferior (struct inferior_list *list,
+                struct inferior_list_entry *entry)
+{
+  struct inferior_list_entry **cur;
 
-  new_inferior->next = inferiors;
-  inferiors = new_inferior;
+  if (list->head == entry)
+    {
+      list->head = entry->next;
+      if (list->tail == entry)
+       list->tail = list->head;
+      return;
+    }
 
+  cur = &list->head;
+  while (*cur && (*cur)->next != entry)
+    cur = &(*cur)->next;
+
+  if (*cur == NULL)
+    return;
+
+  (*cur)->next = entry->next;
+
+  if (list->tail == entry)
+    list->tail = *cur;
+}
+
+void
+add_thread (unsigned long thread_id, void *target_data, unsigned int gdb_id)
+{
+  struct thread_info *new_thread
+    = (struct thread_info *) malloc (sizeof (*new_thread));
+
+  memset (new_thread, 0, sizeof (*new_thread));
+
+  new_thread->entry.id = thread_id;
+
+  add_inferior_to_list (&all_threads, & new_thread->entry);
+  
   if (current_inferior == NULL)
-    current_inferior = inferiors;
+    current_inferior = new_thread;
+
+  new_thread->target_data = target_data;
+  set_inferior_regcache_data (new_thread, new_register_cache ());
+  new_thread->gdb_id = gdb_id;
+}
+
+unsigned int
+thread_id_to_gdb_id (unsigned long thread_id)
+{
+  struct inferior_list_entry *inf = all_threads.head;
+
+  while (inf != NULL)
+    {
+      struct thread_info *thread = get_thread (inf);
+      if (inf->id == thread_id)
+       return thread->gdb_id;
+      inf = inf->next;
+    }
 
-  if (signal_pid == 0)
-    signal_pid = pid;
+  return 0;
+}
+
+unsigned int
+thread_to_gdb_id (struct thread_info *thread)
+{
+  return thread->gdb_id;
+}
+
+unsigned long
+gdb_id_to_thread_id (unsigned int gdb_id)
+{
+  struct inferior_list_entry *inf = all_threads.head;
+
+  while (inf != NULL)
+    {
+      struct thread_info *thread = get_thread (inf);
+      if (thread->gdb_id == gdb_id)
+       return inf->id;
+      inf = inf->next;
+    }
+
+  return 0;
+}
+
+static void
+free_one_thread (struct inferior_list_entry *inf)
+{
+  struct thread_info *thread = get_thread (inf);
+  free_register_cache (inferior_regcache_data (thread));
+  free (thread);
+}
+
+void
+remove_thread (struct thread_info *thread)
+{
+  remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
+  free_one_thread (&thread->entry);
 }
 
 void
 clear_inferiors (void)
 {
-  struct inferior_info *inf = inferiors, *next_inf;
+  for_each_inferior (&all_threads, free_one_thread);
 
-  while (inf)
+  all_threads.head = all_threads.tail = NULL;
+}
+
+struct inferior_list_entry *
+find_inferior (struct inferior_list *list,
+              int (*func) (struct inferior_list_entry *, void *), void *arg)
+{
+  struct inferior_list_entry *inf = list->head;
+
+  while (inf != NULL)
     {
-      next_inf = inf->next;
+      if ((*func) (inf, arg))
+       return inf;
+      inf = inf->next;
+    }
 
-      if (inf->target_data)
-       free (inf->target_data);
+  return NULL;
+}
+
+struct inferior_list_entry *
+find_inferior_id (struct inferior_list *list, unsigned long id)
+{
+  struct inferior_list_entry *inf = list->head;
 
-      free (inf);
-      inf = next_inf;
+  while (inf != NULL)
+    {
+      if (inf->id == id)
+       return inf;
+      inf = inf->next;
     }
 
-  inferiors = NULL;
+  return NULL;
 }
 
 void *
-inferior_target_data (struct inferior_info *inferior)
+inferior_target_data (struct thread_info *inferior)
 {
   return inferior->target_data;
 }
 
 void
-set_inferior_target_data (struct inferior_info *inferior, void *data)
+set_inferior_target_data (struct thread_info *inferior, void *data)
 {
   inferior->target_data = data;
 }
+
+void *
+inferior_regcache_data (struct thread_info *inferior)
+{
+  return inferior->regcache_data;
+}
+
+void
+set_inferior_regcache_data (struct thread_info *inferior, void *data)
+{
+  inferior->regcache_data = data;
+}
This page took 0.034015 seconds and 4 git commands to generate.