/* Thread iterators and ranges for GDB, the GNU debugger.

   Copyright (C) 2018 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/>.  */

#include "defs.h"
#include "gdbthread.h"
#include "inferior.h"

/* See thread-iter.h.  */

all_threads_iterator::all_threads_iterator (begin_t)
{
  /* Advance M_INF/M_THR to the first thread's position.  */
  for (m_inf = inferior_list; m_inf != NULL; m_inf = m_inf->next)
    if ((m_thr = m_inf->thread_list) != NULL)
      return;
}

/* See thread-iter.h.  */

void
all_threads_iterator::advance ()
{
  /* The loop below is written in the natural way as-if we'd always
     start at the beginning of the inferior list.  This fast forwards
     the algorithm to the actual current position.  */
  goto start;

  for (; m_inf != NULL; m_inf = m_inf->next)
    {
      m_thr = m_inf->thread_list;
      while (m_thr != NULL)
	{
	  return;
	start:
	  m_thr = m_thr->next;
	}
    }
}

/* See thread-iter.h.  */

bool
all_matching_threads_iterator::m_inf_matches ()
{
  return (m_filter_ptid == minus_one_ptid
	  || m_filter_ptid.pid () == m_inf->pid);
}

/* See thread-iter.h.  */

all_matching_threads_iterator::all_matching_threads_iterator
  (ptid_t filter_ptid)
  : m_filter_ptid (filter_ptid)
{
  m_thr = nullptr;
  for (m_inf = inferior_list; m_inf != NULL; m_inf = m_inf->next)
    if (m_inf_matches ())
      for (m_thr = m_inf->thread_list; m_thr != NULL; m_thr = m_thr->next)
	if (m_thr->ptid.matches (m_filter_ptid))
	  return;
}

/* See thread-iter.h.  */

void
all_matching_threads_iterator::advance ()
{
  /* The loop below is written in the natural way as-if we'd always
     start at the beginning of the inferior list.  This fast forwards
     the algorithm to the actual current position.  */
  goto start;

  for (; m_inf != NULL; m_inf = m_inf->next)
    if (m_inf_matches ())
      {
	m_thr = m_inf->thread_list;
	while (m_thr != NULL)
	  {
	    if (m_thr->ptid.matches (m_filter_ptid))
	      return;
	  start:
	    m_thr = m_thr->next;
	  }
      }
}
