condvar_signal_tc.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-11-20 Shell add test suites
  9. * 2026-03-19 cl2t Add standardized utest documentation block
  10. */
  11. /**
  12. * Test Case Name: Condition Variable Signal Test
  13. *
  14. * Test Objectives:
  15. * - Verify that rt_condvar_signal() correctly wakes up a single thread
  16. * waiting on a condition variable.
  17. * - Test core APIs: rt_condvar_signal(), rt_condvar_timedwait(),
  18. * rt_mutex_take(), rt_mutex_release(), rt_thread_create().
  19. *
  20. * Test Scenarios:
  21. * - The main thread acquires a mutex, creates a waker thread, then waits
  22. * on a condition variable with a 100-tick timeout.
  23. * - The waker thread acquires the mutex and calls rt_condvar_signal() to
  24. * wake the main thread.
  25. * - The main thread verifies it was woken successfully and releases the
  26. * mutex.
  27. *
  28. * Verification Metrics:
  29. * - rt_condvar_signal() must return 0 on success.
  30. * - rt_condvar_timedwait() must return 0 when signaled before timeout.
  31. * - Timeout (-ETIMEDOUT) or interrupt (-EINTR) are acceptable non-fatal
  32. * outcomes.
  33. * - Mutex acquire and release must succeed without errors.
  34. *
  35. * Dependencies:
  36. * - Software configuration: RT_USING_SMART must be enabled.
  37. * - Environmental assumptions: The platform must support multi-threading.
  38. *
  39. * Expected Results:
  40. * - Final output: "[ PASSED ] [ result ] testcase (testcases.ipc.condvar.signal)"
  41. * - No assertion failures during test execution.
  42. */
  43. #include "common.h"
  44. #include "utest_assert.h"
  45. #include <rtdevice.h>
  46. #include <rtdef.h>
  47. #define STACK_SIZE (0x2000)
  48. static struct rt_mutex _local_mtx;
  49. static struct rt_condvar _local_cv;
  50. static void waker_thr(void *param)
  51. {
  52. int err;
  53. rt_mutex_t mutex = &_local_mtx;
  54. rt_condvar_t cond = &_local_cv;
  55. rt_mutex_take(mutex, RT_WAITING_FOREVER);
  56. err = rt_condvar_signal(cond);
  57. if (err != 0)
  58. {
  59. LOG_E("errno=%d, ret=%d\n", errno, err);
  60. LOG_E("rt_condvar_signal() error");
  61. uassert_false(1);
  62. }
  63. else
  64. {
  65. uassert_false(0);
  66. }
  67. rt_mutex_release(mutex);
  68. return;
  69. }
  70. static void condvar_signal_tc(void)
  71. {
  72. rt_thread_t waker;
  73. rt_mutex_t mutex = &_local_mtx;
  74. rt_condvar_t cond = &_local_cv;
  75. int err;
  76. waker = rt_thread_create("waker", waker_thr, 0, STACK_SIZE, 25, 50);
  77. uassert_not_null(waker);
  78. if (rt_mutex_take(mutex, RT_WAITING_FOREVER) != 0)
  79. {
  80. LOG_E("pthread_mutex_lock() error");
  81. uassert_false(1);
  82. return;
  83. }
  84. else
  85. {
  86. uassert_false(0);
  87. }
  88. rt_thread_startup(waker);
  89. err = rt_condvar_timedwait(cond, mutex, RT_KILLABLE, 100);
  90. if (err != 0)
  91. {
  92. if (err == -EINTR || err == -ETIMEDOUT)
  93. {
  94. puts("wait timed out");
  95. uassert_false(0);
  96. }
  97. else
  98. {
  99. LOG_E("errno=%d, ret=%d\n", errno, err);
  100. LOG_E("pthread_cond_timedwait() error");
  101. uassert_false(1);
  102. }
  103. }
  104. err = rt_mutex_release(mutex);
  105. if (err != 0)
  106. {
  107. LOG_E("errno=%d, ret=%d\n", errno, err);
  108. LOG_E("rt_mutex_release() error");
  109. uassert_false(1);
  110. }
  111. else
  112. {
  113. uassert_false(0);
  114. }
  115. return ;
  116. }
  117. static rt_err_t utest_tc_init(void)
  118. {
  119. if (rt_mutex_init(&_local_mtx, "utest", RT_IPC_FLAG_PRIO) != 0)
  120. {
  121. perror("pthread_mutex_init() error");
  122. uassert_false(1);
  123. return -1;
  124. }
  125. rt_condvar_init(&_local_cv, NULL);
  126. return RT_EOK;
  127. }
  128. static rt_err_t utest_tc_cleanup(void)
  129. {
  130. rt_mutex_detach(&_local_mtx);
  131. rt_condvar_detach(&_local_cv);
  132. return RT_EOK;
  133. }
  134. static void testcase(void)
  135. {
  136. UTEST_UNIT_RUN(condvar_signal_tc);
  137. }
  138. UTEST_TC_EXPORT(testcase, "testcases.ipc.condvar.signal", utest_tc_init, utest_tc_cleanup, 10);