host stack: update stale copyright
[vpp.git] / src / svm / test_svm_message_queue.c
1 /*
2  * Copyright (c) 2018-2019 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <svm/ssvm.h>
17 #include <svm/message_queue.h>
18
19 #define test1_error(_fmt, _args...)                     \
20 {                                                       \
21     ssvm_pop_heap (oldheap);                            \
22     error = clib_error_return (0, _fmt, ##_args);       \
23     goto done;                                          \
24 }
25
26 clib_error_t *
27 test1 (int verbose)
28 {
29   ssvm_private_t _ssvm, *ssvm = &_ssvm;
30   svm_msg_q_cfg_t _cfg, *cfg = &_cfg;
31   svm_msg_q_msg_t msg1, msg2, msg[12];
32   ssvm_shared_header_t *sh;
33   clib_error_t *error = 0;
34   svm_msg_q_t *mq;
35   void *oldheap;
36   int i;
37
38   clib_memset (ssvm, 0, sizeof (*ssvm));
39
40   ssvm->ssvm_size = 1 << 20;
41   ssvm->i_am_master = 1;
42   ssvm->my_pid = getpid ();
43   ssvm->name = format (0, "%s%c", "test", 0);
44   ssvm->requested_va = 0;
45
46   if (ssvm_master_init (ssvm, SSVM_SEGMENT_SHM))
47     return clib_error_return (0, "failed: segment allocation");
48   sh = ssvm->sh;
49
50   svm_msg_q_ring_cfg_t rc[2]= {{8, 8, 0}, {8, 16, 0}};
51   cfg->consumer_pid = ~0;
52   cfg->n_rings = 2;
53   cfg->q_nitems = 16;
54   cfg->ring_cfgs = rc;
55
56   oldheap = ssvm_push_heap (sh);
57   mq = svm_msg_q_alloc (cfg);
58   if (!mq)
59     test1_error ("failed: alloc");
60
61   if (vec_len (mq->rings) != 2)
62       test1_error ("failed: ring allocation");
63
64   msg1 = svm_msg_q_alloc_msg (mq, 8);
65   if (mq->rings[0].cursize != 1
66       || msg1.ring_index != 0
67       || msg1.elt_index != 0)
68     test1_error ("failed: msg alloc1");
69
70   msg2 = svm_msg_q_alloc_msg (mq, 15);
71   if (mq->rings[1].cursize != 1
72       || msg2.ring_index != 1
73       || msg2.elt_index != 0)
74       test1_error ("failed: msg alloc2");
75
76   svm_msg_q_free_msg (mq, &msg1);
77   if (mq->rings[0].cursize != 0)
78     test1_error("failed: free msg");
79
80   for (i = 0; i < 12; i++)
81     {
82       msg[i] = svm_msg_q_alloc_msg (mq, 7);
83       *(u32 *)svm_msg_q_msg_data (mq, &msg[i]) = i;
84     }
85
86   if (mq->rings[0].cursize != 8
87       || mq->rings[1].cursize != 5)
88       test1_error ("failed: msg alloc3");
89
90   *(u32 *)svm_msg_q_msg_data (mq, &msg2) = 123;
91   svm_msg_q_add (mq, &msg2, SVM_Q_NOWAIT);
92   for (i = 0; i < 12; i++)
93     svm_msg_q_add (mq, &msg[i], SVM_Q_NOWAIT);
94
95   if (svm_msg_q_sub (mq, &msg2, SVM_Q_NOWAIT, 0))
96     test1_error ("failed: dequeue1");
97
98   if (msg2.ring_index != 1 || msg2.elt_index != 0)
99     test1_error ("failed: dequeue1 result");
100   if (*(u32 *)svm_msg_q_msg_data (mq, &msg2) != 123)
101     test1_error ("failed: dequeue1 wrong data");
102
103   svm_msg_q_free_msg (mq, &msg2);
104
105   for (i = 0; i < 12; i++)
106     {
107       if (svm_msg_q_sub (mq, &msg[i], SVM_Q_NOWAIT, 0))
108         test1_error ("failed: dequeue2");
109       if (i < 8)
110         {
111           if (msg[i].ring_index != 0 || msg[i].elt_index != (i + 1) % 8)
112             test1_error ("failed: dequeue2 result2");
113         }
114       else
115         {
116           if (msg[i].ring_index != 1 || msg[i].elt_index != (i - 8) + 1)
117             test1_error ("failed: dequeue2 result3");
118         }
119       if (*(u32 *)svm_msg_q_msg_data (mq, &msg[i]) != i)
120         test1_error ("failed: dequeue2 wrong data");
121       svm_msg_q_free_msg (mq, &msg[i]);
122     }
123   if (mq->rings[0].cursize != 0 || mq->rings[1].cursize != 0)
124     test1_error ("failed: post dequeue");
125
126   ssvm_pop_heap (oldheap);
127
128 done:
129   ssvm_delete (ssvm);
130   return error;
131 }
132
133 int
134 test_svm_message_queue (unformat_input_t * input)
135 {
136   clib_error_t *error = 0;
137   int verbose = 0;
138   int test_id = 0;
139
140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
141     {
142       if (unformat (input, "test1"))
143         test_id = 1;
144       else
145         {
146           error = clib_error_create ("unknown input `%U'\n",
147                                      format_unformat_error, input);
148           goto out;
149         }
150     }
151
152   switch (test_id)
153     {
154     case 1:
155       error = test1 (verbose);
156     }
157 out:
158   if (error)
159     clib_error_report (error);
160   else
161     clib_warning ("success");
162
163   return 0;
164 }
165
166 int
167 main (int argc, char *argv[])
168 {
169   unformat_input_t i;
170   int r;
171
172   clib_mem_init_thread_safe (0, 256 << 20);
173   unformat_init_command_line (&i, argv);
174   r = test_svm_message_queue (&i);
175   unformat_free (&i);
176   return r;
177 }