]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/processor-trace/libipt/test/src/ptunit-event_queue.c
Import libxo-1.3.0:
[FreeBSD/FreeBSD.git] / contrib / processor-trace / libipt / test / src / ptunit-event_queue.c
1 /*
2  * Copyright (c) 2014-2019, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *  * Redistributions of source code must retain the above copyright notice,
8  *    this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  *  * Neither the name of Intel Corporation nor the names of its contributors
13  *    may be used to endorse or promote products derived from this software
14  *    without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "ptunit.h"
30
31 #include "pt_event_queue.h"
32
33
34 /* A test fixture providing an initialized event queue. */
35 struct evq_fixture {
36         /* The event queue. */
37         struct pt_event_queue evq;
38
39         /* The test fixture initialization and finalization functions. */
40         struct ptunit_result (*init)(struct evq_fixture *);
41         struct ptunit_result (*fini)(struct evq_fixture *);
42 };
43
44
45 static struct ptunit_result efix_init(struct evq_fixture *efix)
46 {
47         pt_evq_init(&efix->evq);
48
49         return ptu_passed();
50 }
51
52 static struct ptunit_result efix_init_pending(struct evq_fixture *efix)
53 {
54         struct pt_event *ev;
55         int evb;
56
57         pt_evq_init(&efix->evq);
58
59         for (evb = 0; evb < evb_max; ++evb) {
60                 ev = pt_evq_enqueue(&efix->evq, (enum pt_event_binding) evb);
61                 ptu_ptr(ev);
62         }
63
64         return ptu_passed();
65 }
66
67 static struct ptunit_result standalone_null(void)
68 {
69         struct pt_event *ev;
70
71         ev = pt_evq_standalone(NULL);
72         ptu_null(ev);
73
74         return ptu_passed();
75 }
76
77 static struct ptunit_result standalone(struct evq_fixture *efix)
78 {
79         struct pt_event *ev;
80
81         ev = pt_evq_standalone(&efix->evq);
82         ptu_ptr(ev);
83         ptu_uint_eq(ev->ip_suppressed, 0ul);
84         ptu_uint_eq(ev->status_update, 0ul);
85
86         return ptu_passed();
87 }
88
89 static struct ptunit_result enqueue_null(enum pt_event_binding evb)
90 {
91         struct pt_event *ev;
92
93         ev = pt_evq_enqueue(NULL, evb);
94         ptu_null(ev);
95
96         return ptu_passed();
97 }
98
99 static struct ptunit_result dequeue_null(enum pt_event_binding evb)
100 {
101         struct pt_event *ev;
102
103         ev = pt_evq_dequeue(NULL, evb);
104         ptu_null(ev);
105
106         return ptu_passed();
107 }
108
109 static struct ptunit_result dequeue_empty(struct evq_fixture *efix,
110                                           enum pt_event_binding evb)
111 {
112         struct pt_event *ev;
113
114         ev = pt_evq_dequeue(&efix->evq, evb);
115         ptu_null(ev);
116
117         return ptu_passed();
118 }
119
120 static struct ptunit_result evq_empty(struct evq_fixture *efix,
121                                       enum pt_event_binding evb)
122 {
123         int status;
124
125         status = pt_evq_empty(&efix->evq, evb);
126         ptu_int_gt(status, 0);
127
128         status = pt_evq_pending(&efix->evq, evb);
129         ptu_int_eq(status, 0);
130
131         return ptu_passed();
132 }
133
134 static struct ptunit_result evq_pending(struct evq_fixture *efix,
135                                         enum pt_event_binding evb)
136 {
137         int status;
138
139         status = pt_evq_empty(&efix->evq, evb);
140         ptu_int_eq(status, 0);
141
142         status = pt_evq_pending(&efix->evq, evb);
143         ptu_int_gt(status, 0);
144
145         return ptu_passed();
146 }
147
148 static struct ptunit_result evq_others_empty(struct evq_fixture *efix,
149                                              enum pt_event_binding evb)
150 {
151         int other;
152
153         for (other = 0; other < evb_max; ++other) {
154                 enum pt_event_binding ob;
155
156                 ob = (enum pt_event_binding) other;
157                 if (ob != evb)
158                         ptu_test(evq_empty, efix, ob);
159         }
160
161         return ptu_passed();
162 }
163
164 static struct ptunit_result enqueue_all_dequeue(struct evq_fixture *efix,
165                                                 enum pt_event_binding evb,
166                                                 size_t num)
167 {
168         struct pt_event *in[evq_max], *out[evq_max];
169         size_t idx;
170
171         ptu_uint_le(num, evq_max - 2);
172
173         for (idx = 0; idx < num; ++idx) {
174                 in[idx] = pt_evq_enqueue(&efix->evq, evb);
175                 ptu_ptr(in[idx]);
176         }
177
178         ptu_test(evq_pending, efix, evb);
179         ptu_test(evq_others_empty, efix, evb);
180
181         for (idx = 0; idx < num; ++idx) {
182                 out[idx] = pt_evq_dequeue(&efix->evq, evb);
183                 ptu_ptr_eq(out[idx], in[idx]);
184         }
185
186         ptu_test(evq_empty, efix, evb);
187
188         return ptu_passed();
189 }
190
191 static struct ptunit_result enqueue_one_dequeue(struct evq_fixture *efix,
192                                                 enum pt_event_binding evb,
193                                                 size_t num)
194 {
195         size_t idx;
196
197         for (idx = 0; idx < num; ++idx) {
198                 struct pt_event *in, *out;
199
200                 in = pt_evq_enqueue(&efix->evq, evb);
201                 ptu_ptr(in);
202
203                 out = pt_evq_dequeue(&efix->evq, evb);
204                 ptu_ptr_eq(out, in);
205         }
206
207         return ptu_passed();
208 }
209
210 static struct ptunit_result overflow(struct evq_fixture *efix,
211                                      enum pt_event_binding evb,
212                                      size_t num)
213 {
214         struct pt_event *in[evq_max], *out[evq_max], *ev;
215         size_t idx;
216
217         ptu_uint_le(num, evq_max - 2);
218
219         for (idx = 0; idx < (evq_max - 2); ++idx) {
220                 in[idx] = pt_evq_enqueue(&efix->evq, evb);
221                 ptu_ptr(in[idx]);
222         }
223
224         for (idx = 0; idx < num; ++idx) {
225                 ev = pt_evq_enqueue(&efix->evq, evb);
226                 ptu_null(ev);
227         }
228
229         for (idx = 0; idx < num; ++idx) {
230                 out[idx] = pt_evq_dequeue(&efix->evq, evb);
231                 ptu_ptr_eq(out[idx], in[idx]);
232         }
233
234         return ptu_passed();
235 }
236
237 static struct ptunit_result clear_null(enum pt_event_binding evb)
238 {
239         int errcode;
240
241         errcode = pt_evq_clear(NULL, evb);
242         ptu_int_eq(errcode, -pte_internal);
243
244         return ptu_passed();
245 }
246
247 static struct ptunit_result clear(struct evq_fixture *efix,
248                                   enum pt_event_binding evb)
249 {
250         int errcode;
251
252         errcode = pt_evq_clear(&efix->evq, evb);
253         ptu_int_eq(errcode, 0);
254
255         ptu_test(evq_empty, efix, evb);
256
257         return ptu_passed();
258 }
259
260 static struct ptunit_result empty_null(enum pt_event_binding evb)
261 {
262         int errcode;
263
264         errcode = pt_evq_empty(NULL, evb);
265         ptu_int_eq(errcode, -pte_internal);
266
267         return ptu_passed();
268 }
269
270 static struct ptunit_result pending_null(enum pt_event_binding evb)
271 {
272         int errcode;
273
274         errcode = pt_evq_pending(NULL, evb);
275         ptu_int_eq(errcode, -pte_internal);
276
277         return ptu_passed();
278 }
279
280 static struct ptunit_result find_null(enum pt_event_binding evb,
281                                       enum pt_event_type evt)
282 {
283         struct pt_event *ev;
284
285         ev = pt_evq_find(NULL, evb, evt);
286         ptu_null(ev);
287
288         return ptu_passed();
289 }
290
291 static struct ptunit_result find_empty(struct evq_fixture *efix,
292                                        enum pt_event_binding evb,
293                                        enum pt_event_type evt)
294 {
295         struct pt_event *ev;
296
297         ev = pt_evq_find(&efix->evq, evb, evt);
298         ptu_null(ev);
299
300         return ptu_passed();
301 }
302
303 static struct ptunit_result find_none_evb(struct evq_fixture *efix,
304                                           enum pt_event_binding evb,
305                                           enum pt_event_type evt)
306 {
307         struct pt_event *ev;
308         size_t other;
309
310         for (other = 0; other < evb_max; ++other) {
311                 enum pt_event_binding ob;
312
313                 ob = (enum pt_event_binding) other;
314                 if (ob != evb) {
315                         ev = pt_evq_enqueue(&efix->evq, ob);
316                         ptu_ptr(ev);
317
318                         ev->type = evt;
319                 }
320         }
321
322         ev = pt_evq_find(&efix->evq, evb, evt);
323         ptu_null(ev);
324
325         return ptu_passed();
326 }
327
328 static struct ptunit_result evq_enqueue_other(struct evq_fixture *efix,
329                                               enum pt_event_binding evb,
330                                               enum pt_event_type evt,
331                                               size_t num)
332 {
333         enum pt_event_type ot;
334         struct pt_event *ev;
335         size_t other;
336
337         for (other = 0; other < num; ++other) {
338                 ot = (enum pt_event_type) other;
339                 if (ot != evt) {
340                         ev = pt_evq_enqueue(&efix->evq, evb);
341                         ptu_ptr(ev);
342
343                         ev->type = ot;
344                 }
345         }
346
347         return ptu_passed();
348 }
349
350 static struct ptunit_result find_none_evt(struct evq_fixture *efix,
351                                           enum pt_event_binding evb,
352                                           enum pt_event_type evt,
353                                           size_t num)
354 {
355         struct pt_event *ev;
356
357         ptu_test(evq_enqueue_other, efix, evb, evt, num);
358
359         ev = pt_evq_find(&efix->evq, evb, evt);
360         ptu_null(ev);
361
362         return ptu_passed();
363 }
364
365 static struct ptunit_result find(struct evq_fixture *efix,
366                                  enum pt_event_binding evb,
367                                  enum pt_event_type evt,
368                                  size_t before, size_t after)
369 {
370         struct pt_event *in, *out;
371
372         ptu_test(evq_enqueue_other, efix, evb, evt, before);
373
374         in = pt_evq_enqueue(&efix->evq, evb);
375         ptu_ptr(in);
376
377         in->type = evt;
378
379         ptu_test(evq_enqueue_other, efix, evb, evt, after);
380
381         out = pt_evq_find(&efix->evq, evb, evt);
382         ptu_ptr_eq(out, in);
383
384         return ptu_passed();
385 }
386
387 int main(int argc, char **argv)
388 {
389         struct evq_fixture efix, pfix;
390         struct ptunit_suite suite;
391
392         efix.init = efix_init;
393         efix.fini = NULL;
394
395         pfix.init = efix_init_pending;
396         pfix.fini = NULL;
397
398         suite = ptunit_mk_suite(argc, argv);
399
400         ptu_run(suite, standalone_null);
401         ptu_run_f(suite, standalone, efix);
402
403         ptu_run_p(suite, enqueue_null, evb_psbend);
404         ptu_run_p(suite, enqueue_null, evb_tip);
405         ptu_run_p(suite, enqueue_null, evb_fup);
406
407         ptu_run_p(suite, dequeue_null, evb_psbend);
408         ptu_run_p(suite, dequeue_null, evb_tip);
409         ptu_run_p(suite, dequeue_null, evb_fup);
410
411         ptu_run_fp(suite, dequeue_empty, efix, evb_psbend);
412         ptu_run_fp(suite, dequeue_empty, efix, evb_tip);
413         ptu_run_fp(suite, dequeue_empty, efix, evb_fup);
414
415         ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_psbend, 1);
416         ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_psbend, 2);
417         ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_tip, 1);
418         ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_tip, 3);
419         ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_fup, 1);
420         ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_fup, 4);
421
422         ptu_run_fp(suite, enqueue_one_dequeue, efix, evb_psbend, evb_max * 2);
423         ptu_run_fp(suite, enqueue_one_dequeue, efix, evb_tip, evb_max * 2);
424         ptu_run_fp(suite, enqueue_one_dequeue, efix, evb_fup, evb_max * 2);
425
426         ptu_run_fp(suite, overflow, efix, evb_psbend, 1);
427         ptu_run_fp(suite, overflow, efix, evb_tip, 2);
428         ptu_run_fp(suite, overflow, efix, evb_fup, 3);
429
430         ptu_run_p(suite, clear_null, evb_psbend);
431         ptu_run_p(suite, clear_null, evb_tip);
432         ptu_run_p(suite, clear_null, evb_fup);
433
434         ptu_run_fp(suite, clear, efix, evb_psbend);
435         ptu_run_fp(suite, clear, pfix, evb_psbend);
436         ptu_run_fp(suite, clear, efix, evb_tip);
437         ptu_run_fp(suite, clear, pfix, evb_tip);
438         ptu_run_fp(suite, clear, efix, evb_fup);
439         ptu_run_fp(suite, clear, pfix, evb_fup);
440
441         ptu_run_p(suite, empty_null, evb_psbend);
442         ptu_run_p(suite, empty_null, evb_tip);
443         ptu_run_p(suite, empty_null, evb_fup);
444
445         ptu_run_p(suite, pending_null, evb_psbend);
446         ptu_run_p(suite, pending_null, evb_tip);
447         ptu_run_p(suite, pending_null, evb_fup);
448
449         ptu_run_p(suite, find_null, evb_psbend, ptev_enabled);
450         ptu_run_p(suite, find_null, evb_tip, ptev_disabled);
451         ptu_run_p(suite, find_null, evb_fup, ptev_paging);
452
453         ptu_run_fp(suite, find_empty, efix, evb_psbend, ptev_enabled);
454         ptu_run_fp(suite, find_empty, efix, evb_tip, ptev_disabled);
455         ptu_run_fp(suite, find_empty, efix, evb_fup, ptev_paging);
456
457         ptu_run_fp(suite, find_none_evb, efix, evb_psbend, ptev_enabled);
458         ptu_run_fp(suite, find_none_evb, efix, evb_tip, ptev_disabled);
459         ptu_run_fp(suite, find_none_evb, efix, evb_fup, ptev_paging);
460
461         ptu_run_fp(suite, find_none_evt, efix, evb_psbend, ptev_enabled, 3);
462         ptu_run_fp(suite, find_none_evt, efix, evb_tip, ptev_disabled, 4);
463         ptu_run_fp(suite, find_none_evt, efix, evb_fup, ptev_paging, 2);
464
465         ptu_run_fp(suite, find, efix, evb_psbend, ptev_enabled, 0, 3);
466         ptu_run_fp(suite, find, efix, evb_tip, ptev_disabled, 2, 0);
467         ptu_run_fp(suite, find, efix, evb_fup, ptev_paging, 1, 4);
468
469         return ptunit_report(&suite);
470 }