btrace: Remove VEC cleanups

This patch replaces two VEC(tp_t) with std::vector<thread_info *>, which
allows to remove two cleanups.  To make it easier to map the old code to
the new code, I added the ordered_remove and unordered_remove functions,
which operate on std::vector and do the same as VEC's
ordered_remove/unordered_remove.

gdb/ChangeLog:

	* record-btrace.c (record_btrace_maybe_mark_async_event): Change
	parameter types to std::vector.  Use bool.
	(record_btrace_wait): Replace VEC(tp_t) with
	std::vector<thread_info *>.
	* common/gdb_vecs.h (unordered_remove, ordered_remove): New.
This commit is contained in:
Simon Marchi 2018-03-06 09:51:33 -05:00 committed by Simon Marchi
parent 228f15081e
commit 5312700841
3 changed files with 72 additions and 35 deletions

View File

@ -1,3 +1,11 @@
2018-03-06 Simon Marchi <simon.marchi@polymtl.ca>
* record-btrace.c (record_btrace_maybe_mark_async_event): Change
parameter types to std::vector. Use bool.
(record_btrace_wait): Replace VEC(tp_t) with
std::vector<thread_info *>.
* common/gdb_vecs.h (unordered_remove, ordered_remove): New.
2018-03-06 Simon Marchi <simon.marchi@polymtl.ca> 2018-03-06 Simon Marchi <simon.marchi@polymtl.ca>
* record-btrace.c (record_btrace_disable_callback): Remove. * record-btrace.c (record_btrace_disable_callback): Remove.

View File

@ -50,4 +50,35 @@ extern void dirnames_to_char_ptr_vec_append
extern std::vector<gdb::unique_xmalloc_ptr<char>> extern std::vector<gdb::unique_xmalloc_ptr<char>>
dirnames_to_char_ptr_vec (const char *dirnames); dirnames_to_char_ptr_vec (const char *dirnames);
/* Remove the element at position IX from VEC, not preserving the order of the
remaining elements. Return the removed element. */
template <typename T>
T
unordered_remove (std::vector<T> &vec, typename std::vector<T>::size_type ix)
{
gdb_assert (ix < vec.size ());
T removed = std::move (vec[ix]);
vec[ix] = std::move (vec.back ());
vec.pop_back ();
return removed;
}
/* Remove the element at position IX from VEC, preserving the order the
remaining elements. Return the removed element. */
template <typename T>
T
ordered_remove (std::vector<T> &vec, typename std::vector<T>::size_type ix)
{
gdb_assert (ix < vec.size ());
T removed = std::move (vec[ix]);
vec.erase (vec.begin () + ix);
return removed;
}
#endif /* GDB_VECS_H */ #endif /* GDB_VECS_H */

View File

@ -2428,13 +2428,12 @@ DEF_VEC_P (tp_t);
/* Announce further events if necessary. */ /* Announce further events if necessary. */
static void static void
record_btrace_maybe_mark_async_event (const VEC (tp_t) *moving, record_btrace_maybe_mark_async_event
const VEC (tp_t) *no_history) (const std::vector<thread_info *> &moving,
const std::vector<thread_info *> &no_history)
{ {
int more_moving, more_no_history; bool more_moving = !moving.empty ();
bool more_no_history = !no_history.empty ();;
more_moving = !VEC_empty (tp_t, moving);
more_no_history = !VEC_empty (tp_t, no_history);
if (!more_moving && !more_no_history) if (!more_moving && !more_no_history)
return; return;
@ -2454,9 +2453,8 @@ static ptid_t
record_btrace_wait (struct target_ops *ops, ptid_t ptid, record_btrace_wait (struct target_ops *ops, ptid_t ptid,
struct target_waitstatus *status, int options) struct target_waitstatus *status, int options)
{ {
VEC (tp_t) *moving, *no_history; std::vector<thread_info *> moving;
struct thread_info *tp, *eventing; std::vector<thread_info *> no_history;
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
DEBUG ("wait %s (0x%x)", target_pid_to_str (ptid), options); DEBUG ("wait %s (0x%x)", target_pid_to_str (ptid), options);
@ -2468,26 +2466,25 @@ record_btrace_wait (struct target_ops *ops, ptid_t ptid,
return ops->to_wait (ops, ptid, status, options); return ops->to_wait (ops, ptid, status, options);
} }
moving = NULL;
no_history = NULL;
make_cleanup (VEC_cleanup (tp_t), &moving);
make_cleanup (VEC_cleanup (tp_t), &no_history);
/* Keep a work list of moving threads. */ /* Keep a work list of moving threads. */
ALL_NON_EXITED_THREADS (tp) {
if (ptid_match (tp->ptid, ptid) thread_info *tp;
&& ((tp->btrace.flags & (BTHR_MOVE | BTHR_STOP)) != 0))
VEC_safe_push (tp_t, moving, tp);
if (VEC_empty (tp_t, moving)) ALL_NON_EXITED_THREADS (tp)
{
if (ptid_match (tp->ptid, ptid)
&& ((tp->btrace.flags & (BTHR_MOVE | BTHR_STOP)) != 0))
moving.push_back (tp);
}
}
if (moving.empty ())
{ {
*status = btrace_step_no_resumed (); *status = btrace_step_no_resumed ();
DEBUG ("wait ended by %s: %s", target_pid_to_str (null_ptid), DEBUG ("wait ended by %s: %s", target_pid_to_str (null_ptid),
target_waitstatus_to_string (status).c_str ()); target_waitstatus_to_string (status).c_str ());
do_cleanups (cleanups);
return null_ptid; return null_ptid;
} }
@ -2508,14 +2505,13 @@ record_btrace_wait (struct target_ops *ops, ptid_t ptid,
nothing else to report. By this time, all threads should have moved to nothing else to report. By this time, all threads should have moved to
either the beginning or the end of their execution history. There will either the beginning or the end of their execution history. There will
be a single user-visible stop. */ be a single user-visible stop. */
eventing = NULL; struct thread_info *eventing = NULL;
while ((eventing == NULL) && !VEC_empty (tp_t, moving)) while ((eventing == NULL) && !moving.empty ())
{ {
unsigned int ix; for (unsigned int ix = 0; eventing == NULL && ix < moving.size ();)
ix = 0;
while ((eventing == NULL) && VEC_iterate (tp_t, moving, ix, tp))
{ {
thread_info *tp = moving[ix];
*status = record_btrace_step_thread (tp); *status = record_btrace_step_thread (tp);
switch (status->kind) switch (status->kind)
@ -2525,12 +2521,11 @@ record_btrace_wait (struct target_ops *ops, ptid_t ptid,
break; break;
case TARGET_WAITKIND_NO_HISTORY: case TARGET_WAITKIND_NO_HISTORY:
VEC_safe_push (tp_t, no_history, no_history.push_back (ordered_remove (moving, ix));
VEC_ordered_remove (tp_t, moving, ix));
break; break;
default: default:
eventing = VEC_unordered_remove (tp_t, moving, ix); eventing = unordered_remove (moving, ix);
break; break;
} }
} }
@ -2543,11 +2538,11 @@ record_btrace_wait (struct target_ops *ops, ptid_t ptid,
In the former case, EVENTING must not be NULL. In the former case, EVENTING must not be NULL.
In the latter case, NO_HISTORY must not be empty. */ In the latter case, NO_HISTORY must not be empty. */
gdb_assert (!VEC_empty (tp_t, no_history)); gdb_assert (!no_history.empty ());
/* We kept threads moving at the end of their execution history. Stop /* We kept threads moving at the end of their execution history. Stop
EVENTING now that we are going to report its stop. */ EVENTING now that we are going to report its stop. */
eventing = VEC_unordered_remove (tp_t, no_history, 0); eventing = unordered_remove (no_history, 0);
eventing->btrace.flags &= ~BTHR_MOVE; eventing->btrace.flags &= ~BTHR_MOVE;
*status = btrace_step_no_history (); *status = btrace_step_no_history ();
@ -2561,8 +2556,12 @@ record_btrace_wait (struct target_ops *ops, ptid_t ptid,
/* Stop all other threads. */ /* Stop all other threads. */
if (!target_is_non_stop_p ()) if (!target_is_non_stop_p ())
ALL_NON_EXITED_THREADS (tp) {
record_btrace_cancel_resume (tp); thread_info *tp;
ALL_NON_EXITED_THREADS (tp)
record_btrace_cancel_resume (tp);
}
/* In async mode, we need to announce further events. */ /* In async mode, we need to announce further events. */
if (target_is_async_p ()) if (target_is_async_p ())
@ -2579,7 +2578,6 @@ record_btrace_wait (struct target_ops *ops, ptid_t ptid,
target_pid_to_str (eventing->ptid), target_pid_to_str (eventing->ptid),
target_waitstatus_to_string (status).c_str ()); target_waitstatus_to_string (status).c_str ());
do_cleanups (cleanups);
return eventing->ptid; return eventing->ptid;
} }