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