1/* Inferior process information for the remote server for GDB. 2 Copyright 2002 3 Free Software Foundation, Inc. 4 5 Contributed by MontaVista Software. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place - Suite 330, 22 Boston, MA 02111-1307, USA. */ 23 24#include <stdlib.h> 25 26#include "server.h" 27 28struct thread_info 29{ 30 struct inferior_list_entry entry; 31 void *target_data; 32 void *regcache_data; 33}; 34 35struct inferior_list all_threads; 36 37struct thread_info *current_inferior; 38 39#define get_thread(inf) ((struct thread_info *)(inf)) 40 41void 42add_inferior_to_list (struct inferior_list *list, 43 struct inferior_list_entry *new_inferior) 44{ 45 new_inferior->next = NULL; 46 if (list->tail != NULL) 47 list->tail->next = new_inferior; 48 else 49 list->head = new_inferior; 50 list->tail = new_inferior; 51} 52 53void 54for_each_inferior (struct inferior_list *list, 55 void (*action) (struct inferior_list_entry *)) 56{ 57 struct inferior_list_entry *cur = list->head, *next; 58 59 while (cur != NULL) 60 { 61 next = cur->next; 62 (*action) (cur); 63 cur = next; 64 } 65} 66 67void 68change_inferior_id (struct inferior_list *list, 69 int new_id) 70{ 71 if (list->head != list->tail) 72 error ("tried to change thread ID after multiple threads are created"); 73 74 list->head->id = new_id; 75} 76 77void 78remove_inferior (struct inferior_list *list, 79 struct inferior_list_entry *entry) 80{ 81 struct inferior_list_entry **cur; 82 83 if (list->head == entry) 84 { 85 list->head = entry->next; 86 if (list->tail == entry) 87 list->tail = list->head; 88 return; 89 } 90 91 cur = &list->head; 92 while (*cur && (*cur)->next != entry) 93 cur = &(*cur)->next; 94 95 if (*cur == NULL) 96 return; 97 98 (*cur)->next = entry->next; 99 100 if (list->tail == entry) 101 list->tail = *cur; 102} 103 104void 105add_thread (int thread_id, void *target_data) 106{ 107 struct thread_info *new_thread 108 = (struct thread_info *) malloc (sizeof (*new_thread)); 109 110 memset (new_thread, 0, sizeof (*new_thread)); 111 112 new_thread->entry.id = thread_id; 113 114 add_inferior_to_list (&all_threads, & new_thread->entry); 115 116 if (current_inferior == NULL) 117 current_inferior = new_thread; 118 119 new_thread->target_data = target_data; 120 set_inferior_regcache_data (new_thread, new_register_cache ()); 121} 122 123static void 124free_one_thread (struct inferior_list_entry *inf) 125{ 126 struct thread_info *thread = get_thread (inf); 127 free_register_cache (inferior_regcache_data (thread)); 128 free (thread); 129} 130 131void 132remove_thread (struct thread_info *thread) 133{ 134 remove_inferior (&all_threads, (struct inferior_list_entry *) thread); 135 free_one_thread (&thread->entry); 136} 137 138void 139clear_inferiors (void) 140{ 141 for_each_inferior (&all_threads, free_one_thread); 142 143 all_threads.head = all_threads.tail = NULL; 144} 145 146struct inferior_list_entry * 147find_inferior (struct inferior_list *list, 148 int (*func) (struct inferior_list_entry *, void *), void *arg) 149{ 150 struct inferior_list_entry *inf = list->head; 151 152 while (inf != NULL) 153 { 154 if ((*func) (inf, arg)) 155 return inf; 156 inf = inf->next; 157 } 158 159 return NULL; 160} 161 162struct inferior_list_entry * 163find_inferior_id (struct inferior_list *list, int id) 164{ 165 struct inferior_list_entry *inf = list->head; 166 167 while (inf != NULL) 168 { 169 if (inf->id == id) 170 return inf; 171 inf = inf->next; 172 } 173 174 return NULL; 175} 176 177void * 178inferior_target_data (struct thread_info *inferior) 179{ 180 return inferior->target_data; 181} 182 183void 184set_inferior_target_data (struct thread_info *inferior, void *data) 185{ 186 inferior->target_data = data; 187} 188 189void * 190inferior_regcache_data (struct thread_info *inferior) 191{ 192 return inferior->regcache_data; 193} 194 195void 196set_inferior_regcache_data (struct thread_info *inferior, void *data) 197{ 198 inferior->regcache_data = data; 199} 200