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