void finalize() { run_thread_finalizers(); finalize_frontend_lean_module(); finalize_definitional_module(); finalize_tactic_module(); finalize_library_module(); finalize_quotient_module(); finalize_inductive_module(); finalize_kernel_module(); finalize_sexpr_module(); finalize_numerics_module(); finalize_util_module(); run_post_thread_finalizers(); }
void finalize() { #ifdef LEAN_TRACK_CUSTOM_ALLOCATORS std::cerr << "memory deallocated by memory_pool and small_object_allocator (before finalization): " << get_memory_deallocated() << "\n"; #endif #ifdef LEAN_TRACK_LIVE_EXPRS std::cerr << "number of live expressions (before finalization): " << get_num_live_exprs() << "\n"; #endif run_thread_finalizers(); finalize_vm_module(); finalize_frontend_lean_module(); finalize_inductive_compiler_module(); finalize_equations_compiler_module(); finalize_constructions_module(); finalize_tactic_module(); finalize_compiler_module(); finalize_library_module(); finalize_vm_core_module(); finalize_library_core_module(); finalize_quotient_module(); finalize_inductive_module(); finalize_kernel_module(); finalize_sexpr_module(); finalize_numerics_module(); finalize_util_module(); run_post_thread_finalizers(); #ifdef LEAN_TRACK_CUSTOM_ALLOCATORS std::cerr << "memory deallocated by memory_pool and small_object_allocator (after finalization): " << get_memory_deallocated() << "\n"; #endif #ifdef LEAN_TRACK_LIVE_EXPRS std::cerr << "number of live expressions (after finalization): " << get_num_live_exprs() << "\n"; #endif delete_thread_finalizer_manager(); #ifdef LEAN_TRACK_CUSTOM_ALLOCATORS std::cerr << "memory deallocated by memory_pool and small_object_allocator (after thread finalization): " << get_memory_deallocated() << "\n"; #endif #ifdef LEAN_TRACK_LIVE_EXPRS std::cerr << "number of live expressions (after thread finalization): " << get_num_live_exprs() << "\n"; #endif }
void mt_task_queue::spawn_worker() { lean_always_assert(!m_shutting_down); auto this_worker = std::make_shared<worker_info>(); m_workers.push_back(this_worker); m_required_workers--; this_worker->m_thread.reset(new lthread([this, this_worker]() { save_stack_info(false); unique_lock<mutex> lock(m_mutex); while (true) { if (m_shutting_down) { break; } if (m_required_workers < 0) { scoped_add<int> inc_required(m_required_workers, +1); scoped_add<unsigned> inc_sleeping(m_sleeping_workers, +1); if (m_wake_up_worker.wait_for(lock, g_worker_max_idle_time, [&] { return m_required_workers >= 1 || m_shutting_down; })) { continue; } else { break; } } if (m_queue.empty()) { if (m_queue_added.wait_for(lock, g_worker_max_idle_time, [&] { return !m_queue.empty() || m_shutting_down; })) { continue; } else { break; } } auto t = dequeue(); if (get_state(t).load() != task_state::Queued) continue; get_state(t) = task_state::Running; reset_heartbeat(); { flet<gtask> _(this_worker->m_current_task, t); scoped_current_task scope_cur_task(&t); notify_queue_changed(); lock.unlock(); execute(t); lock.lock(); } reset_heartbeat(); handle_finished(t); notify_queue_changed(); } // We need to run the finalizers while the lock is held, // otherwise we risk a race condition at the end of the program. // We would finalize in the thread, while we call the finalize() function. run_thread_finalizers(); run_post_thread_finalizers(); m_workers.erase(std::find(m_workers.begin(), m_workers.end(), this_worker)); m_required_workers++; m_shut_down_cv.notify_all(); })); }