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

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

#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_target == nullptr | |

|| m_filter_target == m_inf->process_target ()) | |

&& (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 | |

(process_stratum_target *filter_target, ptid_t filter_ptid) | |

: m_filter_target (filter_target), | |

m_filter_ptid (filter_ptid) | |

{ | |

gdb_assert ((filter_target == nullptr && filter_ptid == minus_one_ptid) | |

|| filter_target->stratum () == process_stratum); | |

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; | |

} | |

} | |

} |