lwp_tid.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-01-15 shaojinchun first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include "lwp.h"
  13. #ifdef ARCH_MM_MMU
  14. #include "lwp_user_mm.h"
  15. #endif
  16. #define DBG_TAG "LWP_TID"
  17. #define DBG_LVL DBG_INFO
  18. #include <rtdbg.h>
  19. #define TID_MAX 10000
  20. #define TID_CT_ASSERT(name, x) \
  21. struct assert_##name {char ary[2 * (x) - 1];}
  22. TID_CT_ASSERT(tid_min_nr, LWP_TID_MAX_NR > 1);
  23. TID_CT_ASSERT(tid_max_nr, LWP_TID_MAX_NR < TID_MAX);
  24. static struct lwp_avl_struct lwp_tid_ary[LWP_TID_MAX_NR];
  25. static struct lwp_avl_struct *lwp_tid_free_head = RT_NULL;
  26. static int lwp_tid_ary_alloced = 0;
  27. static struct lwp_avl_struct *lwp_tid_root = RT_NULL;
  28. static int current_tid = 0;
  29. int lwp_tid_get(void)
  30. {
  31. rt_base_t level;
  32. struct lwp_avl_struct *p;
  33. int tid = 0;
  34. level = rt_hw_interrupt_disable();
  35. p = lwp_tid_free_head;
  36. if (p)
  37. {
  38. lwp_tid_free_head = (struct lwp_avl_struct *)p->avl_right;
  39. }
  40. else if (lwp_tid_ary_alloced < LWP_TID_MAX_NR)
  41. {
  42. p = lwp_tid_ary + lwp_tid_ary_alloced;
  43. lwp_tid_ary_alloced++;
  44. }
  45. if (p)
  46. {
  47. int found_noused = 0;
  48. RT_ASSERT(p->data == RT_NULL);
  49. for (tid = current_tid + 1; tid < TID_MAX; tid++)
  50. {
  51. if (!lwp_avl_find(tid, lwp_tid_root))
  52. {
  53. found_noused = 1;
  54. break;
  55. }
  56. }
  57. if (!found_noused)
  58. {
  59. for (tid = 1; tid <= current_tid; tid++)
  60. {
  61. if (!lwp_avl_find(tid, lwp_tid_root))
  62. {
  63. found_noused = 1;
  64. break;
  65. }
  66. }
  67. }
  68. p->avl_key = tid;
  69. lwp_avl_insert(p, &lwp_tid_root);
  70. current_tid = tid;
  71. }
  72. rt_hw_interrupt_enable(level);
  73. return tid;
  74. }
  75. void lwp_tid_put(int tid)
  76. {
  77. rt_base_t level;
  78. struct lwp_avl_struct *p;
  79. level = rt_hw_interrupt_disable();
  80. p = lwp_avl_find(tid, lwp_tid_root);
  81. if (p)
  82. {
  83. p->data = RT_NULL;
  84. lwp_avl_remove(p, &lwp_tid_root);
  85. p->avl_right = lwp_tid_free_head;
  86. lwp_tid_free_head = p;
  87. }
  88. rt_hw_interrupt_enable(level);
  89. }
  90. rt_thread_t lwp_tid_get_thread(int tid)
  91. {
  92. rt_base_t level;
  93. struct lwp_avl_struct *p;
  94. rt_thread_t thread = RT_NULL;
  95. level = rt_hw_interrupt_disable();
  96. p = lwp_avl_find(tid, lwp_tid_root);
  97. if (p)
  98. {
  99. thread = (rt_thread_t)p->data;
  100. }
  101. rt_hw_interrupt_enable(level);
  102. return thread;
  103. }
  104. void lwp_tid_set_thread(int tid, rt_thread_t thread)
  105. {
  106. rt_base_t level;
  107. struct lwp_avl_struct *p;
  108. level = rt_hw_interrupt_disable();
  109. p = lwp_avl_find(tid, lwp_tid_root);
  110. if (p)
  111. {
  112. p->data = thread;
  113. }
  114. rt_hw_interrupt_enable(level);
  115. }