pthread_mutex.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include <rtthread.h>
  2. #include "pthread.h"
  3. #define MUTEXATTR_SHARED_MASK 0x0010
  4. #define MUTEXATTR_TYPE_MASK 0x000f
  5. const pthread_mutexattr_t pthread_default_mutexattr = PTHREAD_PROCESS_PRIVATE;
  6. int pthread_mutexattr_init(pthread_mutexattr_t *attr)
  7. {
  8. if (attr)
  9. {
  10. *attr = pthread_default_mutexattr;
  11. return 0;
  12. }
  13. return EINVAL;
  14. }
  15. int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
  16. {
  17. if (attr)
  18. {
  19. *attr = -1;
  20. return 0;
  21. }
  22. return EINVAL;
  23. }
  24. int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
  25. {
  26. if (attr && type)
  27. {
  28. int atype = (*attr & MUTEXATTR_TYPE_MASK);
  29. if (atype >= PTHREAD_MUTEX_NORMAL && atype <= PTHREAD_MUTEX_ERRORCHECK)
  30. {
  31. *type = atype;
  32. return 0;
  33. }
  34. }
  35. return EINVAL;
  36. }
  37. int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
  38. {
  39. if (attr && type >= PTHREAD_MUTEX_NORMAL &&
  40. type <= PTHREAD_MUTEX_ERRORCHECK )
  41. {
  42. *attr = (*attr & ~MUTEXATTR_TYPE_MASK) | type;
  43. return 0;
  44. }
  45. return EINVAL;
  46. }
  47. int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared)
  48. {
  49. if (!attr) return EINVAL;
  50. switch (pshared)
  51. {
  52. case PTHREAD_PROCESS_PRIVATE:
  53. *attr &= ~MUTEXATTR_SHARED_MASK;
  54. return 0;
  55. case PTHREAD_PROCESS_SHARED:
  56. *attr |= MUTEXATTR_SHARED_MASK;
  57. return 0;
  58. }
  59. return EINVAL;
  60. }
  61. int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared)
  62. {
  63. if (!attr || !pshared) return EINVAL;
  64. *pshared = (*attr & MUTEXATTR_SHARED_MASK) ? PTHREAD_PROCESS_SHARED
  65. : PTHREAD_PROCESS_PRIVATE;
  66. return 0;
  67. }
  68. int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
  69. {
  70. rt_err_t result;
  71. char name[RT_NAME_MAX];
  72. static rt_uint16_t pthread_mutex_number = 0;
  73. if (!mutex) return EINVAL;
  74. /* build mutex name */
  75. rt_snprintf(name, sizeof(name), "pmtx%02d", pthread_mutex_number ++);
  76. if (attr == RT_NULL) mutex->attr = pthread_default_mutexattr;
  77. else mutex->attr = *attr;
  78. /* init mutex lock */
  79. result = rt_mutex_init(&(mutex->lock), name, RT_IPC_FLAG_FIFO);
  80. if (result != RT_EOK) return EINVAL;
  81. /* detach the object from system object container */
  82. rt_object_detach(&(mutex->lock.parent.parent));
  83. return 0;
  84. }
  85. int pthread_mutex_destroy(pthread_mutex_t *mutex)
  86. {
  87. if (!mutex || mutex->attr == -1) return EINVAL;
  88. /* it's busy */
  89. if (mutex->lock.owner != RT_NULL) return EBUSY;
  90. rt_memset(mutex, 0, sizeof(pthread_mutex_t));
  91. mutex->attr = -1;
  92. return 0;
  93. }
  94. int pthread_mutex_lock(pthread_mutex_t *mutex)
  95. {
  96. int mtype;
  97. rt_err_t result;
  98. if (!mutex) return EINVAL;
  99. if (mutex->attr == -1)
  100. {
  101. /* init mutex */
  102. pthread_mutex_init(mutex, RT_NULL);
  103. }
  104. mtype = mutex->attr & MUTEXATTR_TYPE_MASK;
  105. rt_enter_critical();
  106. if (mutex->lock.owner == rt_thread_self() && mtype != PTHREAD_MUTEX_RECURSIVE)
  107. {
  108. rt_exit_critical();
  109. return EDEADLK;
  110. }
  111. rt_exit_critical();
  112. result = rt_mutex_take(&(mutex->lock), RT_WAITING_FOREVER);
  113. if (result == RT_EOK) return 0;
  114. return EINVAL;
  115. }
  116. int pthread_mutex_unlock(pthread_mutex_t *mutex)
  117. {
  118. rt_err_t result;
  119. if (!mutex) return EINVAL;
  120. if (mutex->attr == -1)
  121. {
  122. /* init mutex */
  123. pthread_mutex_init(mutex, RT_NULL);
  124. }
  125. if (mutex->lock.owner != rt_thread_self())
  126. {
  127. int mtype;
  128. mtype = mutex->attr & MUTEXATTR_TYPE_MASK;
  129. /* error check, return EPERM */
  130. if (mtype == PTHREAD_MUTEX_ERRORCHECK) return EPERM;
  131. /* no thread waiting on this mutex */
  132. if (mutex->lock.owner == RT_NULL) return 0;
  133. }
  134. result = rt_mutex_release(&(mutex->lock));
  135. if (result == RT_EOK) return 0;
  136. }
  137. int pthread_mutex_trylock(pthread_mutex_t *mutex)
  138. {
  139. rt_err_t result;
  140. if (!mutex) return EINVAL;
  141. if (mutex->attr == -1)
  142. {
  143. /* init mutex */
  144. pthread_mutex_init(mutex, RT_NULL);
  145. }
  146. result = rt_mutex_take(&(mutex->lock), 0);
  147. if (result == RT_EOK) return 0;
  148. return EBUSY;
  149. }