VPP-598: tcp stack initial commit
[vpp.git] / src / svm / test_svm_fifo1.c
1 /*
2  * Copyright (c) 2016 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_fifo_segment.h"
17
18 clib_error_t *
19 hello_world (int verbose)
20 {
21   svm_fifo_segment_create_args_t _a, *a = &_a;
22   svm_fifo_segment_private_t *sp;
23   svm_fifo_t *f;
24   int rv;
25   u8 *test_data;
26   u8 *retrieved_data = 0;
27   clib_error_t *error = 0;
28   int pid = getpid ();
29
30   memset (a, 0, sizeof (*a));
31
32   a->segment_name = "fifo-test1";
33   a->segment_size = 256 << 10;
34
35   rv = svm_fifo_segment_create (a);
36
37   if (rv)
38     return clib_error_return (0, "svm_fifo_segment_create returned %d", rv);
39
40   sp = svm_fifo_get_segment (a->new_segment_index);
41
42   f = svm_fifo_segment_alloc_fifo (sp, 4096);
43
44   if (f == 0)
45     return clib_error_return (0, "svm_fifo_segment_alloc_fifo failed");
46
47   test_data = format (0, "Hello world%c", 0);
48   vec_validate (retrieved_data, vec_len (test_data) - 1);
49
50   while (svm_fifo_max_enqueue (f) >= vec_len (test_data))
51     svm_fifo_enqueue_nowait (f, pid, vec_len (test_data), test_data);
52
53   while (svm_fifo_max_dequeue (f) >= vec_len (test_data))
54     svm_fifo_dequeue_nowait (f, pid, vec_len (retrieved_data),
55                              retrieved_data);
56
57   while (svm_fifo_max_enqueue (f) >= vec_len (test_data))
58     svm_fifo_enqueue_nowait (f, pid, vec_len (test_data), test_data);
59
60   while (svm_fifo_max_dequeue (f) >= vec_len (test_data))
61     svm_fifo_dequeue_nowait (f, pid, vec_len (retrieved_data),
62                              retrieved_data);
63
64   if (!memcmp (retrieved_data, test_data, vec_len (test_data)))
65     error = clib_error_return (0, "data test OK, got '%s'", retrieved_data);
66   else
67     error = clib_error_return (0, "data test FAIL!");
68
69   svm_fifo_segment_free_fifo (sp, f);
70
71   return error;
72 }
73
74 clib_error_t *
75 master (int verbose)
76 {
77   svm_fifo_segment_create_args_t _a, *a = &_a;
78   svm_fifo_segment_private_t *sp;
79   svm_fifo_t *f;
80   int rv;
81   u8 *test_data;
82   u8 *retrieved_data = 0;
83   int i;
84   int pid = getpid ();
85
86   memset (a, 0, sizeof (*a));
87
88   a->segment_name = "fifo-test1";
89   a->segment_size = 256 << 10;
90
91   rv = svm_fifo_segment_create (a);
92
93   if (rv)
94     return clib_error_return (0, "svm_fifo_segment_create returned %d", rv);
95
96   sp = svm_fifo_get_segment (a->new_segment_index);
97
98   f = svm_fifo_segment_alloc_fifo (sp, 4096);
99
100   if (f == 0)
101     return clib_error_return (0, "svm_fifo_segment_alloc_fifo failed");
102
103   test_data = format (0, "Hello world%c", 0);
104   vec_validate (retrieved_data, vec_len (test_data) - 1);
105
106   for (i = 0; i < 1000; i++)
107     svm_fifo_enqueue_nowait (f, pid, vec_len (test_data), test_data);
108
109   return clib_error_return (0, "master (enqueue) done");
110 }
111
112 clib_error_t *
113 mempig (int verbose)
114 {
115   svm_fifo_segment_create_args_t _a, *a = &_a;
116   svm_fifo_segment_private_t *sp;
117   svm_fifo_t *f;
118   svm_fifo_t **flist = 0;
119   int rv;
120   int i;
121
122   memset (a, 0, sizeof (*a));
123
124   a->segment_name = "fifo-test1";
125   a->segment_size = 256 << 10;
126
127   rv = svm_fifo_segment_create (a);
128
129   if (rv)
130     return clib_error_return (0, "svm_fifo_segment_create returned %d", rv);
131
132   sp = svm_fifo_get_segment (a->new_segment_index);
133
134   for (i = 0; i < 1000; i++)
135     {
136       f = svm_fifo_segment_alloc_fifo (sp, 4096);
137       if (f == 0)
138         break;
139       vec_add1 (flist, f);
140     }
141
142   fformat (stdout, "Try #1: created %d fifos...\n", vec_len (flist));
143   for (i = 0; i < vec_len (flist); i++)
144     {
145       f = flist[i];
146       svm_fifo_segment_free_fifo (sp, f);
147     }
148
149   _vec_len (flist) = 0;
150
151   for (i = 0; i < 1000; i++)
152     {
153       f = svm_fifo_segment_alloc_fifo (sp, 4096);
154       if (f == 0)
155         break;
156       vec_add1 (flist, f);
157     }
158
159   fformat (stdout, "Try #2: created %d fifos...\n", vec_len (flist));
160   for (i = 0; i < vec_len (flist); i++)
161     {
162       f = flist[i];
163       svm_fifo_segment_free_fifo (sp, f);
164     }
165
166   return 0;
167 }
168
169 clib_error_t *
170 offset (int verbose)
171 {
172   svm_fifo_segment_create_args_t _a, *a = &_a;
173   svm_fifo_segment_private_t *sp;
174   svm_fifo_t *f;
175   int rv;
176   u32 *test_data = 0;
177   u32 *recovered_data = 0;
178   int i;
179   int pid = getpid ();
180
181   memset (a, 0, sizeof (*a));
182
183   a->segment_name = "fifo-test1";
184   a->segment_size = 256 << 10;
185
186   rv = svm_fifo_segment_create (a);
187
188   if (rv)
189     return clib_error_return (0, "svm_fifo_segment_create returned %d", rv);
190
191   sp = svm_fifo_get_segment (a->new_segment_index);
192
193   f = svm_fifo_segment_alloc_fifo (sp, 200 << 10);
194
195   if (f == 0)
196     return clib_error_return (0, "svm_fifo_segment_alloc_fifo failed");
197
198   for (i = 0; i < (3 * 1024); i++)
199     vec_add1 (test_data, i);
200
201   /* Enqueue the first 1024 u32's */
202   svm_fifo_enqueue_nowait (f, pid, 4096 /* bytes to enqueue */ ,
203                            (u8 *) test_data);
204
205   /* Enqueue the third 1024 u32's 2048 ahead of the current tail */
206   svm_fifo_enqueue_with_offset (f, pid, 4096, 4096, (u8 *) & test_data[2048]);
207
208   /* Enqueue the second 1024 u32's at the current tail */
209   svm_fifo_enqueue_nowait (f, pid, 4096 /* bytes to enqueue */ ,
210                            (u8 *) & test_data[1024]);
211
212   vec_validate (recovered_data, (3 * 1024) - 1);
213
214   svm_fifo_dequeue_nowait (f, pid, 3 * 4096, (u8 *) recovered_data);
215
216   for (i = 0; i < (3 * 1024); i++)
217     {
218       if (recovered_data[i] != test_data[i])
219         {
220           clib_warning ("[%d] expected %d recovered %d", i,
221                         test_data[i], recovered_data[i]);
222           return clib_error_return (0, "offset test FAILED");
223         }
224     }
225
226   return clib_error_return (0, "offset test OK");
227 }
228
229 clib_error_t *
230 slave (int verbose)
231 {
232   svm_fifo_segment_create_args_t _a, *a = &_a;
233   svm_fifo_segment_private_t *sp;
234   svm_fifo_segment_header_t *fsh;
235   svm_fifo_t *f;
236   ssvm_shared_header_t *sh;
237   int rv;
238   u8 *test_data;
239   u8 *retrieved_data = 0;
240   int pid = getpid ();
241   int i;
242
243   memset (a, 0, sizeof (*a));
244
245   a->segment_name = "fifo-test1";
246
247   rv = svm_fifo_segment_attach (a);
248
249   if (rv)
250     return clib_error_return (0, "svm_fifo_segment_attach returned %d", rv);
251
252   sp = svm_fifo_get_segment (a->new_segment_index);
253   sh = sp->ssvm.sh;
254   fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
255
256   /* might wanna wait.. */
257   f = (svm_fifo_t *) fsh->fifos[0];
258
259   /* Lazy bastards united */
260   test_data = format (0, "Hello world%c", 0);
261   vec_validate (retrieved_data, vec_len (test_data) - 1);
262
263   for (i = 0; i < 1000; i++)
264     {
265       svm_fifo_dequeue_nowait (f, pid, vec_len (retrieved_data),
266                                retrieved_data);
267       if (memcmp (retrieved_data, test_data, vec_len (retrieved_data)))
268         return clib_error_return (0, "retrieved data incorrect, '%s'",
269                                   retrieved_data);
270     }
271
272   return clib_error_return (0, "slave (dequeue) done");
273 }
274
275
276 int
277 test_ssvm_fifo1 (unformat_input_t * input)
278 {
279   clib_error_t *error = 0;
280   int verbose = 0;
281   int test_id = 0;
282
283   svm_fifo_segment_init (0x200000000ULL, 20);
284
285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
286     {
287       if (unformat (input, "verbose %d", &verbose))
288         ;
289       else if (unformat (input, "verbose"))
290         verbose = 1;
291       else if (unformat (input, "master"))
292         test_id = 1;
293       else if (unformat (input, "slave"))
294         test_id = 2;
295       else if (unformat (input, "mempig"))
296         test_id = 3;
297       else if (unformat (input, "offset"))
298         test_id = 4;
299       else
300         {
301           error = clib_error_create ("unknown input `%U'\n",
302                                      format_unformat_error, input);
303           goto out;
304         }
305     }
306
307   switch (test_id)
308     {
309     case 0:
310       error = hello_world (verbose);
311       break;
312
313     case 1:
314       error = master (verbose);
315       break;
316
317     case 2:
318       error = slave (verbose);
319       break;
320
321     case 3:
322       error = mempig (verbose);
323       break;
324
325     case 4:
326       error = offset (verbose);
327       break;
328
329     default:
330       error = clib_error_return (0, "test id %d unknown", test_id);
331       break;
332     }
333
334 out:
335   if (error)
336     clib_error_report (error);
337
338   return 0;
339 }
340
341
342
343 int
344 main (int argc, char *argv[])
345 {
346   unformat_input_t i;
347   int r;
348
349   unformat_init_command_line (&i, argv);
350   r = test_ssvm_fifo1 (&i);
351   unformat_free (&i);
352   return r;
353 }
354
355 /*
356  * fd.io coding-style-patch-verification: ON
357  *
358  * Local Variables:
359  * eval: (c-set-style "gnu")
360  * End:
361  */