|
1 | 1 | #pragma once |
2 | 2 |
|
3 | 3 | #include <cstddef> |
4 | | -#include <cstdio> |
5 | 4 | #include <memory> |
6 | 5 |
|
7 | 6 | #include "quadrants/runtime/llvm/llvm_offline_cache.h" |
@@ -100,8 +99,11 @@ class LlvmProgramImpl : public ProgramImpl { |
100 | 99 | return runtime_exec_->fetch_result<T>(i, result_buffer); |
101 | 100 | } |
102 | 101 |
|
103 | | - // Mark the impl as shutting down so `synchronize_and_assert()` skips the overflow poll, preventing a |
104 | | - // `qd.sync()` racing with destruction from throwing inside `~Program()` unwinding. |
| 102 | + // Skip the adstack-overflow poll from this point on: `Program::finalize()` invokes `pre_finalize()` before the |
| 103 | + // two teardown `synchronize()` calls, and we do not want `check_adstack_overflow()` to throw into a |
| 104 | + // `~Program()` unwinding path - that would terminate the process with a bare `QuadrantsAssertionError` instead |
| 105 | + // of letting the user handle it at their own `qd.sync()` site. The flag only affects the internal poll; the |
| 106 | + // user can still call `qd.sync()` explicitly before finalize to observe the raise. |
105 | 107 | void pre_finalize() override { |
106 | 108 | finalizing_ = true; |
107 | 109 | } |
@@ -165,8 +167,6 @@ class LlvmProgramImpl : public ProgramImpl { |
165 | 167 | if (!finalizing_) { |
166 | 168 | runtime_exec_->check_adstack_overflow(); |
167 | 169 | } |
168 | | - // Flush JIT-generated `qd.print()` output at every user-visible sync. |
169 | | - fflush(stdout); |
170 | 170 | } |
171 | 171 |
|
172 | 172 | LLVMRuntime *get_llvm_runtime() { |
@@ -267,8 +267,11 @@ class LlvmProgramImpl : public ProgramImpl { |
267 | 267 | std::size_t num_snode_trees_processed_{0}; |
268 | 268 | std::unique_ptr<LlvmRuntimeExecutor> runtime_exec_; |
269 | 269 | std::unique_ptr<LlvmOfflineCache> cache_data_; |
270 | | - // Set by `pre_finalize()` / `finalize()` so `synchronize_and_assert()` skips the overflow poll while |
271 | | - // teardown is in progress. |
| 270 | + // Flipped on by `pre_finalize()` (with a defensive re-assignment in `finalize()`) so the `synchronize()` |
| 271 | + // override stops polling the adstack-overflow flag during teardown. `Program::finalize()` invokes |
| 272 | + // `pre_finalize()` before its two teardown syncs, so the flag is already true when those syncs run; moving |
| 273 | + // the assignment back into `finalize()` alone would silently re-introduce the `std::terminate()` teardown bug |
| 274 | + // this field was introduced to fix. |
272 | 275 | bool finalizing_{false}; |
273 | 276 | }; |
274 | 277 |
|
|
0 commit comments