/* Multi-thread control defs for remote server for GDB.
   Copyright (C) 1993-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDBSERVER_GDBTHREAD_H
#define GDBSERVER_GDBTHREAD_H

#include "gdbsupport/common-gdbthread.h"
#include "inferiors.h"

#include <list>

struct btrace_target_info;
struct regcache;

struct thread_info
{
  /* The id of this thread.  */
  ptid_t id;

  void *target_data;
  struct regcache *regcache_data;

  /* The last resume GDB requested on this thread.  */
  enum resume_kind last_resume_kind;

  /* The last wait status reported for this thread.  */
  struct target_waitstatus last_status;

  /* True if LAST_STATUS hasn't been reported to GDB yet.  */
  int status_pending_p;

  /* Given `while-stepping', a thread may be collecting data for more
     than one tracepoint simultaneously.  E.g.:

    ff0001  INSN1 <-- TP1, while-stepping 10 collect $regs
    ff0002  INSN2
    ff0003  INSN3 <-- TP2, collect $regs
    ff0004  INSN4 <-- TP3, while-stepping 10 collect $regs
    ff0005  INSN5

   Notice that when instruction INSN5 is reached, the while-stepping
   actions of both TP1 and TP3 are still being collected, and that TP2
   had been collected meanwhile.  The whole range of ff0001-ff0005
   should be single-stepped, due to at least TP1's while-stepping
   action covering the whole range.

   On the other hand, the same tracepoint with a while-stepping action
   may be hit by more than one thread simultaneously, hence we can't
   keep the current step count in the tracepoint itself.

   This is the head of the list of the states of `while-stepping'
   tracepoint actions this thread is now collecting; NULL if empty.
   Each item in the list holds the current step of the while-stepping
   action.  */
  struct wstep_state *while_stepping;

  /* Branch trace target information for this thread.  */
  struct btrace_target_info *btrace;
};

extern std::list<thread_info *> all_threads;

void remove_thread (struct thread_info *thread);
struct thread_info *add_thread (ptid_t ptid, void *target_data);

/* Return a pointer to the first thread, or NULL if there isn't one.  */

struct thread_info *get_first_thread (void);

struct thread_info *find_thread_ptid (ptid_t ptid);

/* Find any thread of the PID process.  Returns NULL if none is
   found.  */
struct thread_info *find_any_thread_of_pid (int pid);

/* Find the first thread for which FUNC returns true.  Return NULL if no thread
   satisfying FUNC is found.  */

template <typename Func>
static thread_info *
find_thread (Func func)
{
  std::list<thread_info *>::iterator next, cur = all_threads.begin ();

  while (cur != all_threads.end ())
    {
      next = cur;
      next++;

      if (func (*cur))
	return *cur;

      cur = next;
    }

  return NULL;
}

/* Like the above, but only consider threads with pid PID.  */

template <typename Func>
static thread_info *
find_thread (int pid, Func func)
{
  return find_thread ([&] (thread_info *thread)
    {
      return thread->id.pid () == pid && func (thread);
    });
}

/* Find the first thread that matches FILTER for which FUNC returns true.
   Return NULL if no thread satisfying these conditions is found.  */

template <typename Func>
static thread_info *
find_thread (ptid_t filter, Func func)
{
  return find_thread ([&] (thread_info *thread) {
    return thread->id.matches (filter) && func (thread);
  });
}

/* Invoke FUNC for each thread.  */

template <typename Func>
static void
for_each_thread (Func func)
{
  std::list<thread_info *>::iterator next, cur = all_threads.begin ();

  while (cur != all_threads.end ())
    {
      next = cur;
      next++;
      func (*cur);
      cur = next;
    }
}

/* Like the above, but only consider threads with pid PID.  */

template <typename Func>
static void
for_each_thread (int pid, Func func)
{
  for_each_thread ([&] (thread_info *thread)
    {
      if (pid == thread->id.pid ())
	func (thread);
    });
}

/* Find the a random thread for which FUNC (THREAD) returns true.  If
   no entry is found then return NULL.  */

template <typename Func>
static thread_info *
find_thread_in_random (Func func)
{
  int count = 0;
  int random_selector;

  /* First count how many interesting entries we have.  */
  for_each_thread ([&] (thread_info *thread) {
    if (func (thread))
      count++;
  });

  if (count == 0)
    return NULL;

  /* Now randomly pick an entry out of those.  */
  random_selector = (int)
    ((count * (double) rand ()) / (RAND_MAX + 1.0));

  thread_info *thread = find_thread ([&] (thread_info *thr_arg) {
    return func (thr_arg) && (random_selector-- == 0);
  });

  gdb_assert (thread != NULL);

  return thread;
}

/* Get current thread ID (Linux task ID).  */
#define current_ptid (current_thread->id)

/* Get the ptid of THREAD.  */

static inline ptid_t
ptid_of (const thread_info *thread)
{
  return thread->id;
}

/* Get the pid of THREAD.  */

static inline int
pid_of (const thread_info *thread)
{
  return thread->id.pid ();
}

/* Get the lwp of THREAD.  */

static inline long
lwpid_of (const thread_info *thread)
{
  return thread->id.lwp ();
}

#endif /* GDBSERVER_GDBTHREAD_H */
