Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | /* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <errno.h> #include <zephyr/posix/pthread.h> /** * @brief Destroy semaphore. * * see IEEE 1003.1 */ int sem_destroy(sem_t *semaphore) { if (semaphore == NULL) { errno = EINVAL; return -1; } if (k_sem_count_get(semaphore)) { errno = EBUSY; return -1; } k_sem_reset(semaphore); return 0; } /** * @brief Get value of semaphore. * * See IEEE 1003.1 */ int sem_getvalue(sem_t *semaphore, int *value) { if (semaphore == NULL) { errno = EINVAL; return -1; } *value = (int) k_sem_count_get(semaphore); return 0; } /** * @brief Initialize semaphore. * * See IEEE 1003.1 */ int sem_init(sem_t *semaphore, int pshared, unsigned int value) { if (value > CONFIG_SEM_VALUE_MAX) { errno = EINVAL; return -1; } /* * Zephyr has no concept of process, so only thread shared * semaphore makes sense in here. */ __ASSERT(pshared == 0, "pshared should be 0"); k_sem_init(semaphore, value, CONFIG_SEM_VALUE_MAX); return 0; } /** * @brief Unlock a semaphore. * * See IEEE 1003.1 */ int sem_post(sem_t *semaphore) { if (semaphore == NULL) { errno = EINVAL; return -1; } k_sem_give(semaphore); return 0; } /** * @brief Try time limited locking a semaphore. * * See IEEE 1003.1 */ int sem_timedwait(sem_t *semaphore, struct timespec *abstime) { int32_t timeout; int64_t current_ms, abstime_ms; __ASSERT(abstime, "abstime pointer NULL"); if ((abstime->tv_sec < 0) || (abstime->tv_nsec >= NSEC_PER_SEC)) { errno = EINVAL; return -1; } current_ms = (int64_t)k_uptime_get(); abstime_ms = (int64_t)_ts_to_ms(abstime); if (abstime_ms <= current_ms) { timeout = 0; } else { timeout = (int32_t)(abstime_ms - current_ms); } if (k_sem_take(semaphore, K_MSEC(timeout))) { errno = ETIMEDOUT; return -1; } return 0; } /** * @brief Lock a semaphore if not taken. * * See IEEE 1003.1 */ int sem_trywait(sem_t *semaphore) { if (k_sem_take(semaphore, K_NO_WAIT) == -EBUSY) { errno = EAGAIN; return -1; } else { return 0; } } /** * @brief Lock a semaphore. * * See IEEE 1003.1 */ int sem_wait(sem_t *semaphore) { /* With K_FOREVER, may return only success. */ (void)k_sem_take(semaphore, K_FOREVER); return 0; } |