[IE][VPU][XLink]: XLink semaphore wrappers impl (#3079)
[platform/upstream/dldt.git] / inference-engine / thirdparty / movidius / XLink / shared / src / XLinkSemaphore.c
1 // Copyright (C) 2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include "XLinkSemaphore.h"
6 #include "XLinkErrorUtils.h"
7 #include "XLinkLog.h"
8
9 static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
10 static pthread_cond_t ref_cond = PTHREAD_COND_INITIALIZER;
11
12 int XLink_sem_inc(XLink_sem_t* sem)
13 {
14     XLINK_RET_IF_FAIL(pthread_mutex_lock(&ref_mutex));
15     if (sem->refs < 0) {
16         // Semaphore has been already destroyed
17         XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
18         return -1;
19     }
20
21     sem->refs++;
22     XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
23
24     return 0;
25 }
26
27 int XLink_sem_dec(XLink_sem_t* sem)
28 {
29     XLINK_RET_IF_FAIL(pthread_mutex_lock(&ref_mutex));
30     if (sem->refs < 1) {
31         // Can't decrement reference count if there are no waiters
32         // or semaphore has been already destroyed
33         XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
34         return -1;
35     }
36
37     sem->refs--;
38     int ret = pthread_cond_broadcast(&ref_cond);
39     XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
40
41     return ret;
42 }
43
44
45 int XLink_sem_init(XLink_sem_t* sem, int pshared, unsigned int value)
46 {
47     XLINK_RET_ERR_IF(sem == NULL, -1);
48
49     XLINK_RET_IF_FAIL(sem_init(&sem->psem, pshared, value));
50     XLINK_RET_IF_FAIL(pthread_mutex_lock(&ref_mutex));
51     sem->refs = 0;
52     XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
53
54     return 0;
55 }
56
57 int XLink_sem_destroy(XLink_sem_t* sem)
58 {
59     XLINK_RET_ERR_IF(sem == NULL, -1);
60
61     XLINK_RET_IF_FAIL(pthread_mutex_lock(&ref_mutex));
62     if (sem->refs < 0) {
63         // Semaphore has been already destroyed
64         XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
65         return -1;
66     }
67
68     while(sem->refs > 0) {
69         if (pthread_cond_wait(&ref_cond, &ref_mutex)) {
70             break;
71         };
72     }
73     sem->refs = -1;
74     int ret = sem_destroy(&sem->psem);
75     XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
76
77     return ret;
78 }
79
80 int XLink_sem_post(XLink_sem_t* sem)
81 {
82     XLINK_RET_ERR_IF(sem == NULL, -1);
83     if (sem->refs < 0) {
84         return -1;
85     }
86
87     return sem_post(&sem->psem);
88 }
89
90 int XLink_sem_wait(XLink_sem_t* sem)
91 {
92     XLINK_RET_ERR_IF(sem == NULL, -1);
93
94     XLINK_RET_IF_FAIL(XLink_sem_inc(sem));
95     int ret = sem_wait(&sem->psem);
96     XLINK_RET_IF_FAIL(XLink_sem_dec(sem));
97
98     return ret;
99 }
100
101 int XLink_sem_timedwait(XLink_sem_t* sem, const struct timespec* abstime)
102 {
103     XLINK_RET_ERR_IF(sem == NULL, -1);
104     XLINK_RET_ERR_IF(abstime == NULL, -1);
105
106     XLINK_RET_IF_FAIL(XLink_sem_inc(sem));
107     int ret = sem_timedwait(&sem->psem, abstime);
108     XLINK_RET_IF_FAIL(XLink_sem_dec(sem));
109
110     return ret;
111 }
112
113 int XLink_sem_set_refs(XLink_sem_t* sem, int refs)
114 {
115     XLINK_RET_ERR_IF(sem == NULL, -1);
116     XLINK_RET_ERR_IF(refs < -1, -1);
117
118     XLINK_RET_IF_FAIL(pthread_mutex_lock(&ref_mutex));
119     sem->refs = refs;
120     int ret = pthread_cond_broadcast(&ref_cond);
121     XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
122
123     return ret;
124 }
125
126 int XLink_sem_get_refs(XLink_sem_t* sem, int *sval)
127 {
128     XLINK_RET_ERR_IF(sem == NULL, -1);
129
130     *sval = sem->refs;
131     return 0;
132 }