1
0

pthread_cond.c 4.4 KB

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