ex7.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. */
  9. /* ex7
  10. *
  11. * Test case that illustrates a timed wait on a condition variable.
  12. */
  13. #include <sys/errno.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <pthread.h>
  17. #include <sys/time.h>
  18. #include <unistd.h>
  19. #define usleep rt_thread_sleep
  20. /* Our event variable using a condition variable contruct. */
  21. typedef struct
  22. {
  23. pthread_mutex_t mutex;
  24. pthread_cond_t cond;
  25. int flag;
  26. } event_t;
  27. /* Global event to signal main thread the timeout of the child thread. */
  28. event_t main_event;
  29. static void *test_thread(void *ms_param)
  30. {
  31. int status = 0;
  32. event_t foo;
  33. struct timespec time;
  34. struct timeval now;
  35. long ms = (long) ms_param;
  36. /* initialize cond var */
  37. pthread_cond_init(&foo.cond, NULL);
  38. pthread_mutex_init(&foo.mutex, NULL);
  39. foo.flag = 0;
  40. /* set the time out value */
  41. printf("waiting %ld ms ...\n", ms);
  42. gettimeofday(&now, NULL);
  43. time.tv_sec = now.tv_sec + ms / 1000 + (now.tv_usec + (ms % 1000) * 1000)
  44. / 1000000;
  45. time.tv_nsec = ((now.tv_usec + (ms % 1000) * 1000) % 1000000) * 1000;
  46. /* Just use this to test the time out. The cond var is never signaled. */
  47. pthread_mutex_lock(&foo.mutex);
  48. while (foo.flag == 0 && status != ETIMEDOUT)
  49. {
  50. status = pthread_cond_timedwait(&foo.cond, &foo.mutex, &time);
  51. }
  52. pthread_mutex_unlock(&foo.mutex);
  53. /* post the main event */
  54. pthread_mutex_lock(&main_event.mutex);
  55. main_event.flag = 1;
  56. pthread_cond_signal(&main_event.cond);
  57. pthread_mutex_unlock(&main_event.mutex);
  58. /* that's it, bye */
  59. return (void*) status;
  60. }
  61. int libc_ex7(void)
  62. {
  63. unsigned long count;
  64. setvbuf(stdout, NULL, _IONBF, 0);
  65. /* initialize main event cond var */
  66. pthread_cond_init(&main_event.cond, NULL);
  67. pthread_mutex_init(&main_event.mutex, NULL);
  68. main_event.flag = 0;
  69. for (count = 0; count < 20; ++count)
  70. {
  71. pthread_t thread;
  72. int status;
  73. /* pass down the milli-second timeout in the void* param */
  74. status = pthread_create(&thread, NULL, test_thread, (void*)(count
  75. * 100));
  76. if (status != 0)
  77. {
  78. printf("status = %d, count = %lu: %s\n", status, count, strerror(
  79. errno));
  80. return 1;
  81. }
  82. else
  83. {
  84. /* wait for the event posted by the child thread */
  85. pthread_mutex_lock(&main_event.mutex);
  86. while (main_event.flag == 0)
  87. {
  88. pthread_cond_wait(&main_event.cond, &main_event.mutex);
  89. }
  90. main_event.flag = 0;
  91. pthread_mutex_unlock(&main_event.mutex);
  92. printf("count = %lu\n", count);
  93. }
  94. usleep(10);
  95. }
  96. return 0;
  97. }
  98. #include <finsh.h>
  99. FINSH_FUNCTION_EXPORT(libc_ex7, example 7 for libc);