#include #include #include #include #include #include #include static struct traceobj trobj; static RT_TASK t_real; static RT_PIPE mpipe; static pthread_t t_reg; static int minor; struct pipe_message { int value; }; static void realtime_task(void *arg) { struct pipe_message m; int ret, seq = 0; traceobj_enter(&trobj); ret = rt_pipe_bind(&mpipe, "pipe", TM_INFINITE); traceobj_check(&trobj, ret, 0); while (seq < 8192) { ret = rt_pipe_read(&mpipe, &m, sizeof(m), TM_INFINITE); traceobj_assert(&trobj, ret == sizeof(m)); traceobj_assert(&trobj, m.value == seq); ret = rt_pipe_write(&mpipe, &m, sizeof(m), (seq & 1) ? P_URGENT : P_NORMAL); traceobj_assert(&trobj, ret == sizeof(m)); seq++; } pthread_cancel(t_reg); traceobj_exit(&trobj); } static void *regular_thread(void *arg) { struct pipe_message m; int fd, seq = 0; ssize_t ret; char *rtp; asprintf(&rtp, "/dev/rtp%d", minor); fd = open(rtp, O_RDWR); free(rtp); traceobj_assert(&trobj, fd >= 0); for (;;) { m.value = seq; ret = write(fd, &m, sizeof(m)); traceobj_assert(&trobj, ret == sizeof(m)); ret = read(fd, &m, sizeof(m)); traceobj_assert(&trobj, ret == sizeof(m)); traceobj_assert(&trobj, m.value == seq); seq++; } return NULL; } int main(int argc, char *const argv[]) { struct timespec ts_start, ts_end, ts_timeout, ts_delta; struct pipe_message m; RTIME start, end; SRTIME timeout; int ret; traceobj_init(&trobj, argv[0], 0); ret = rt_pipe_create(&mpipe, "pipe", P_MINOR_AUTO, 0); traceobj_assert(&trobj, ret >= 0); ret = rt_pipe_delete(&mpipe); traceobj_check(&trobj, ret, 0); ret = rt_task_create(&t_real, "realtime", 0, 10, 0); traceobj_check(&trobj, ret, 0); ret = rt_task_start(&t_real, realtime_task, NULL); traceobj_check(&trobj, ret, 0); ret = rt_pipe_create(&mpipe, "pipe", P_MINOR_AUTO, 16384); traceobj_assert(&trobj, ret >= 0); minor = ret; ret = rt_pipe_read(&mpipe, &m, sizeof(m), TM_NONBLOCK); traceobj_check(&trobj, ret, -EWOULDBLOCK); ret = rt_pipe_read_until(&mpipe, &m, sizeof(m), TM_NONBLOCK); traceobj_check(&trobj, ret, -EWOULDBLOCK); ts_timeout.tv_sec = 0; ts_timeout.tv_nsec = 0; ret = rt_pipe_read_timed(&mpipe, &m, sizeof(m), &ts_timeout); traceobj_check(&trobj, ret, -EWOULDBLOCK); start = rt_timer_read(); timeout = rt_timer_ns2ticks(100000000); ret = rt_pipe_read(&mpipe, &m, sizeof(m), timeout); end = rt_timer_read(); traceobj_assert(&trobj, end - start >= timeout); traceobj_assert(&trobj, end - start < timeout + rt_timer_ns2ticks(5000000)); start = rt_timer_read(); timeout = start + rt_timer_ns2ticks(100000000); ret = rt_pipe_read_until(&mpipe, &m, sizeof(m), timeout); end = rt_timer_read(); traceobj_assert(&trobj, end >= timeout); traceobj_assert(&trobj, end < timeout + rt_timer_ns2ticks(5000000)); clock_gettime(CLOCK_COPPERPLATE, &ts_start); timespec_adds(&ts_timeout, &ts_start, 100000000); ret = rt_pipe_read_timed(&mpipe, &m, sizeof(m), &ts_timeout); clock_gettime(CLOCK_COPPERPLATE, &ts_end); timespec_sub(&ts_delta, &ts_end, &ts_timeout); traceobj_assert(&trobj, ts_delta.tv_sec >= 0); traceobj_assert(&trobj, ts_delta.tv_nsec < 5000000); ret = pthread_create(&t_reg, NULL, regular_thread, NULL); traceobj_check(&trobj, ret, 0); traceobj_join(&trobj); exit(0); }