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