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