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