ex7.c 2.9 KB

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