2021-03-08 07:18:51 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*
|
|
|
|
* Change Logs:
|
|
|
|
* Date Author Notes
|
|
|
|
*/
|
2010-11-18 19:31:54 +08:00
|
|
|
/* ex7
|
|
|
|
*
|
|
|
|
* Test case that illustrates a timed wait on a condition variable.
|
|
|
|
*/
|
|
|
|
|
2021-05-22 02:50:35 +08:00
|
|
|
#include <sys/errno.h>
|
2010-11-18 19:31:54 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2024-08-14 07:36:32 +08:00
|
|
|
#define usleep rt_thread_delay
|
2010-11-18 19:31:54 +08:00
|
|
|
|
|
|
|
/* Our event variable using a condition variable contruct. */
|
|
|
|
typedef struct {
|
2021-03-07 08:34:04 +08:00
|
|
|
pthread_mutex_t mutex;
|
|
|
|
pthread_cond_t cond;
|
|
|
|
int flag;
|
2010-11-18 19:31:54 +08:00
|
|
|
} event_t;
|
|
|
|
|
|
|
|
/* Global event to signal main thread the timeout of the child thread. */
|
|
|
|
event_t main_event;
|
|
|
|
|
|
|
|
static void *test_thread(void *ms_param) {
|
2021-03-07 08:34:04 +08:00
|
|
|
int status = 0;
|
|
|
|
event_t foo;
|
|
|
|
struct timespec time;
|
|
|
|
struct timeval now;
|
|
|
|
long ms = (long) ms_param;
|
|
|
|
|
|
|
|
/* initialize cond var */
|
|
|
|
pthread_cond_init(&foo.cond, NULL);
|
|
|
|
pthread_mutex_init(&foo.mutex, NULL);
|
|
|
|
foo.flag = 0;
|
|
|
|
|
|
|
|
/* set the time out value */
|
|
|
|
printf("waiting %ld ms ...\n", ms);
|
|
|
|
gettimeofday(&now, NULL);
|
|
|
|
time.tv_sec = now.tv_sec + ms / 1000 + (now.tv_usec + (ms % 1000) * 1000)
|
|
|
|
/ 1000000;
|
|
|
|
time.tv_nsec = ((now.tv_usec + (ms % 1000) * 1000) % 1000000) * 1000;
|
|
|
|
|
|
|
|
/* Just use this to test the time out. The cond var is never signaled. */
|
|
|
|
pthread_mutex_lock(&foo.mutex);
|
|
|
|
while (foo.flag == 0 && status != ETIMEDOUT) {
|
|
|
|
status = pthread_cond_timedwait(&foo.cond, &foo.mutex, &time);
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&foo.mutex);
|
|
|
|
|
|
|
|
/* post the main event */
|
|
|
|
pthread_mutex_lock(&main_event.mutex);
|
|
|
|
main_event.flag = 1;
|
|
|
|
pthread_cond_signal(&main_event.cond);
|
|
|
|
pthread_mutex_unlock(&main_event.mutex);
|
|
|
|
|
|
|
|
/* that's it, bye */
|
|
|
|
return (void*) status;
|
2010-11-18 19:31:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int libc_ex7(void) {
|
2021-03-07 08:34:04 +08:00
|
|
|
unsigned long count;
|
|
|
|
|
|
|
|
setvbuf(stdout, NULL, _IONBF, 0);
|
|
|
|
|
|
|
|
/* initialize main event cond var */
|
|
|
|
pthread_cond_init(&main_event.cond, NULL);
|
|
|
|
pthread_mutex_init(&main_event.mutex, NULL);
|
|
|
|
main_event.flag = 0;
|
|
|
|
|
|
|
|
for (count = 0; count < 20; ++count) {
|
|
|
|
pthread_t thread;
|
|
|
|
int status;
|
|
|
|
|
|
|
|
/* pass down the milli-second timeout in the void* param */
|
|
|
|
status = pthread_create(&thread, NULL, test_thread, (void*) (count
|
|
|
|
* 100));
|
|
|
|
if (status != 0) {
|
|
|
|
printf("status = %d, count = %lu: %s\n", status, count, strerror(
|
|
|
|
errno));
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/* wait for the event posted by the child thread */
|
|
|
|
pthread_mutex_lock(&main_event.mutex);
|
|
|
|
while (main_event.flag == 0) {
|
|
|
|
pthread_cond_wait(&main_event.cond, &main_event.mutex);
|
|
|
|
}
|
|
|
|
main_event.flag = 0;
|
|
|
|
pthread_mutex_unlock(&main_event.mutex);
|
|
|
|
|
|
|
|
printf("count = %lu\n", count);
|
|
|
|
}
|
|
|
|
|
|
|
|
usleep(10);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2010-11-18 19:31:54 +08:00
|
|
|
}
|
|
|
|
#include <finsh.h>
|
|
|
|
FINSH_FUNCTION_EXPORT(libc_ex7, example 7 for libc);
|