#include #include #include #include #include #include static struct traceobj trobj; static RT_TASK t_bgnd, t_fgnd; static RT_BUFFER buffer; static void foreground_task(void *arg) { ssize_t ret; char buf[6]; int n = 0; traceobj_enter(&trobj); /* * We should get a short read (1 bytes), then a full read (2 * bytes), and back again. */ for (;;) { memset(buf,0, sizeof(buf)); ret = rt_buffer_read(&buffer, buf, 2, TM_INFINITE); switch (ret) { case -EINVAL: case -EIDRM: /* Fine, deleted. */ goto out; case 1: traceobj_assert(&trobj, buf[0] == ((n / 2) % 26) + 'A'); break; case 2: traceobj_assert(&trobj, atoi(buf) == ((n / 2) % 10) * 11); break; default: traceobj_assert(&trobj, 0); } n++; } out: traceobj_exit(&trobj); } static void background_task(void *arg) { char c = 'A', s[3]; ssize_t ret; int n = 0; traceobj_enter(&trobj); for (;;) { ret = rt_buffer_write(&buffer, &c, 1, TM_INFINITE); if (ret == -EINVAL || ret == -EIDRM) break; traceobj_assert(&trobj, ret == 1); c++; if (c > 'Z') c = 'A'; sprintf(s, "%.2d", 11 * n); ret = rt_buffer_write(&buffer, s, 2, TM_INFINITE); if (ret == -EINVAL || ret == -EIDRM) break; traceobj_assert(&trobj, ret == 2); n = (n + 1) % 10; } traceobj_exit(&trobj); } int main(int argc, char *const argv[]) { int ret; traceobj_init(&trobj, argv[0], 0); ret = rt_buffer_create(&buffer, NULL, 2, B_FIFO); traceobj_check(&trobj, ret, 0); ret = rt_task_shadow(NULL, "main_task", 30, 0); traceobj_check(&trobj, ret, 0); ret = rt_task_create(&t_fgnd, "FGND", 0, 20, 0); traceobj_check(&trobj, ret, 0); ret = rt_task_start(&t_fgnd, foreground_task, NULL); traceobj_check(&trobj, ret, 0); ret = rt_task_create(&t_bgnd, "BGND", 0, 10, 0); traceobj_check(&trobj, ret, 0); ret = rt_task_start(&t_bgnd, background_task, NULL); traceobj_check(&trobj, ret, 0); ret = rt_task_sleep(1500000000ULL); traceobj_check(&trobj, ret, 0); ret = rt_buffer_delete(&buffer); traceobj_check(&trobj, ret, 0); traceobj_join(&trobj); exit(0); }