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 28 struct thread_info 29 { 30 struct inferior_list_entry entry; 31 void *target_data; 32 void *regcache_data; 33 }; 34 35 struct inferior_list all_threads; 36 37 struct thread_info *current_inferior; 38 39 #define get_thread(inf) ((struct thread_info *)(inf)) 40 41 void 42 add_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 53 void 54 for_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 67 void 68 change_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 77 void 78 remove_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 104 void 105 add_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 123 static void 124 free_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 131 void 132 remove_thread (struct thread_info *thread) 133 { 134 remove_inferior (&all_threads, (struct inferior_list_entry *) thread); 135 free_one_thread (&thread->entry); 136 } 137 138 void 139 clear_inferiors (void) 140 { 141 for_each_inferior (&all_threads, free_one_thread); 142 143 all_threads.head = all_threads.tail = NULL; 144 } 145 146 struct inferior_list_entry * 147 find_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 162 struct inferior_list_entry * 163 find_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 177 void * 178 inferior_target_data (struct thread_info *inferior) 179 { 180 return inferior->target_data; 181 } 182 183 void 184 set_inferior_target_data (struct thread_info *inferior, void *data) 185 { 186 inferior->target_data = data; 187 } 188 189 void * 190 inferior_regcache_data (struct thread_info *inferior) 191 { 192 return inferior->regcache_data; 193 } 194 195 void 196 set_inferior_regcache_data (struct thread_info *inferior, void *data) 197 { 198 inferior->regcache_data = data; 199 } 200