C++fy thread_apply_all_command
This eliminates a couple cleanups. gdb/ChangeLog: 2017-04-13 Pedro Alves <palves@redhat.com> * thread.c: Include <algorithm>. (thread_array_cleanup): Delete. (scoped_inc_dec_ref): New class. (live_threads_count): New function. (set_thread_refcount): Delete. (tp_array_compar_ascending): Now a bool. (tp_array_compar): Convert to a std::sort comparison function. (thread_apply_all_command): Use std::vector and scoped_inc_dec_ref and live_threads_count.
This commit is contained in:
parent
2a00d7ce26
commit
c6609450b3
|
@ -1,3 +1,15 @@
|
||||||
|
2017-04-13 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
* thread.c: Include <algorithm>.
|
||||||
|
(thread_array_cleanup): Delete.
|
||||||
|
(scoped_inc_dec_ref): New class.
|
||||||
|
(live_threads_count): New function.
|
||||||
|
(set_thread_refcount): Delete.
|
||||||
|
(tp_array_compar_ascending): Now a bool.
|
||||||
|
(tp_array_compar): Convert to a std::sort comparison function.
|
||||||
|
(thread_apply_all_command): Use std::vector and scoped_inc_dec_ref
|
||||||
|
and live_threads_count.
|
||||||
|
|
||||||
2017-04-13 Pedro Alves <palves@redhat.com>
|
2017-04-13 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* infrun.c (follow_fork_inferior): Also switch the current
|
* infrun.c (follow_fork_inferior): Also switch the current
|
||||||
|
|
143
gdb/thread.c
143
gdb/thread.c
|
@ -44,6 +44,7 @@
|
||||||
#include "cli/cli-utils.h"
|
#include "cli/cli-utils.h"
|
||||||
#include "thread-fsm.h"
|
#include "thread-fsm.h"
|
||||||
#include "tid-parse.h"
|
#include "tid-parse.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
/* Definition of struct thread_info exported to gdbthread.h. */
|
/* Definition of struct thread_info exported to gdbthread.h. */
|
||||||
|
|
||||||
|
@ -69,16 +70,27 @@ static void info_threads_command (char *, int);
|
||||||
static void thread_apply_command (char *, int);
|
static void thread_apply_command (char *, int);
|
||||||
static void restore_current_thread (ptid_t);
|
static void restore_current_thread (ptid_t);
|
||||||
|
|
||||||
/* Data to cleanup thread array. */
|
/* RAII type used to increase / decrease the refcount of each thread
|
||||||
|
in a given list of threads. */
|
||||||
|
|
||||||
struct thread_array_cleanup
|
class scoped_inc_dec_ref
|
||||||
{
|
{
|
||||||
/* Array of thread pointers used to set
|
public:
|
||||||
reference count. */
|
explicit scoped_inc_dec_ref (const std::vector<thread_info *> &thrds)
|
||||||
struct thread_info **tp_array;
|
: m_thrds (thrds)
|
||||||
|
{
|
||||||
|
for (thread_info *thr : m_thrds)
|
||||||
|
thr->incref ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Thread count in the array. */
|
~scoped_inc_dec_ref ()
|
||||||
int count;
|
{
|
||||||
|
for (thread_info *thr : m_thrds)
|
||||||
|
thr->decref ();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::vector<thread_info *> &m_thrds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -565,6 +577,20 @@ thread_count (void)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the number of non-exited threads in the thread list. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
live_threads_count (void)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
|
ALL_NON_EXITED_THREADS (tp)
|
||||||
|
++result;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
valid_global_thread_id (int global_id)
|
valid_global_thread_id (int global_id)
|
||||||
{
|
{
|
||||||
|
@ -1605,19 +1631,6 @@ restore_current_thread_cleanup_dtor (void *arg)
|
||||||
xfree (old);
|
xfree (old);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the thread reference count. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_thread_refcount (void *data)
|
|
||||||
{
|
|
||||||
int k;
|
|
||||||
struct thread_array_cleanup *ta_cleanup
|
|
||||||
= (struct thread_array_cleanup *) data;
|
|
||||||
|
|
||||||
for (k = 0; k != ta_cleanup->count; k++)
|
|
||||||
ta_cleanup->tp_array[k]->decref ();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cleanup *
|
struct cleanup *
|
||||||
make_cleanup_restore_current_thread (void)
|
make_cleanup_restore_current_thread (void)
|
||||||
{
|
{
|
||||||
|
@ -1693,30 +1706,30 @@ print_thread_id (struct thread_info *thr)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If non-zero tp_array_compar should sort in ascending order, otherwise in
|
/* If true, tp_array_compar should sort in ascending order, otherwise
|
||||||
descending order. */
|
in descending order. */
|
||||||
|
|
||||||
static int tp_array_compar_ascending;
|
static bool tp_array_compar_ascending;
|
||||||
|
|
||||||
/* Sort an array for struct thread_info pointers by thread ID (first
|
/* Sort an array for struct thread_info pointers by thread ID (first
|
||||||
by inferior number, and then by per-inferior thread number). The
|
by inferior number, and then by per-inferior thread number). The
|
||||||
order is determined by TP_ARRAY_COMPAR_ASCENDING. */
|
order is determined by TP_ARRAY_COMPAR_ASCENDING. */
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
tp_array_compar (const void *ap_voidp, const void *bp_voidp)
|
tp_array_compar (const thread_info *a, const thread_info *b)
|
||||||
{
|
{
|
||||||
const struct thread_info *a = *(const struct thread_info * const *) ap_voidp;
|
|
||||||
const struct thread_info *b = *(const struct thread_info * const *) bp_voidp;
|
|
||||||
|
|
||||||
if (a->inf->num != b->inf->num)
|
if (a->inf->num != b->inf->num)
|
||||||
{
|
{
|
||||||
return (((a->inf->num > b->inf->num) - (a->inf->num < b->inf->num))
|
if (tp_array_compar_ascending)
|
||||||
* (tp_array_compar_ascending ? +1 : -1));
|
return a->inf->num < b->inf->num;
|
||||||
|
else
|
||||||
|
return a->inf->num > b->inf->num;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (((a->per_inf_num > b->per_inf_num)
|
if (tp_array_compar_ascending)
|
||||||
- (a->per_inf_num < b->per_inf_num))
|
return (a->per_inf_num < b->per_inf_num);
|
||||||
* (tp_array_compar_ascending ? +1 : -1));
|
else
|
||||||
|
return (a->per_inf_num > b->per_inf_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply a GDB command to a list of threads. List syntax is a whitespace
|
/* Apply a GDB command to a list of threads. List syntax is a whitespace
|
||||||
|
@ -1732,15 +1745,13 @@ thread_apply_all_command (char *cmd, int from_tty)
|
||||||
{
|
{
|
||||||
struct cleanup *old_chain;
|
struct cleanup *old_chain;
|
||||||
char *saved_cmd;
|
char *saved_cmd;
|
||||||
int tc;
|
|
||||||
struct thread_array_cleanup ta_cleanup;
|
|
||||||
|
|
||||||
tp_array_compar_ascending = 0;
|
tp_array_compar_ascending = false;
|
||||||
if (cmd != NULL
|
if (cmd != NULL
|
||||||
&& check_for_argument (&cmd, "-ascending", strlen ("-ascending")))
|
&& check_for_argument (&cmd, "-ascending", strlen ("-ascending")))
|
||||||
{
|
{
|
||||||
cmd = skip_spaces (cmd);
|
cmd = skip_spaces (cmd);
|
||||||
tp_array_compar_ascending = 1;
|
tp_array_compar_ascending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == NULL || *cmd == '\000')
|
if (cmd == NULL || *cmd == '\000')
|
||||||
|
@ -1755,42 +1766,40 @@ thread_apply_all_command (char *cmd, int from_tty)
|
||||||
saved_cmd = xstrdup (cmd);
|
saved_cmd = xstrdup (cmd);
|
||||||
make_cleanup (xfree, saved_cmd);
|
make_cleanup (xfree, saved_cmd);
|
||||||
|
|
||||||
/* Note this includes exited threads. */
|
int tc = live_threads_count ();
|
||||||
tc = thread_count ();
|
|
||||||
if (tc != 0)
|
if (tc != 0)
|
||||||
{
|
{
|
||||||
struct thread_info **tp_array;
|
/* Save a copy of the thread list and increment each thread's
|
||||||
struct thread_info *tp;
|
refcount while executing the command in the context of each
|
||||||
int i = 0, k;
|
thread, in case the command is one that wipes threads. E.g.,
|
||||||
|
detach, kill, disconnect, etc., or even normally continuing
|
||||||
|
over an inferior or thread exit. */
|
||||||
|
std::vector<thread_info *> thr_list_cpy;
|
||||||
|
thr_list_cpy.reserve (tc);
|
||||||
|
|
||||||
/* Save a copy of the thread_list in case we execute detach
|
{
|
||||||
command. */
|
thread_info *tp;
|
||||||
tp_array = XNEWVEC (struct thread_info *, tc);
|
|
||||||
make_cleanup (xfree, tp_array);
|
|
||||||
|
|
||||||
ALL_NON_EXITED_THREADS (tp)
|
ALL_NON_EXITED_THREADS (tp)
|
||||||
{
|
|
||||||
tp_array[i] = tp;
|
|
||||||
tp->incref ();
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
/* Because we skipped exited threads, we may end up with fewer
|
|
||||||
threads in the array than the total count of threads. */
|
|
||||||
gdb_assert (i <= tc);
|
|
||||||
|
|
||||||
if (i != 0)
|
|
||||||
qsort (tp_array, i, sizeof (*tp_array), tp_array_compar);
|
|
||||||
|
|
||||||
ta_cleanup.tp_array = tp_array;
|
|
||||||
ta_cleanup.count = i;
|
|
||||||
make_cleanup (set_thread_refcount, &ta_cleanup);
|
|
||||||
|
|
||||||
for (k = 0; k != i; k++)
|
|
||||||
if (thread_alive (tp_array[k]))
|
|
||||||
{
|
{
|
||||||
switch_to_thread (tp_array[k]->ptid);
|
thr_list_cpy.push_back (tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_assert (thr_list_cpy.size () == tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the refcounts, and restore them back on scope
|
||||||
|
exit. */
|
||||||
|
scoped_inc_dec_ref inc_dec_ref (thr_list_cpy);
|
||||||
|
|
||||||
|
std::sort (thr_list_cpy.begin (), thr_list_cpy.end (), tp_array_compar);
|
||||||
|
|
||||||
|
for (thread_info *thr : thr_list_cpy)
|
||||||
|
if (thread_alive (thr))
|
||||||
|
{
|
||||||
|
switch_to_thread (thr->ptid);
|
||||||
printf_filtered (_("\nThread %s (%s):\n"),
|
printf_filtered (_("\nThread %s (%s):\n"),
|
||||||
print_thread_id (tp_array[k]),
|
print_thread_id (thr),
|
||||||
target_pid_to_str (inferior_ptid));
|
target_pid_to_str (inferior_ptid));
|
||||||
execute_command (cmd, from_tty);
|
execute_command (cmd, from_tty);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue