diff options
author | Tom Tromey <tom@tromey.com> | 2023-12-03 12:34:49 -0700 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2024-01-18 08:20:16 -0700 |
commit | 47efef8f2d8a10b63d2c6125aded1d2da69d8a04 (patch) | |
tree | fc94ec0ca473443e1218e1af36e4cb3fea5f44ef /gdb/dwarf2/cooked-index.c | |
parent | 6e53356b77887974e554ae07f9d76b83cd211700 (diff) |
Change cooked_index_worker to abstract base class
This changes cooked_index_worker to be an abstract base class. The
base class implementation is moved to cooked-index.c, and a concrete
subclass is added to read.c.
This change is preparation for the new .debug_names reader, which will
supply its own concrete implementation of the worker.
Diffstat (limited to 'gdb/dwarf2/cooked-index.c')
-rw-r--r-- | gdb/dwarf2/cooked-index.c | 136 |
1 files changed, 134 insertions, 2 deletions
diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c index d63fd0ab5bc..97a749f97e8 100644 --- a/gdb/dwarf2/cooked-index.c +++ b/gdb/dwarf2/cooked-index.c @@ -442,9 +442,141 @@ cooked_index_shard::find (const std::string &name, bool completing) const return range (lower, upper); } +/* See cooked-index.h. */ + +void +cooked_index_worker::start () +{ + gdb::thread_pool::g_thread_pool->post_task ([=] () + { + this->start_reading (); + }); +} + +/* See cooked-index.h. */ + +void +cooked_index_worker::start_reading () +{ + SCOPE_EXIT { bfd_thread_cleanup (); }; + + try + { + do_reading (); + } + catch (const gdb_exception &exc) + { + m_failed = exc; + set (cooked_state::CACHE_DONE); + } +} + +/* See cooked-index.h. */ + +bool +cooked_index_worker::wait (cooked_state desired_state, bool allow_quit) +{ + bool done; +#if CXX_STD_THREAD + { + std::unique_lock<std::mutex> lock (m_mutex); + + /* This may be called from a non-main thread -- this functionality + is needed for the index cache -- but in this case we require + that the desired state already have been attained. */ + gdb_assert (is_main_thread () || desired_state <= m_state); + + while (desired_state > m_state) + { + if (allow_quit) + { + std::chrono::milliseconds duration { 15 }; + if (m_cond.wait_for (lock, duration) == std::cv_status::timeout) + QUIT; + } + else + m_cond.wait (lock); + } + done = m_state == cooked_state::CACHE_DONE; + } +#else + /* Without threads, all the work is done immediately on the main + thread, and there is never anything to wait for. */ + done = true; +#endif /* CXX_STD_THREAD */ + + /* Only the main thread is allowed to report complaints and the + like. */ + if (!is_main_thread ()) + return false; + + if (m_reported) + return done; + m_reported = true; + + /* Emit warnings first, maybe they were emitted before an exception + (if any) was thrown. */ + m_warnings.emit (); + + if (m_failed.has_value ()) + { + /* start_reading failed -- report it. */ + exception_print (gdb_stderr, *m_failed); + m_failed.reset (); + return done; + } + + /* Only show a given exception a single time. */ + std::unordered_set<gdb_exception> seen_exceptions; + for (auto &one_result : m_results) + { + re_emit_complaints (std::get<1> (one_result)); + for (auto &one_exc : std::get<2> (one_result)) + if (seen_exceptions.insert (one_exc).second) + exception_print (gdb_stderr, one_exc); + } + + print_stats (); + + struct objfile *objfile = m_per_objfile->objfile; + dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd; + cooked_index *table + = (gdb::checked_static_cast<cooked_index *> + (per_bfd->index_table.get ())); + + auto_obstack temp_storage; + enum language lang = language_unknown; + const char *main_name = table->get_main_name (&temp_storage, &lang); + if (main_name != nullptr) + set_objfile_main_name (objfile, main_name, lang); + + /* dwarf_read_debug_printf ("Done building psymtabs of %s", */ + /* objfile_name (objfile)); */ + + return done; +} + +/* See cooked-index.h. */ + +void +cooked_index_worker::set (cooked_state desired_state) +{ + gdb_assert (desired_state != cooked_state::INITIAL); + +#if CXX_STD_THREAD + std::lock_guard<std::mutex> guard (m_mutex); + gdb_assert (desired_state > m_state); + m_state = desired_state; + m_cond.notify_one (); +#else + /* Without threads, all the work is done immediately on the main + thread, and there is never anything to do. */ +#endif /* CXX_STD_THREAD */ +} -cooked_index::cooked_index (dwarf2_per_objfile *per_objfile) - : m_state (std::make_unique<cooked_index_worker> (per_objfile)), +cooked_index::cooked_index (dwarf2_per_objfile *per_objfile, + std::unique_ptr<cooked_index_worker> &&worker) + : m_state (std::move (worker)), m_per_bfd (per_objfile->per_bfd) { /* ACTIVE_VECTORS is not locked, and this assert ensures that this |