posix_thread.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include <iron_thread.h>
  2. #include <assert.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <wchar.h>
  7. void iron_mutex_init(iron_mutex_t *mutex) {
  8. pthread_mutexattr_t attr;
  9. pthread_mutexattr_init(&attr);
  10. pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  11. pthread_mutex_init(&mutex->impl.mutex, &attr);
  12. }
  13. void iron_mutex_destroy(iron_mutex_t *mutex) {
  14. pthread_mutex_destroy(&mutex->impl.mutex);
  15. }
  16. bool iron_mutex_try_to_lock(iron_mutex_t *mutex) {
  17. return pthread_mutex_trylock(&mutex->impl.mutex) == 0;
  18. }
  19. void iron_mutex_lock(iron_mutex_t *mutex) {
  20. pthread_mutex_lock(&mutex->impl.mutex);
  21. }
  22. void iron_mutex_unlock(iron_mutex_t *mutex) {
  23. pthread_mutex_unlock(&mutex->impl.mutex);
  24. }
  25. #if !defined(IRON_IOS) && !defined(IRON_MACOS)
  26. struct thread_start {
  27. void (*thread)(void *param);
  28. void *param;
  29. };
  30. #define THREAD_STARTS 64
  31. static struct thread_start starts[THREAD_STARTS];
  32. static int thread_start_index = 0;
  33. static void *ThreadProc(void *arg) {
  34. intptr_t start_index = (intptr_t)arg;
  35. starts[start_index].thread(starts[start_index].param);
  36. pthread_exit(NULL);
  37. return NULL;
  38. }
  39. void iron_thread_init(iron_thread_t *t, void (*thread)(void *param), void *param) {
  40. t->impl.param = param;
  41. t->impl.thread = thread;
  42. pthread_attr_t attr;
  43. pthread_attr_init(&attr);
  44. // pthread_attr_setstacksize(&attr, 1024 * 64);
  45. struct sched_param sp;
  46. memset(&sp, 0, sizeof(sp));
  47. sp.sched_priority = 0;
  48. pthread_attr_setschedparam(&attr, &sp);
  49. intptr_t start_index = thread_start_index++;
  50. if (thread_start_index >= THREAD_STARTS) {
  51. thread_start_index = 0;
  52. }
  53. starts[start_index].thread = thread;
  54. starts[start_index].param = param;
  55. int ret = pthread_create(&t->impl.pthread, &attr, &ThreadProc, (void *)start_index);
  56. assert(ret == 0);
  57. pthread_attr_destroy(&attr);
  58. }
  59. void iron_thread_wait_and_destroy(iron_thread_t *thread) {
  60. int ret;
  61. do {
  62. ret = pthread_join(thread->impl.pthread, NULL);
  63. } while (ret != 0);
  64. }
  65. bool iron_thread_try_to_destroy(iron_thread_t *thread) {
  66. return pthread_join(thread->impl.pthread, NULL) == 0;
  67. }
  68. void iron_threads_init() {}
  69. void iron_threads_quit() {}
  70. // Alternatively _GNU_SOURCE can be defined to make
  71. // the headers declare it but let's not make it too
  72. // easy to write Linux-specific POSIX-code
  73. int pthread_setname_np(pthread_t thread, const char *name);
  74. #endif
  75. void iron_thread_set_name(const char *name) {
  76. #if !defined(IRON_IOS) && !defined(IRON_MACOS)
  77. pthread_setname_np(pthread_self(), name);
  78. #else
  79. pthread_setname_np(name);
  80. #endif
  81. }
  82. void iron_thread_sleep(int milliseconds) {
  83. usleep(1000 * (useconds_t)milliseconds);
  84. }