smp_affinity_pri2_tc.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-08-10 RV the first version
  9. */
  10. #include <rtthread.h>
  11. #include "utest.h"
  12. /**
  13. * @brief Threads are automatically balanced across cores.
  14. *
  15. * @note Create RT_CPUS_NR threads, thread 0 is not bound to core 0, higher priority, the priority of the other
  16. * threads for the system's highest and the thread entry function does not let out the CPU control, run the
  17. * specified number of times after the creation of thread 0 in thread 0, a low-priority bound to the core 0,
  18. * the thread will not preempt the core 0 is running on threads
  19. */
  20. /* Number of thread runs */
  21. static int run_num = 10;
  22. #define THREAD_STACK_SIZE UTEST_THR_STACK_SIZE
  23. #define THREAD_PRIORITY 2
  24. #define LOW_PRIORITY 50
  25. #define THIGH_PRIORITY 10
  26. static rt_thread_t threads[RT_CPUS_NR];
  27. static rt_thread_t temp_thread;
  28. static struct rt_spinlock lock;
  29. static int thread_inc = 0;
  30. static int run_flag = 0;
  31. static int num = 0;
  32. static void thread_temp_entry(void *parameter)
  33. {
  34. run_flag = 1;
  35. rt_thread_delete(temp_thread);
  36. }
  37. static void thread_entry(void *parameter)
  38. {
  39. int id = 0;
  40. int para = *(int *)parameter;
  41. while (1)
  42. {
  43. thread_inc++;
  44. id = rt_hw_cpu_id();
  45. if (para == 0)
  46. {
  47. if (thread_inc == run_num)
  48. {
  49. uassert_int_equal(id, 0);
  50. temp_thread = rt_thread_create("Tn", thread_temp_entry, RT_NULL, THREAD_STACK_SIZE, LOW_PRIORITY, 20);
  51. if (temp_thread != RT_NULL)
  52. {
  53. rt_thread_control(temp_thread, RT_THREAD_CTRL_BIND_CPU, (void *)0);
  54. rt_thread_startup(temp_thread);
  55. uassert_int_not_equal(run_flag, 1);
  56. }
  57. }
  58. rt_thread_delay(5);
  59. }
  60. else
  61. {
  62. uassert_int_not_equal(id, 0);
  63. while (1);
  64. }
  65. }
  66. }
  67. static void smp_affinity_pri2_tc(void)
  68. {
  69. static int params[RT_CPUS_NR] = {0};
  70. char thread_name[8];
  71. int i;
  72. for (i = 0; i < RT_CPUS_NR; i++)
  73. {
  74. params[i] = i;
  75. }
  76. threads[0] = rt_thread_create("T0", thread_entry, (int *)&params[0], THREAD_STACK_SIZE, THIGH_PRIORITY, 20);
  77. if (threads[0] != RT_NULL)
  78. {
  79. uassert_true(1);
  80. rt_thread_startup(threads[0]);
  81. }
  82. /* Create high-priority unbound threads with thread functions that don't let out CPU control */
  83. for (i = 1; i < RT_CPUS_NR; i++)
  84. {
  85. rt_snprintf(thread_name, sizeof(thread_name), "T%d", i);
  86. threads[i] = rt_thread_create(thread_name, thread_entry, (int *)&params[i], THREAD_STACK_SIZE, THREAD_PRIORITY, 20);
  87. if (threads[i] != RT_NULL)
  88. {
  89. uassert_true(1);
  90. rt_thread_control(threads[i], RT_THREAD_CTRL_BIND_CPU, (void *)i);
  91. rt_thread_startup(threads[i]);
  92. }
  93. }
  94. rt_thread_delay(50);
  95. }
  96. static rt_err_t utest_tc_init(void)
  97. {
  98. rt_spin_lock_init(&lock);
  99. return RT_EOK;
  100. }
  101. static rt_err_t utest_tc_cleanup(void)
  102. {
  103. for (num = 0; num < RT_CPUS_NR; num++)
  104. {
  105. rt_thread_delete(threads[num]);
  106. }
  107. return RT_EOK;
  108. }
  109. static void testcase(void)
  110. {
  111. UTEST_UNIT_RUN(smp_affinity_pri2_tc);
  112. }
  113. UTEST_TC_EXPORT(testcase, "testcases.smp.affinity_pri2_tc", utest_tc_init, utest_tc_cleanup, 10);