X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fthread.c;h=63e55a4bab4982f7eae90322bf600ecaaec16e6a;hb=4fa62494657f9b422edd7049c7207bd6c6849c3f;hp=a1617f2390be7e914d23d215ac21fdbc017ab5b4;hpb=88fc996f5819bf526d17f6f273135943ac41ab38;p=binutils-gdb.git diff --git a/gdb/thread.c b/gdb/thread.c index a1617f2390b..63e55a4bab4 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -75,7 +75,7 @@ enum thread_state struct thread_info* inferior_thread (void) { - struct thread_info *tp = find_thread_pid (inferior_ptid); + struct thread_info *tp = find_thread_ptid (inferior_ptid); gdb_assert (tp); return tp; } @@ -141,12 +141,34 @@ init_thread_list (void) thread_list = NULL; } +/* Allocate a new thread with target id PTID and add it to the thread + list. */ + +static struct thread_info * +new_thread (ptid_t ptid) +{ + struct thread_info *tp; + + tp = xcalloc (1, sizeof (*tp)); + + tp->ptid = ptid; + tp->num = ++highest_thread_num; + tp->next = thread_list; + thread_list = tp; + + /* Nothing to follow yet. */ + tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS; + tp->state_ = THREAD_STOPPED; + + return tp; +} + struct thread_info * add_thread_silent (ptid_t ptid) { struct thread_info *tp; - tp = find_thread_pid (ptid); + tp = find_thread_ptid (ptid); if (tp) /* Found an old thread with the same id. It has to be dead, otherwise we wouldn't be adding a new thread with the same id. @@ -162,12 +184,7 @@ add_thread_silent (ptid_t ptid) if (ptid_equal (inferior_ptid, ptid)) { - tp = xmalloc (sizeof (*tp)); - memset (tp, 0, sizeof (*tp)); - tp->ptid = minus_one_ptid; - tp->num = ++highest_thread_num; - tp->next = thread_list; - thread_list = tp; + tp = new_thread (ptid); /* Make switch_to_thread not read from the thread. */ tp->state_ = THREAD_EXITED; @@ -191,13 +208,7 @@ add_thread_silent (ptid_t ptid) delete_thread (ptid); } - tp = (struct thread_info *) xmalloc (sizeof (*tp)); - memset (tp, 0, sizeof (*tp)); - tp->ptid = ptid; - tp->num = ++highest_thread_num; - tp->next = thread_list; - thread_list = tp; - + tp = new_thread (ptid); observer_notify_new_thread (tp); return tp; @@ -302,7 +313,7 @@ find_thread_id (int num) /* Find a thread_info by matching PTID. */ struct thread_info * -find_thread_pid (ptid_t ptid) +find_thread_ptid (ptid_t ptid) { struct thread_info *tp; @@ -401,6 +412,22 @@ in_thread_list (ptid_t ptid) return 0; /* Never heard of 'im */ } +/* Finds the first thread of the inferior given by PID. If PID is -1, + return the first thread in the list. */ + +struct thread_info * +first_thread_of_process (int pid) +{ + struct thread_info *tp, *ret = NULL; + + for (tp = thread_list; tp; tp = tp->next) + if (pid == -1 || ptid_get_pid (tp->ptid) == pid) + if (ret == NULL || tp->num < ret->num) + ret = tp; + + return ret; +} + /* Print a list of thread ids currently known, and the total number of threads. To be used from within catch_errors. */ static int @@ -483,7 +510,7 @@ thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid) inf = find_inferior_pid (ptid_get_pid (old_ptid)); inf->pid = ptid_get_pid (new_ptid); - tp = find_thread_pid (old_ptid); + tp = find_thread_ptid (old_ptid); tp->ptid = new_ptid; observer_notify_thread_ptid_changed (old_ptid, new_ptid); @@ -493,28 +520,30 @@ void set_running (ptid_t ptid, int running) { struct thread_info *tp; + int all = ptid_equal (ptid, minus_one_ptid); /* We try not to notify the observer if no thread has actually changed the running state -- merely to reduce the number of messages to frontend. Frontend is supposed to handle multiple *running just fine. */ - if (PIDGET (ptid) == -1) + if (all || ptid_is_pid (ptid)) { int any_started = 0; for (tp = thread_list; tp; tp = tp->next) - { - if (tp->state_ == THREAD_EXITED) - continue; - if (running && tp->state_ == THREAD_STOPPED) - any_started = 1; - tp->state_ = running ? THREAD_RUNNING : THREAD_STOPPED; - } + if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid)) + { + if (tp->state_ == THREAD_EXITED) + continue; + if (running && tp->state_ == THREAD_STOPPED) + any_started = 1; + tp->state_ = running ? THREAD_RUNNING : THREAD_STOPPED; + } if (any_started) observer_notify_target_resumed (ptid); } else { int started = 0; - tp = find_thread_pid (ptid); + tp = find_thread_ptid (ptid); gdb_assert (tp); gdb_assert (tp->state_ != THREAD_EXITED); if (running && tp->state_ == THREAD_STOPPED) @@ -533,7 +562,7 @@ is_thread_state (ptid_t ptid, enum thread_state state) if (!target_has_execution) return 0; - tp = find_thread_pid (ptid); + tp = find_thread_ptid (ptid); gdb_assert (tp); return tp->state_ == state; } @@ -591,7 +620,7 @@ is_executing (ptid_t ptid) if (!target_has_execution) return 0; - tp = find_thread_pid (ptid); + tp = find_thread_ptid (ptid); gdb_assert (tp); return tp->executing_; } @@ -600,15 +629,17 @@ void set_executing (ptid_t ptid, int executing) { struct thread_info *tp; + int all = ptid_equal (ptid, minus_one_ptid); - if (PIDGET (ptid) == -1) + if (all || ptid_is_pid (ptid)) { for (tp = thread_list; tp; tp = tp->next) - tp->executing_ = executing; + if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid)) + tp->executing_ = executing; } else { - tp = find_thread_pid (ptid); + tp = find_thread_ptid (ptid); gdb_assert (tp); tp->executing_ = executing; } @@ -628,7 +659,7 @@ set_stop_requested (ptid_t ptid, int stop) } else { - tp = find_thread_pid (ptid); + tp = find_thread_ptid (ptid); gdb_assert (tp); tp->stop_requested = stop; } @@ -664,7 +695,7 @@ finish_thread_state (ptid_t ptid) } else { - tp = find_thread_pid (ptid); + tp = find_thread_ptid (ptid); gdb_assert (tp); if (tp->state_ != THREAD_EXITED) { @@ -836,7 +867,7 @@ switch_to_thread (ptid_t ptid) if (!ptid_equal (inferior_ptid, null_ptid) && !is_exited (ptid) && !is_executing (ptid)) - stop_pc = read_pc (); + stop_pc = regcache_read_pc (get_thread_regcache (ptid)); else stop_pc = ~(CORE_ADDR) 0; } @@ -917,7 +948,7 @@ do_restore_current_thread_cleanup (void *arg) struct thread_info *tp; struct current_thread_cleanup *old = arg; - tp = find_thread_pid (old->inferior_ptid); + tp = find_thread_ptid (old->inferior_ptid); /* If the previously selected thread belonged to a process that has in the mean time been deleted (due to normal exit, detach, etc.), @@ -946,7 +977,7 @@ restore_current_thread_cleanup_dtor (void *arg) { struct current_thread_cleanup *old = arg; struct thread_info *tp; - tp = find_thread_pid (old->inferior_ptid); + tp = find_thread_ptid (old->inferior_ptid); if (tp) tp->refcount--; xfree (old); @@ -976,7 +1007,7 @@ make_cleanup_restore_current_thread (void) old->selected_frame_id = get_frame_id (frame); old->selected_frame_level = frame_relative_level (frame); - tp = find_thread_pid (inferior_ptid); + tp = find_thread_ptid (inferior_ptid); if (tp) tp->refcount++; }