espidf_thread.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #ifndef _GNU_SOURCE
  6. #define _GNU_SOURCE
  7. #endif
  8. #include "platform_api_vmcore.h"
  9. #include "platform_api_extension.h"
  10. typedef struct {
  11. thread_start_routine_t start;
  12. void *arg;
  13. } thread_wrapper_arg;
  14. static void *
  15. os_thread_wrapper(void *arg)
  16. {
  17. thread_wrapper_arg *targ = arg;
  18. thread_start_routine_t start_func = targ->start;
  19. void *thread_arg = targ->arg;
  20. #if 0
  21. os_printf("THREAD CREATED %jx\n", (uintmax_t)(uintptr_t)pthread_self());
  22. #endif
  23. BH_FREE(targ);
  24. start_func(thread_arg);
  25. return NULL;
  26. }
  27. korp_tid
  28. os_self_thread(void)
  29. {
  30. /* only allowed if this is a thread, xTaskCreate is not enough look at
  31. * product_mini for how to use this*/
  32. return pthread_self();
  33. }
  34. int
  35. os_mutex_init(korp_mutex *mutex)
  36. {
  37. return pthread_mutex_init(mutex, NULL);
  38. }
  39. int
  40. os_mutex_destroy(korp_mutex *mutex)
  41. {
  42. return pthread_mutex_destroy(mutex);
  43. }
  44. int
  45. os_mutex_lock(korp_mutex *mutex)
  46. {
  47. return pthread_mutex_lock(mutex);
  48. }
  49. int
  50. os_mutex_unlock(korp_mutex *mutex)
  51. {
  52. return pthread_mutex_unlock(mutex);
  53. }
  54. int
  55. os_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
  56. void *arg, unsigned int stack_size, int prio)
  57. {
  58. pthread_attr_t tattr;
  59. thread_wrapper_arg *targ;
  60. assert(stack_size > 0);
  61. assert(tid);
  62. assert(start);
  63. pthread_attr_init(&tattr);
  64. pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
  65. if (pthread_attr_setstacksize(&tattr, stack_size) != 0) {
  66. os_printf("Invalid thread stack size %u. Min stack size = %u",
  67. stack_size, PTHREAD_STACK_MIN);
  68. pthread_attr_destroy(&tattr);
  69. return BHT_ERROR;
  70. }
  71. targ = (thread_wrapper_arg *)BH_MALLOC(sizeof(*targ));
  72. if (!targ) {
  73. pthread_attr_destroy(&tattr);
  74. return BHT_ERROR;
  75. }
  76. targ->start = start;
  77. targ->arg = arg;
  78. if (pthread_create(tid, &tattr, os_thread_wrapper, targ) != 0) {
  79. pthread_attr_destroy(&tattr);
  80. os_free(targ);
  81. return BHT_ERROR;
  82. }
  83. pthread_attr_destroy(&tattr);
  84. return BHT_OK;
  85. }
  86. int
  87. os_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
  88. unsigned int stack_size)
  89. {
  90. return os_thread_create_with_prio(tid, start, arg, stack_size,
  91. BH_THREAD_DEFAULT_PRIORITY);
  92. }
  93. int
  94. os_thread_join(korp_tid thread, void **retval)
  95. {
  96. return pthread_join(thread, retval);
  97. }
  98. int
  99. os_thread_detach(korp_tid tid)
  100. {
  101. return pthread_detach(tid);
  102. }
  103. void
  104. os_thread_exit(void *retval)
  105. {
  106. pthread_exit(retval);
  107. }
  108. int
  109. os_cond_init(korp_cond *cond)
  110. {
  111. return pthread_cond_init(cond, NULL);
  112. }
  113. int
  114. os_cond_destroy(korp_cond *cond)
  115. {
  116. return pthread_cond_destroy(cond);
  117. }
  118. int
  119. os_cond_wait(korp_cond *cond, korp_mutex *mutex)
  120. {
  121. return pthread_cond_wait(cond, mutex);
  122. }
  123. static void
  124. msec_nsec_to_abstime(struct timespec *ts, uint64 usec)
  125. {
  126. struct timeval tv;
  127. time_t tv_sec_new;
  128. long int tv_nsec_new;
  129. gettimeofday(&tv, NULL);
  130. tv_sec_new = (time_t)(tv.tv_sec + usec / 1000000);
  131. if (tv_sec_new >= tv.tv_sec) {
  132. ts->tv_sec = tv_sec_new;
  133. }
  134. else {
  135. /* integer overflow */
  136. ts->tv_sec = BH_TIME_T_MAX;
  137. os_printf("Warning: os_cond_reltimedwait exceeds limit, "
  138. "set to max timeout instead\n");
  139. }
  140. tv_nsec_new = (long int)(tv.tv_usec * 1000 + (usec % 1000000) * 1000);
  141. if (tv.tv_usec * 1000 >= tv.tv_usec && tv_nsec_new >= tv.tv_usec * 1000) {
  142. ts->tv_nsec = tv_nsec_new;
  143. }
  144. else {
  145. /* integer overflow */
  146. ts->tv_nsec = LONG_MAX;
  147. os_printf("Warning: os_cond_reltimedwait exceeds limit, "
  148. "set to max timeout instead\n");
  149. }
  150. if (ts->tv_nsec >= 1000000000L && ts->tv_sec < BH_TIME_T_MAX) {
  151. ts->tv_sec++;
  152. ts->tv_nsec -= 1000000000L;
  153. }
  154. }
  155. int
  156. os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds)
  157. {
  158. int ret;
  159. struct timespec abstime;
  160. if (useconds == BHT_WAIT_FOREVER)
  161. ret = pthread_cond_wait(cond, mutex);
  162. else {
  163. msec_nsec_to_abstime(&abstime, useconds);
  164. ret = pthread_cond_timedwait(cond, mutex, &abstime);
  165. }
  166. if (ret != BHT_OK && ret != ETIMEDOUT)
  167. return BHT_ERROR;
  168. return ret;
  169. }
  170. int
  171. os_cond_signal(korp_cond *cond)
  172. {
  173. return pthread_cond_signal(cond);
  174. }