semaphore.c 2.2 KB

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