hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <copperplate/traceobj.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>
 
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);
}