Skip to content

Commit 7f1c797

Browse files
authored
[onert] Propagate async buffer fill errors to waiters (#16365)
It adds error handling mechanism for asynchronous buffer fill operations in BulkPipelineModel to prevent indefinite blocking when async buffer fill encounters exceptions. ONE-DCO-1.0-Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
1 parent 8c030c9 commit 7f1c797

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

runtime/onert/backend/trix/ops/BulkPipelineModel.cc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,12 @@ void BulkPipelineModel::setNextModel(std::shared_ptr<BulkPipelineModel> next)
184184
void BulkPipelineModel::waitForBufferReady()
185185
{
186186
std::unique_lock<std::mutex> lock(_buffer_mutex);
187-
_buffer_cv.wait(lock, [this] { return _buffer_ready.load(); });
187+
_buffer_cv.wait(lock, [this] { return _buffer_ready.load() || _buffer_error.load(); });
188+
189+
if (_buffer_error.load())
190+
{
191+
throw std::runtime_error("Buffer fill failed");
192+
}
188193
}
189194

190195
void BulkPipelineModel::markBufferReady()
@@ -199,6 +204,7 @@ void BulkPipelineModel::markBufferReady()
199204
void BulkPipelineModel::startAsyncBufferFill()
200205
{
201206
_buffer_ready = false;
207+
_buffer_error = false;
202208
_async_fill_future = std::async(std::launch::async, [this] {
203209
try
204210
{
@@ -207,6 +213,12 @@ void BulkPipelineModel::startAsyncBufferFill()
207213
}
208214
catch (const std::exception &e)
209215
{
216+
{
217+
std::lock_guard<std::mutex> lock(_buffer_mutex);
218+
_buffer_ready = false;
219+
_buffer_error = true;
220+
}
221+
_buffer_cv.notify_all();
210222
std::cerr << "Failed to fill buffers asynchronously: " << e.what() << std::endl;
211223
}
212224
});

runtime/onert/backend/trix/ops/BulkPipelineModel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class BulkPipelineModel
106106
std::mutex _buffer_mutex;
107107
std::condition_variable _buffer_cv;
108108
std::atomic<bool> _buffer_ready{false};
109+
std::atomic<bool> _buffer_error{false};
109110
std::future<void> _async_fill_future;
110111
};
111112

runtime/onert/backend/trix/ops/test/BulkPipelineModel.test.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,26 @@ TEST_F(BulkPipelineModelTest, test_model_release)
114114
EXPECT_EQ(model->modelId(), 0);
115115
EXPECT_EQ(model->metadata(), nullptr);
116116
}
117+
118+
TEST_F(BulkPipelineModelTest, test_async_fill)
119+
{
120+
model->initialize();
121+
model->prepare();
122+
123+
std::shared_ptr<BulkPipelineModel> next_model;
124+
next_model = std::make_shared<BulkPipelineModel>("next_model_path", 0);
125+
next_model->initialize();
126+
next_model->prepare();
127+
next_model->setBufferOwnership(BulkPipelineModel::BufferOwnership::SHARED);
128+
129+
model->setNextModel(next_model);
130+
131+
EXPECT_NO_THROW(next_model->startAsyncBufferFill());
132+
EXPECT_NO_THROW(next_model->waitForBufferReady());
133+
134+
// Release model for negative test
135+
next_model->release();
136+
// Exception will be thrown to different thread
137+
next_model->startAsyncBufferFill();
138+
EXPECT_ANY_THROW(next_model->waitForBufferReady());
139+
}

0 commit comments

Comments
 (0)