1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include <assert.h>
21 #include <stdint.h>
22 #include <string.h>
23 #include "os/os.h"
24 #include "nimble/nimble_npl.h"
25
26 #include <errno.h>
27 #include <pthread.h>
28 #include <semaphore.h>
29
30
31 ble_npl_error_t
ble_npl_sem_init(struct ble_npl_sem * sem,uint16_t tokens)32 ble_npl_sem_init(struct ble_npl_sem *sem, uint16_t tokens)
33 {
34 if (!sem) {
35 return BLE_NPL_INVALID_PARAM;
36 }
37
38 sem_init(&sem->lock, 0, tokens);
39
40 return BLE_NPL_OK;
41 }
42
43 ble_npl_error_t
ble_npl_sem_release(struct ble_npl_sem * sem)44 ble_npl_sem_release(struct ble_npl_sem *sem)
45 {
46 int err;
47
48 if (!sem) {
49 return BLE_NPL_INVALID_PARAM;
50 }
51
52 err = sem_post(&sem->lock);
53
54 return (err) ? BLE_NPL_ERROR : BLE_NPL_OK;
55 }
56
57 ble_npl_error_t
ble_npl_sem_pend(struct ble_npl_sem * sem,uint32_t timeout)58 ble_npl_sem_pend(struct ble_npl_sem *sem, uint32_t timeout)
59 {
60 int err = 0;
61 struct timespec wait;
62
63 if (!sem) {
64 return BLE_NPL_INVALID_PARAM;
65 }
66
67 err = clock_gettime(CLOCK_REALTIME, &wait);
68 if (err) {
69 return BLE_NPL_ERROR;
70 }
71
72 wait.tv_sec += timeout / 1000;
73 wait.tv_nsec += (timeout % 1000) * 1000000;
74 wait.tv_nsec %= 1000000000;
75
76 if (timeout == BLE_NPL_WAIT_FOREVER) {
77 err = sem_wait(&sem->lock);
78 }
79 else
80 {
81 if (sem_timedwait(&sem->lock, &wait)) {
82 assert(errno == ETIMEDOUT);
83 return BLE_NPL_TIMEOUT;
84 }
85 }
86
87 return (err) ? BLE_NPL_ERROR : BLE_NPL_OK;
88 }
89
90 uint16_t
ble_npl_sem_get_count(struct ble_npl_sem * sem)91 ble_npl_sem_get_count(struct ble_npl_sem *sem)
92 {
93 int count;
94
95 assert(sem);
96 assert(&sem->lock);
97 sem_getvalue(&sem->lock, &count);
98
99 return count;
100 }
101