History

lavfi/dnn: DNNAsyncExecModule Execution Failure Handling

This commit adds the case handling if the asynchronous execution of a request fails by checking the exit status of the thread when joining before starting another execution. On failure, it does the cleanup as well.

Shubhanshu Saxena committed 5 years ago

Commit 20637451 parent 371e5672 files · +28 −5Browse files

Showing the changes to libavfilter (2 of 2 files). Show all

Unified · Split

2 files
  1. libavfilter/dnn/dnn_backend_common.c +19 −4
  2. libavfilter/dnn/dnn_backend_tf.c +9 −1
libavfilter/dnn/dnn_backend_common.c+19−4
@@ -23,6 +23,9 @@ · 22 unmodified lines
23 23
24#include "dnn_backend_common.h"24#include "dnn_backend_common.h"
25 25
26#define DNN_ASYNC_SUCCESS (void *)0
27#define DNN_ASYNC_FAIL (void *)-1
28
26int ff_check_exec_params(void *ctx, DNNBackendType backend, DNNFunctionType func_type, DNNExecBaseParams *exec_params)29int ff_check_exec_params(void *ctx, DNNBackendType backend, DNNFunctionType func_type, DNNExecBaseParams *exec_params)
27{30{
28 if (!exec_params) {31 if (!exec_params) {
@@ -79,18 +82,25 @@ static void *async_thread_routine(void *args) · 50 unmodified lines
79 DNNAsyncExecModule *async_module = args;82 DNNAsyncExecModule *async_module = args;
80 void *request = async_module->args;83 void *request = async_module->args;
81 84
82 async_module->start_inference(request);85 if (async_module->start_inference(request) != DNN_SUCCESS) {
86 return DNN_ASYNC_FAIL;
87 }
83 async_module->callback(request);88 async_module->callback(request);
84 return NULL;89 return DNN_ASYNC_SUCCESS;
85}90}
86 91
87DNNReturnType ff_dnn_async_module_cleanup(DNNAsyncExecModule *async_module)92DNNReturnType ff_dnn_async_module_cleanup(DNNAsyncExecModule *async_module)
88{93{
94 void *status = 0;
89 if (!async_module) {95 if (!async_module) {
90 return DNN_ERROR;96 return DNN_ERROR;
91 }97 }
92#if HAVE_PTHREAD_CANCEL98#if HAVE_PTHREAD_CANCEL
93 pthread_join(async_module->thread_id, NULL);99 pthread_join(async_module->thread_id, &status);
100 if (status == DNN_ASYNC_FAIL) {
101 av_log(NULL, AV_LOG_ERROR, "Last Inference Failed.\n");
102 return DNN_ERROR;
103 }
94#endif104#endif
95 async_module->start_inference = NULL;105 async_module->start_inference = NULL;
96 async_module->callback = NULL;106 async_module->callback = NULL;
@@ -101,6 +111,7 @@ DNNReturnType ff_dnn_async_module_cleanup(DNNAsyncExecModule *async_module) · 4 unmodified lines
101DNNReturnType ff_dnn_start_inference_async(void *ctx, DNNAsyncExecModule *async_module)111DNNReturnType ff_dnn_start_inference_async(void *ctx, DNNAsyncExecModule *async_module)
102{112{
103 int ret;113 int ret;
114 void *status = 0;
104 115
105 if (!async_module) {116 if (!async_module) {
106 av_log(ctx, AV_LOG_ERROR, "async_module is null when starting async inference.\n");117 av_log(ctx, AV_LOG_ERROR, "async_module is null when starting async inference.\n");
@@ -108,7 +119,11 @@ DNNReturnType ff_dnn_start_inference_async(void *ctx, DNNAsyncExecModule *async_ · 1 unmodified line
108 }119 }
109 120
110#if HAVE_PTHREAD_CANCEL121#if HAVE_PTHREAD_CANCEL
111 pthread_join(async_module->thread_id, NULL);122 pthread_join(async_module->thread_id, &status);
123 if (status == DNN_ASYNC_FAIL) {
124 av_log(ctx, AV_LOG_ERROR, "Unable to start inference as previous inference failed.\n");
125 return DNN_ERROR;
126 }
112 ret = pthread_create(&async_module->thread_id, NULL, async_thread_routine, async_module);127 ret = pthread_create(&async_module->thread_id, NULL, async_thread_routine, async_module);
113 if (ret != 0) {128 if (ret != 0) {
114 av_log(ctx, AV_LOG_ERROR, "Unable to start async inference.\n");129 av_log(ctx, AV_LOG_ERROR, "Unable to start async inference.\n");
libavfilter/dnn/dnn_backend_tf.c+9−1
@@ -91,6 +91,7 @@ AVFILTER_DEFINE_CLASS(dnn_tensorflow); · 90 unmodified lines
91 91
92static DNNReturnType execute_model_tf(TFRequestItem *request, Queue *inference_queue);92static DNNReturnType execute_model_tf(TFRequestItem *request, Queue *inference_queue);
93static void infer_completion_callback(void *args);93static void infer_completion_callback(void *args);
94static inline void destroy_request_item(TFRequestItem **arg);
94 95
95static void free_buffer(void *data, size_t length)96static void free_buffer(void *data, size_t length)
96{97{
@@ -172,6 +173,10 @@ static DNNReturnType tf_start_inference(void *args) · 75 unmodified lines
172 request->status);173 request->status);
173 if (TF_GetCode(request->status) != TF_OK) {174 if (TF_GetCode(request->status) != TF_OK) {
174 av_log(&tf_model->ctx, AV_LOG_ERROR, "%s", TF_Message(request->status));175 av_log(&tf_model->ctx, AV_LOG_ERROR, "%s", TF_Message(request->status));
176 tf_free_request(infer_request);
177 if (ff_safe_queue_push_back(tf_model->request_queue, request) < 0) {
178 destroy_request_item(&request);
179 }
175 return DNN_ERROR;180 return DNN_ERROR;
176 }181 }
177 return DNN_SUCCESS;182 return DNN_SUCCESS;
@@ -1095,7 +1100,10 @@ static DNNReturnType execute_model_tf(TFRequestItem *request, Queue *inference_q · 917 unmodified lines
1095 }1100 }
1096 1101
1097 if (task->async) {1102 if (task->async) {
1098 return ff_dnn_start_inference_async(ctx, &request->exec_module);1103 if (ff_dnn_start_inference_async(ctx, &request->exec_module) != DNN_SUCCESS) {
1104 goto err;
1105 }
1106 return DNN_SUCCESS;
1099 } else {1107 } else {
1100 if (tf_start_inference(request) != DNN_SUCCESS) {1108 if (tf_start_inference(request) != DNN_SUCCESS) {
1101 goto err;1109 goto err;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t