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 } 471