pthread_cond.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include <pthread.h>
  2. int pthread_condattr_destroy(pthread_condattr_t *attr)
  3. {
  4. if (!attr) return EINVAL;
  5. return 0;
  6. }
  7. int pthread_condattr_init(pthread_condattr_t *attr)
  8. {
  9. if (!attr) return EINVAL;
  10. *attr = PTHREAD_PROCESS_PRIVATE;
  11. return 0;
  12. }
  13. int pthread_condattr_getclock(const pthread_condattr_t *attr,
  14. clockid_t *clock_id)
  15. {
  16. return 0;
  17. }
  18. int pthread_condattr_setclock(pthread_condattr_t *attr,
  19. clockid_t clock_id)
  20. {
  21. return 0;
  22. }
  23. int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared)
  24. {
  25. if (!attr || !pshared) return EINVAL;
  26. *pshared = PTHREAD_PROCESS_PRIVATE;
  27. return 0;
  28. }
  29. int pthread_condattr_setpshared(pthread_condattr_t*attr, int pshared)
  30. {
  31. if ((pshared != PTHREAD_PROCESS_PRIVATE) && (pshared != PTHREAD_PROCESS_SHARED))
  32. return EINVAL;
  33. if (pshared != PTHREAD_PROCESS_PRIVATE)
  34. return ENOSYS;
  35. return 0;
  36. }
  37. int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
  38. {
  39. rt_err_t result;
  40. rt_uint8_t cond_name[RT_NAME_MAX];
  41. static rt_uint16_t cond_num = 0;
  42. /* parameter check */
  43. if (cond == RT_NULL) return EINVAL;
  44. if ((attr != RT_NULL) && (*attr != PTHREAD_PROCESS_PRIVATE)) return EINVAL;
  45. rt_snprintf(cond_name, sizeof(cond_name),
  46. "cond%02d", cond_num++);
  47. cond->attr = *attr;
  48. result = rt_sem_init(&cond->sem, cond_name, 0, RT_IPC_FLAG_FIFO);
  49. if (result != RT_EOK) return EINVAL;
  50. /* detach the object from system object container */
  51. rt_object_detach(&(cond->sem.parent.parent));
  52. return 0;
  53. }
  54. int pthread_cond_destroy(pthread_cond_t *cond)
  55. {
  56. rt_err_t result;
  57. if (cond == RT_NULL) return EINVAL;
  58. if (cond->attr == -1) return 0; /* which is not initialized */
  59. result = rt_sem_trytake(&(cond->sem));
  60. if (result != RT_EOK) return EBUSY;
  61. /* clean condition */
  62. rt_memset(cond, 0, sizeof(pthread_cond_t));
  63. cond->attr = -1;
  64. return 0;
  65. }
  66. int pthread_cond_broadcast(pthread_cond_t *cond)
  67. {
  68. rt_err_t result;
  69. if (cond->attr == -1)
  70. pthread_cond_init(cond, RT_NULL);
  71. rt_enter_critical();
  72. while (1)
  73. {
  74. /* try to take condition semaphore */
  75. result = rt_sem_trytake(&(cond->sem));
  76. if (result == -RT_ETIMEOUT)
  77. {
  78. /* it's timeout, release this semaphore */
  79. rt_sem_release(&(cond->sem));
  80. }
  81. else if (result == RT_EOK)
  82. {
  83. /* has taken this semaphore, release it */
  84. rt_sem_release(&(cond->sem));
  85. break;
  86. }
  87. else
  88. {
  89. rt_exit_critical();
  90. return EINVAL;
  91. }
  92. }
  93. rt_exit_critical();
  94. return 0;
  95. }
  96. int pthread_cond_signal(pthread_cond_t *cond)
  97. {
  98. rt_err_t result;
  99. if (cond->attr == -1)
  100. pthread_cond_init(cond, RT_NULL);
  101. result = rt_sem_release(&(cond->sem));
  102. if (result == RT_EOK) return 0;
  103. return 0;
  104. }
  105. rt_err_t _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
  106. rt_int32_t timeout)
  107. {
  108. rt_err_t result;
  109. if (!cond || !mutex) return -RT_ERROR;
  110. /* check whether initialized */
  111. if (cond->attr == -1) pthread_cond_init(cond, RT_NULL);
  112. /* The mutex was not owned by the current thread at the time of the call. */
  113. if (mutex->lock.owner != pthread_self()) return -RT_ERROR;
  114. /* unlock a mutex failed */
  115. if (pthread_mutex_unlock(mutex) != 0)
  116. return -RT_ERROR;
  117. result = rt_sem_take(&(cond->sem), timeout);
  118. /* lock mutex again */
  119. pthred_mutex_lock(mutex);
  120. return result;
  121. }
  122. int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
  123. {
  124. rt_err_t result;
  125. result = _pthread_cond_timedwait(cond, mutex, RT_WAITING_FOREVER);
  126. if (result == RT_EOK) return 0;
  127. return EINVAL;
  128. }
  129. int pthread_cond_timedwait(pthread_cond_t *cond,
  130. pthread_mutex_t * mutex,
  131. const struct timespec *abstime)
  132. {
  133. rt_int32_t timeout;
  134. rt_err_t result;
  135. timeout = abstime->tv_sec * RT_TICK_PER_SECOND +
  136. abstime->tv_nsec * RT_TICK_PER_SECOND/1000000000;
  137. result = _pthread_cond_timedwait(cond, mutex, timeout);
  138. if (result == RT_EOK) return 0;
  139. if (result == -RT_ETIMEOUT) return ETIMEDOUT;
  140. return EINVAL;
  141. }