/* Multi-thread control defs for remote server for GDB.
   Copyright (C) 1993-2022 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
{
  thread_info (ptid_t id, void *target_data)
    : id (id), target_data (target_data)
  {}

  ~thread_info ()
  {
    free_register_cache (this->regcache_data);
  }

  /* The id of this thread.  */
  ptid_t id;

  void *target_data;
  struct regcache *regcache_data = nullptr;

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

  /* 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 = 0;

  /* 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 = nullptr;

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

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 ();
}

/* Switch the current thread.  */

void switch_to_thread (thread_info *thread);

/* Save/restore current thread.  */

class scoped_restore_current_thread
{
public:
  scoped_restore_current_thread ();
  ~scoped_restore_current_thread ();

  DISABLE_COPY_AND_ASSIGN (scoped_restore_current_thread);

  /* Cancel restoring on scope exit.  */
  void dont_restore () { m_dont_restore = true; }

private:
  bool m_dont_restore = false;
  thread_info *m_thread;
};

#endif /* GDBSERVER_GDBTHREAD_H */
