1 // Copyright (C) 2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
5 #include "XLinkSemaphore.h"
6 #include "XLinkErrorUtils.h"
9 static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
10 static pthread_cond_t ref_cond = PTHREAD_COND_INITIALIZER;
12 int XLink_sem_inc(XLink_sem_t* sem)
14 XLINK_RET_IF_FAIL(pthread_mutex_lock(&ref_mutex));
16 // Semaphore has been already destroyed
17 XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
22 XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
27 int XLink_sem_dec(XLink_sem_t* sem)
29 XLINK_RET_IF_FAIL(pthread_mutex_lock(&ref_mutex));
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));
38 int ret = pthread_cond_broadcast(&ref_cond);
39 XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
45 int XLink_sem_init(XLink_sem_t* sem, int pshared, unsigned int value)
47 XLINK_RET_ERR_IF(sem == NULL, -1);
49 XLINK_RET_IF_FAIL(sem_init(&sem->psem, pshared, value));
50 XLINK_RET_IF_FAIL(pthread_mutex_lock(&ref_mutex));
52 XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
57 int XLink_sem_destroy(XLink_sem_t* sem)
59 XLINK_RET_ERR_IF(sem == NULL, -1);
61 XLINK_RET_IF_FAIL(pthread_mutex_lock(&ref_mutex));
63 // Semaphore has been already destroyed
64 XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
68 while(sem->refs > 0) {
69 if (pthread_cond_wait(&ref_cond, &ref_mutex)) {
74 int ret = sem_destroy(&sem->psem);
75 XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
80 int XLink_sem_post(XLink_sem_t* sem)
82 XLINK_RET_ERR_IF(sem == NULL, -1);
87 return sem_post(&sem->psem);
90 int XLink_sem_wait(XLink_sem_t* sem)
92 XLINK_RET_ERR_IF(sem == NULL, -1);
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));
101 int XLink_sem_timedwait(XLink_sem_t* sem, const struct timespec* abstime)
103 XLINK_RET_ERR_IF(sem == NULL, -1);
104 XLINK_RET_ERR_IF(abstime == NULL, -1);
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));
113 int XLink_sem_set_refs(XLink_sem_t* sem, int refs)
115 XLINK_RET_ERR_IF(sem == NULL, -1);
116 XLINK_RET_ERR_IF(refs < -1, -1);
118 XLINK_RET_IF_FAIL(pthread_mutex_lock(&ref_mutex));
120 int ret = pthread_cond_broadcast(&ref_cond);
121 XLINK_RET_IF_FAIL(pthread_mutex_unlock(&ref_mutex));
126 int XLink_sem_get_refs(XLink_sem_t* sem, int *sval)
128 XLINK_RET_ERR_IF(sem == NULL, -1);