[IE][VPU]: fixing wrong threads behavior in mvnc_api.c (#5053)

Lock global mutexes while locking all inferences to prevent unlocking all inferences on all devices including just opened
This commit is contained in:
Aleksandr Korolev 2021-04-01 14:17:29 +03:00 committed by GitHub
parent 0f8cdfa293
commit ce5aa7dc1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -82,8 +82,23 @@ static OVERLAPPED global_lock_overlap = { 0 };
#define GLOBAL_UNLOCK() UnlockFileEx(global_lock_fd, 0, MAXDWORD, MAXDWORD, &global_lock_overlap)
#else
static int global_lock_fd = -1;
#define GLOBAL_LOCK() flock(global_lock_fd, LOCK_EX)
#define GLOBAL_UNLOCK() flock(global_lock_fd, LOCK_UN)
#define GLOBAL_LOCK() \
do { \
CHECK_MUTEX_SUCCESS_RC(flock(global_lock_fd, LOCK_EX), NC_ERROR); \
if (pthread_mutex_lock(&deviceOpenMutex) != 0) { \
CHECK_MUTEX_SUCCESS(flock(global_lock_fd, LOCK_UN)); \
return NC_ERROR; \
} \
} while (0)
#define GLOBAL_UNLOCK() \
do { \
if (flock(global_lock_fd, LOCK_UN) != 0) { \
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex)); \
return NC_ERROR; \
} \
CHECK_MUTEX_SUCCESS_RC(pthread_mutex_unlock(&deviceOpenMutex), NC_ERROR); \
} while (0)
#endif
#define STRINGIFY(_text) #_text
@ -749,17 +764,10 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
}
GLOBAL_LOCK();
int error = pthread_mutex_lock(&deviceOpenMutex);
if (error) {
GLOBAL_UNLOCK();
mvLog(MVLOG_ERROR, "pthread_mutex_lock(&deviceOpenMutex) failed with error: %d", error);
return NC_ERROR;
}
if (!initialized) {
ncStatus_t sc;
if ((sc = initializeXLink()) != 0) {
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return sc;
}
@ -775,7 +783,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
}
if (rc != X_LINK_SUCCESS) {
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return parseXLinkError(NC_ERROR);
}
@ -795,7 +802,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
d->wd_interval = watchdogInterval;
*deviceHandlePtr = dH;
} else {
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
mvLog(MVLOG_ERROR, "Memory allocation failed");
free(d);
@ -805,7 +811,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
if (d->dev_addr == NULL) {
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return NC_OUT_OF_MEMORY;
}
@ -817,7 +822,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
if (!handler) {
mvLog(MVLOG_ERROR, "Memory allocation failed");
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return NC_OUT_OF_MEMORY;
}
@ -847,7 +851,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
mvLog(MVLOG_ERROR, "Can't get firmware, error: %s", ncStatusToStr(sc));
free(handler);
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return NC_MVCMD_NOT_FOUND;
}
@ -858,7 +861,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
__func__, XLinkErrorToStr(rc), d->dev_addr);
free(handler);
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return NC_ERROR;
} else {
@ -917,7 +919,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
mvLog(MVLOG_ERROR, "Can't get firmware, error: %s", ncStatusToStr(sc));
free(handler);
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return NC_MVCMD_NOT_FOUND;
}
@ -1017,7 +1018,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
}
free(handler);
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return NC_ERROR;
}
@ -1028,7 +1028,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
mvLog(MVLOG_ERROR, "Failed connection to device (%s) with error %d", d->dev_addr, rc);
free(handler);
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return parseXLinkError(rc);
}
@ -1041,7 +1040,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
if (d->dev_addr == NULL || d->dev_addr_booted == NULL || d->xlink == NULL) {
mvLog(MVLOG_ERROR, "device is invalid");
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return NC_INVALID_HANDLE;
}
@ -1049,11 +1047,10 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
devices = d;
mvLog(MVLOG_INFO, "XLinkConnect done - link Id %d\n", handler->linkId);
int error = 0;
if ((error = pthread_mutex_init(&d->dev_data_m, NULL)) != 0) {
mvLog(MVLOG_ERROR, "pthread_mutex_init (dev_data_m) failed with error: %d", error);
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return NC_ERROR;
}
@ -1062,7 +1059,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
mvLog(MVLOG_ERROR, "pthread_mutex_init (dev_stream_m) failed with error: %d", error);
CHECK_MUTEX_SUCCESS(pthread_mutex_destroy(&d->dev_data_m));
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return NC_ERROR;
}
@ -1071,7 +1067,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
CHECK_MUTEX_SUCCESS(pthread_mutex_destroy(&d->dev_data_m));
CHECK_MUTEX_SUCCESS(pthread_mutex_destroy(&d->dev_stream_m));
destroyDeviceHandle(deviceHandlePtr);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
return NC_ERROR;
}
@ -1087,7 +1082,6 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
sleepForSeconds(1);
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&deviceOpenMutex));
GLOBAL_UNLOCK();
streamId_t deviceMonitorStreamId = XLinkOpenStream(d->xlink->linkId, "deviceMonitor", CONFIG_STREAM_SIZE);
@ -1941,22 +1935,24 @@ ncStatus_t checkGraphMonitorResponse(streamId_t graphMonStream) {
return NC_OK;
}
static void lockAllInferences() {
static ncStatus_t lockAllInferences() {
GLOBAL_LOCK();
struct _devicePrivate_t *d = devices;
while (d) {
CHECK_MUTEX_SUCCESS(pthread_mutex_lock(&d->graph_stream_m));
d = d->next;
}
return;
return NC_OK;
}
static void unlockAllInferences() {
static ncStatus_t unlockAllInferences() {
struct _devicePrivate_t *d = devices;
while (d) {
CHECK_MUTEX_SUCCESS(pthread_mutex_unlock(&d->graph_stream_m));
d = d->next;
}
return;
GLOBAL_UNLOCK();
return NC_OK;
}
ncStatus_t ncGraphAllocate(struct ncDeviceHandle_t * deviceHandle,
@ -2006,7 +2002,12 @@ ncStatus_t ncGraphAllocate(struct ncDeviceHandle_t * deviceHandle,
return NC_OUT_OF_MEMORY;
}
lockAllInferences();
rc = lockAllInferences();
if (rc != 0) {
mvLog(MVLOG_ERROR, "can't lock all inferences");
unlockAllInferences();
return rc;
}
g->id = graphIdCount++;
streamId_t streamId;
@ -2171,7 +2172,11 @@ ncStatus_t ncGraphAllocate(struct ncDeviceHandle_t * deviceHandle,
g->debug_buffer = g->aux_buffer;
g->time_taken = (float *) (g->aux_buffer + 120);
unlockAllInferences();
rc = unlockAllInferences();
if (rc != 0) {
mvLog(MVLOG_ERROR, "Can't unlock all inferences");
return rc;
}
GLOBAL_LOCK();
g->dev = d;