smp_affinity_pri1_tc.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 Test that threads with low-priority bound cores do not preempt high-priority threads.
  14. *
  15. * @note Create RT_CPUS_NR threads, thread 0 is bound to core 0, lower priority, the priority of the other threads
  16. * for the system's highest and the thread entry function does not let out the CPU control, run the specified
  17. * number of times in thread 0 to create a high-priority not bound to the core of the thread, the thread will
  18. * be preempted by the core 0 is running on the thread!
  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 num = 0;
  31. static void thread_temp_entry(void *parameter)
  32. {
  33. int id = 0;
  34. while (1)
  35. {
  36. id = rt_hw_cpu_id();
  37. uassert_int_equal(id, 0);
  38. extern long list_thread(void);
  39. list_thread();
  40. rt_thread_delete(temp_thread);
  41. }
  42. }
  43. static void thread_entry(void *parameter)
  44. {
  45. int id = 0;
  46. int para = *(int *)parameter;
  47. while (1)
  48. {
  49. thread_inc++;
  50. id = rt_hw_cpu_id();
  51. if (para == 0)
  52. {
  53. if (thread_inc == run_num)
  54. {
  55. uassert_int_equal(id, 0);
  56. extern long list_thread(void);
  57. list_thread();
  58. /* Creating high-priority untied core threads */
  59. temp_thread = rt_thread_create("Tn", thread_temp_entry, RT_NULL, THREAD_STACK_SIZE, THIGH_PRIORITY, 20);
  60. if (temp_thread != RT_NULL)
  61. {
  62. rt_thread_startup(temp_thread);
  63. }
  64. }
  65. rt_thread_delay(5);
  66. }
  67. else
  68. {
  69. uassert_int_not_equal(id, 0);
  70. while (1);
  71. }
  72. }
  73. }
  74. static void smp_affinity_pri1_tc(void)
  75. {
  76. static int params[RT_CPUS_NR] = {0};
  77. char thread_name[8];
  78. int i;
  79. for (i = 0; i < RT_CPUS_NR; i++)
  80. {
  81. params[i] = i;
  82. }
  83. /* Creating threads with low priority bindings to core 0 */
  84. threads[0] = rt_thread_create("T0", thread_entry, (int *)&params[0], THREAD_STACK_SIZE, LOW_PRIORITY, 20);
  85. if (threads[0] != RT_NULL)
  86. {
  87. rt_thread_control(threads[0], RT_THREAD_CTRL_BIND_CPU, (void *)0);
  88. rt_thread_startup(threads[0]);
  89. }
  90. /* Create high-priority unbound threads with thread functions that don't let out CPU control */
  91. for (i = 1; i < RT_CPUS_NR; i++)
  92. {
  93. rt_snprintf(thread_name, sizeof(thread_name), "T%d", i);
  94. threads[i] = rt_thread_create(thread_name, thread_entry, (int *)&params[i], THREAD_STACK_SIZE, THREAD_PRIORITY, 20);
  95. if (threads[i] != RT_NULL)
  96. {
  97. rt_thread_control(threads[i], RT_THREAD_CTRL_BIND_CPU, (void *)i);
  98. rt_thread_startup(threads[i]);
  99. }
  100. }
  101. rt_thread_delay(100);
  102. }
  103. static rt_err_t utest_tc_init(void)
  104. {
  105. rt_spin_lock_init(&lock);
  106. return RT_EOK;
  107. }
  108. static rt_err_t utest_tc_cleanup(void)
  109. {
  110. for (num = 0; num < RT_CPUS_NR; num++)
  111. {
  112. rt_thread_delete(threads[num]);
  113. }
  114. return RT_EOK;
  115. }
  116. static void testcase(void)
  117. {
  118. UTEST_UNIT_RUN(smp_affinity_pri1_tc);
  119. }
  120. UTEST_TC_EXPORT(testcase, "testcases.smp.affinity_pri1_tc", utest_tc_init, utest_tc_cleanup, 10);