1 /* 2 * AioContext tests 3 * 4 * Copyright Red Hat, Inc. 2012 5 * 6 * Authors: 7 * Paolo Bonzini <pbonzini@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU LGPL, version 2 or later. 10 * See the COPYING.LIB file in the top-level directory. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "block/aio.h" 15 #include "qapi/error.h" 16 #include "qemu/timer.h" 17 #include "qemu/sockets.h" 18 #include "qemu/error-report.h" 19 #include "qemu/coroutine-core.h" 20 #include "qemu/main-loop.h" 21 22 static AioContext *ctx; 23 24 typedef struct { 25 EventNotifier e; 26 int n; 27 int active; 28 bool auto_set; 29 } EventNotifierTestData; 30 31 /* Wait until event notifier becomes inactive */ 32 static void wait_until_inactive(EventNotifierTestData *data) 33 { 34 while (data->active > 0) { 35 aio_poll(ctx, true); 36 } 37 } 38 39 /* Simple callbacks for testing. */ 40 41 typedef struct { 42 QEMUBH *bh; 43 int n; 44 int max; 45 } BHTestData; 46 47 typedef struct { 48 QEMUTimer timer; 49 QEMUClockType clock_type; 50 int n; 51 int max; 52 int64_t ns; 53 AioContext *ctx; 54 } TimerTestData; 55 56 static void bh_test_cb(void *opaque) 57 { 58 BHTestData *data = opaque; 59 if (++data->n < data->max) { 60 qemu_bh_schedule(data->bh); 61 } 62 } 63 64 static void timer_test_cb(void *opaque) 65 { 66 TimerTestData *data = opaque; 67 if (++data->n < data->max) { 68 timer_mod(&data->timer, 69 qemu_clock_get_ns(data->clock_type) + data->ns); 70 } 71 } 72 73 static void dummy_io_handler_read(EventNotifier *e) 74 { 75 } 76 77 static void bh_delete_cb(void *opaque) 78 { 79 BHTestData *data = opaque; 80 if (++data->n < data->max) { 81 qemu_bh_schedule(data->bh); 82 } else { 83 qemu_bh_delete(data->bh); 84 data->bh = NULL; 85 } 86 } 87 88 static void event_ready_cb(EventNotifier *e) 89 { 90 EventNotifierTestData *data = container_of(e, EventNotifierTestData, e); 91 g_assert(event_notifier_test_and_clear(e)); 92 data->n++; 93 if (data->active > 0) { 94 data->active--; 95 } 96 if (data->auto_set && data->active) { 97 event_notifier_set(e); 98 } 99 } 100 101 /* Tests using aio_*. */ 102 103 static void set_event_notifier(AioContext *nctx, EventNotifier *notifier, 104 EventNotifierHandler *handler) 105 { 106 aio_set_event_notifier(nctx, notifier, handler, NULL, NULL); 107 } 108 109 static void test_bh_schedule(void) 110 { 111 BHTestData data = { .n = 0 }; 112 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 113 114 qemu_bh_schedule(data.bh); 115 g_assert_cmpint(data.n, ==, 0); 116 117 g_assert(aio_poll(ctx, true)); 118 g_assert_cmpint(data.n, ==, 1); 119 120 g_assert(!aio_poll(ctx, false)); 121 g_assert_cmpint(data.n, ==, 1); 122 qemu_bh_delete(data.bh); 123 } 124 125 static void test_bh_schedule10(void) 126 { 127 BHTestData data = { .n = 0, .max = 10 }; 128 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 129 130 qemu_bh_schedule(data.bh); 131 g_assert_cmpint(data.n, ==, 0); 132 133 g_assert(aio_poll(ctx, false)); 134 g_assert_cmpint(data.n, ==, 1); 135 136 g_assert(aio_poll(ctx, true)); 137 g_assert_cmpint(data.n, ==, 2); 138 139 while (data.n < 10) { 140 aio_poll(ctx, true); 141 } 142 g_assert_cmpint(data.n, ==, 10); 143 144 g_assert(!aio_poll(ctx, false)); 145 g_assert_cmpint(data.n, ==, 10); 146 qemu_bh_delete(data.bh); 147 } 148 149 static void test_bh_cancel(void) 150 { 151 BHTestData data = { .n = 0 }; 152 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 153 154 qemu_bh_schedule(data.bh); 155 g_assert_cmpint(data.n, ==, 0); 156 157 qemu_bh_cancel(data.bh); 158 g_assert_cmpint(data.n, ==, 0); 159 160 g_assert(!aio_poll(ctx, false)); 161 g_assert_cmpint(data.n, ==, 0); 162 qemu_bh_delete(data.bh); 163 } 164 165 static void test_bh_delete(void) 166 { 167 BHTestData data = { .n = 0 }; 168 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 169 170 qemu_bh_schedule(data.bh); 171 g_assert_cmpint(data.n, ==, 0); 172 173 qemu_bh_delete(data.bh); 174 g_assert_cmpint(data.n, ==, 0); 175 176 g_assert(!aio_poll(ctx, false)); 177 g_assert_cmpint(data.n, ==, 0); 178 } 179 180 static void test_bh_delete_from_cb(void) 181 { 182 BHTestData data1 = { .n = 0, .max = 1 }; 183 184 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); 185 186 qemu_bh_schedule(data1.bh); 187 g_assert_cmpint(data1.n, ==, 0); 188 189 while (data1.n < data1.max) { 190 aio_poll(ctx, true); 191 } 192 g_assert_cmpint(data1.n, ==, data1.max); 193 g_assert(data1.bh == NULL); 194 195 g_assert(!aio_poll(ctx, false)); 196 } 197 198 static void test_bh_delete_from_cb_many(void) 199 { 200 BHTestData data1 = { .n = 0, .max = 1 }; 201 BHTestData data2 = { .n = 0, .max = 3 }; 202 BHTestData data3 = { .n = 0, .max = 2 }; 203 BHTestData data4 = { .n = 0, .max = 4 }; 204 205 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); 206 data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2); 207 data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3); 208 data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4); 209 210 qemu_bh_schedule(data1.bh); 211 qemu_bh_schedule(data2.bh); 212 qemu_bh_schedule(data3.bh); 213 qemu_bh_schedule(data4.bh); 214 g_assert_cmpint(data1.n, ==, 0); 215 g_assert_cmpint(data2.n, ==, 0); 216 g_assert_cmpint(data3.n, ==, 0); 217 g_assert_cmpint(data4.n, ==, 0); 218 219 g_assert(aio_poll(ctx, false)); 220 g_assert_cmpint(data1.n, ==, 1); 221 g_assert_cmpint(data2.n, ==, 1); 222 g_assert_cmpint(data3.n, ==, 1); 223 g_assert_cmpint(data4.n, ==, 1); 224 g_assert(data1.bh == NULL); 225 226 while (data1.n < data1.max || 227 data2.n < data2.max || 228 data3.n < data3.max || 229 data4.n < data4.max) { 230 aio_poll(ctx, true); 231 } 232 g_assert_cmpint(data1.n, ==, data1.max); 233 g_assert_cmpint(data2.n, ==, data2.max); 234 g_assert_cmpint(data3.n, ==, data3.max); 235 g_assert_cmpint(data4.n, ==, data4.max); 236 g_assert(data1.bh == NULL); 237 g_assert(data2.bh == NULL); 238 g_assert(data3.bh == NULL); 239 g_assert(data4.bh == NULL); 240 } 241 242 static void test_bh_flush(void) 243 { 244 BHTestData data = { .n = 0 }; 245 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 246 247 qemu_bh_schedule(data.bh); 248 g_assert_cmpint(data.n, ==, 0); 249 250 g_assert(aio_poll(ctx, true)); 251 g_assert_cmpint(data.n, ==, 1); 252 253 g_assert(!aio_poll(ctx, false)); 254 g_assert_cmpint(data.n, ==, 1); 255 qemu_bh_delete(data.bh); 256 } 257 258 static void test_set_event_notifier(void) 259 { 260 EventNotifierTestData data = { .n = 0, .active = 0 }; 261 event_notifier_init(&data.e, false); 262 set_event_notifier(ctx, &data.e, event_ready_cb); 263 g_assert(!aio_poll(ctx, false)); 264 g_assert_cmpint(data.n, ==, 0); 265 266 set_event_notifier(ctx, &data.e, NULL); 267 g_assert(!aio_poll(ctx, false)); 268 g_assert_cmpint(data.n, ==, 0); 269 event_notifier_cleanup(&data.e); 270 } 271 272 static void test_wait_event_notifier(void) 273 { 274 EventNotifierTestData data = { .n = 0, .active = 1 }; 275 event_notifier_init(&data.e, false); 276 set_event_notifier(ctx, &data.e, event_ready_cb); 277 while (aio_poll(ctx, false)); 278 g_assert_cmpint(data.n, ==, 0); 279 g_assert_cmpint(data.active, ==, 1); 280 281 event_notifier_set(&data.e); 282 g_assert(aio_poll(ctx, false)); 283 g_assert_cmpint(data.n, ==, 1); 284 g_assert_cmpint(data.active, ==, 0); 285 286 g_assert(!aio_poll(ctx, false)); 287 g_assert_cmpint(data.n, ==, 1); 288 g_assert_cmpint(data.active, ==, 0); 289 290 set_event_notifier(ctx, &data.e, NULL); 291 g_assert(!aio_poll(ctx, false)); 292 g_assert_cmpint(data.n, ==, 1); 293 294 event_notifier_cleanup(&data.e); 295 } 296 297 static void test_flush_event_notifier(void) 298 { 299 EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true }; 300 event_notifier_init(&data.e, false); 301 set_event_notifier(ctx, &data.e, event_ready_cb); 302 while (aio_poll(ctx, false)); 303 g_assert_cmpint(data.n, ==, 0); 304 g_assert_cmpint(data.active, ==, 10); 305 306 event_notifier_set(&data.e); 307 g_assert(aio_poll(ctx, false)); 308 g_assert_cmpint(data.n, ==, 1); 309 g_assert_cmpint(data.active, ==, 9); 310 g_assert(aio_poll(ctx, false)); 311 312 wait_until_inactive(&data); 313 g_assert_cmpint(data.n, ==, 10); 314 g_assert_cmpint(data.active, ==, 0); 315 g_assert(!aio_poll(ctx, false)); 316 317 set_event_notifier(ctx, &data.e, NULL); 318 g_assert(!aio_poll(ctx, false)); 319 event_notifier_cleanup(&data.e); 320 } 321 322 static void test_wait_event_notifier_noflush(void) 323 { 324 EventNotifierTestData data = { .n = 0 }; 325 EventNotifierTestData dummy = { .n = 0, .active = 1 }; 326 327 event_notifier_init(&data.e, false); 328 set_event_notifier(ctx, &data.e, event_ready_cb); 329 330 g_assert(!aio_poll(ctx, false)); 331 g_assert_cmpint(data.n, ==, 0); 332 333 /* Until there is an active descriptor, aio_poll may or may not call 334 * event_ready_cb. Still, it must not block. */ 335 event_notifier_set(&data.e); 336 g_assert(aio_poll(ctx, true)); 337 data.n = 0; 338 339 /* An active event notifier forces aio_poll to look at EventNotifiers. */ 340 event_notifier_init(&dummy.e, false); 341 set_event_notifier(ctx, &dummy.e, event_ready_cb); 342 343 event_notifier_set(&data.e); 344 g_assert(aio_poll(ctx, false)); 345 g_assert_cmpint(data.n, ==, 1); 346 g_assert(!aio_poll(ctx, false)); 347 g_assert_cmpint(data.n, ==, 1); 348 349 event_notifier_set(&data.e); 350 g_assert(aio_poll(ctx, false)); 351 g_assert_cmpint(data.n, ==, 2); 352 g_assert(!aio_poll(ctx, false)); 353 g_assert_cmpint(data.n, ==, 2); 354 355 event_notifier_set(&dummy.e); 356 wait_until_inactive(&dummy); 357 g_assert_cmpint(data.n, ==, 2); 358 g_assert_cmpint(dummy.n, ==, 1); 359 g_assert_cmpint(dummy.active, ==, 0); 360 361 set_event_notifier(ctx, &dummy.e, NULL); 362 event_notifier_cleanup(&dummy.e); 363 364 set_event_notifier(ctx, &data.e, NULL); 365 g_assert(!aio_poll(ctx, false)); 366 g_assert_cmpint(data.n, ==, 2); 367 368 event_notifier_cleanup(&data.e); 369 } 370 371 static void test_timer_schedule(void) 372 { 373 TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL, 374 .max = 2, 375 .clock_type = QEMU_CLOCK_REALTIME }; 376 EventNotifier e; 377 378 /* aio_poll will not block to wait for timers to complete unless it has 379 * an fd to wait on. Fixing this breaks other tests. So create a dummy one. 380 */ 381 event_notifier_init(&e, false); 382 set_event_notifier(ctx, &e, dummy_io_handler_read); 383 aio_poll(ctx, false); 384 385 aio_timer_init(ctx, &data.timer, data.clock_type, 386 SCALE_NS, timer_test_cb, &data); 387 timer_mod(&data.timer, 388 qemu_clock_get_ns(data.clock_type) + 389 data.ns); 390 391 g_assert_cmpint(data.n, ==, 0); 392 393 /* timer_mod may well cause an event notifier to have gone off, 394 * so clear that 395 */ 396 do {} while (aio_poll(ctx, false)); 397 398 g_assert(!aio_poll(ctx, false)); 399 g_assert_cmpint(data.n, ==, 0); 400 401 g_usleep(1 * G_USEC_PER_SEC); 402 g_assert_cmpint(data.n, ==, 0); 403 404 g_assert(aio_poll(ctx, false)); 405 g_assert_cmpint(data.n, ==, 1); 406 407 /* timer_mod called by our callback */ 408 do {} while (aio_poll(ctx, false)); 409 410 g_assert(!aio_poll(ctx, false)); 411 g_assert_cmpint(data.n, ==, 1); 412 413 g_assert(aio_poll(ctx, true)); 414 g_assert_cmpint(data.n, ==, 2); 415 416 /* As max is now 2, an event notifier should not have gone off */ 417 418 g_assert(!aio_poll(ctx, false)); 419 g_assert_cmpint(data.n, ==, 2); 420 421 set_event_notifier(ctx, &e, NULL); 422 event_notifier_cleanup(&e); 423 424 timer_del(&data.timer); 425 } 426 427 /* Now the same tests, using the context as a GSource. They are 428 * very similar to the ones above, with g_main_context_iteration 429 * replacing aio_poll. However: 430 * - sometimes both the AioContext and the glib main loop wake 431 * themselves up. Hence, some "g_assert(!aio_poll(ctx, false));" 432 * are replaced by "while (g_main_context_iteration(NULL, false));". 433 * - there is no exact replacement for a blocking wait. 434 * "while (g_main_context_iteration(NULL, true)" seems to work, 435 * but it is not documented _why_ it works. For these tests a 436 * non-blocking loop like "while (g_main_context_iteration(NULL, false)" 437 * works well, and that's what I am using. 438 */ 439 440 static void test_source_flush(void) 441 { 442 g_assert(!g_main_context_iteration(NULL, false)); 443 aio_notify(ctx); 444 while (g_main_context_iteration(NULL, false)); 445 g_assert(!g_main_context_iteration(NULL, false)); 446 } 447 448 static void test_source_bh_schedule(void) 449 { 450 BHTestData data = { .n = 0 }; 451 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 452 453 qemu_bh_schedule(data.bh); 454 g_assert_cmpint(data.n, ==, 0); 455 456 g_assert(g_main_context_iteration(NULL, true)); 457 g_assert_cmpint(data.n, ==, 1); 458 459 g_assert(!g_main_context_iteration(NULL, false)); 460 g_assert_cmpint(data.n, ==, 1); 461 qemu_bh_delete(data.bh); 462 } 463 464 static void test_source_bh_schedule10(void) 465 { 466 BHTestData data = { .n = 0, .max = 10 }; 467 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 468 469 qemu_bh_schedule(data.bh); 470 g_assert_cmpint(data.n, ==, 0); 471 472 g_assert(g_main_context_iteration(NULL, false)); 473 g_assert_cmpint(data.n, ==, 1); 474 475 g_assert(g_main_context_iteration(NULL, true)); 476 g_assert_cmpint(data.n, ==, 2); 477 478 while (g_main_context_iteration(NULL, false)); 479 g_assert_cmpint(data.n, ==, 10); 480 481 g_assert(!g_main_context_iteration(NULL, false)); 482 g_assert_cmpint(data.n, ==, 10); 483 qemu_bh_delete(data.bh); 484 } 485 486 static void test_source_bh_cancel(void) 487 { 488 BHTestData data = { .n = 0 }; 489 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 490 491 qemu_bh_schedule(data.bh); 492 g_assert_cmpint(data.n, ==, 0); 493 494 qemu_bh_cancel(data.bh); 495 g_assert_cmpint(data.n, ==, 0); 496 497 while (g_main_context_iteration(NULL, false)); 498 g_assert_cmpint(data.n, ==, 0); 499 qemu_bh_delete(data.bh); 500 } 501 502 static void test_source_bh_delete(void) 503 { 504 BHTestData data = { .n = 0 }; 505 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 506 507 qemu_bh_schedule(data.bh); 508 g_assert_cmpint(data.n, ==, 0); 509 510 qemu_bh_delete(data.bh); 511 g_assert_cmpint(data.n, ==, 0); 512 513 while (g_main_context_iteration(NULL, false)); 514 g_assert_cmpint(data.n, ==, 0); 515 } 516 517 static void test_source_bh_delete_from_cb(void) 518 { 519 BHTestData data1 = { .n = 0, .max = 1 }; 520 521 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); 522 523 qemu_bh_schedule(data1.bh); 524 g_assert_cmpint(data1.n, ==, 0); 525 526 g_main_context_iteration(NULL, true); 527 g_assert_cmpint(data1.n, ==, data1.max); 528 g_assert(data1.bh == NULL); 529 530 /* 531 * There may be up to one more iteration due to the aio_notify 532 * EventNotifier. 533 */ 534 g_main_context_iteration(NULL, false); 535 536 assert(!g_main_context_iteration(NULL, false)); 537 } 538 539 static void test_source_bh_delete_from_cb_many(void) 540 { 541 BHTestData data1 = { .n = 0, .max = 1 }; 542 BHTestData data2 = { .n = 0, .max = 3 }; 543 BHTestData data3 = { .n = 0, .max = 2 }; 544 BHTestData data4 = { .n = 0, .max = 4 }; 545 546 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); 547 data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2); 548 data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3); 549 data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4); 550 551 qemu_bh_schedule(data1.bh); 552 qemu_bh_schedule(data2.bh); 553 qemu_bh_schedule(data3.bh); 554 qemu_bh_schedule(data4.bh); 555 g_assert_cmpint(data1.n, ==, 0); 556 g_assert_cmpint(data2.n, ==, 0); 557 g_assert_cmpint(data3.n, ==, 0); 558 g_assert_cmpint(data4.n, ==, 0); 559 560 g_assert(g_main_context_iteration(NULL, false)); 561 g_assert_cmpint(data1.n, ==, 1); 562 g_assert_cmpint(data2.n, ==, 1); 563 g_assert_cmpint(data3.n, ==, 1); 564 g_assert_cmpint(data4.n, ==, 1); 565 g_assert(data1.bh == NULL); 566 567 while (g_main_context_iteration(NULL, false)); 568 g_assert_cmpint(data1.n, ==, data1.max); 569 g_assert_cmpint(data2.n, ==, data2.max); 570 g_assert_cmpint(data3.n, ==, data3.max); 571 g_assert_cmpint(data4.n, ==, data4.max); 572 g_assert(data1.bh == NULL); 573 g_assert(data2.bh == NULL); 574 g_assert(data3.bh == NULL); 575 g_assert(data4.bh == NULL); 576 } 577 578 static void test_source_bh_flush(void) 579 { 580 BHTestData data = { .n = 0 }; 581 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 582 583 qemu_bh_schedule(data.bh); 584 g_assert_cmpint(data.n, ==, 0); 585 586 g_assert(g_main_context_iteration(NULL, true)); 587 g_assert_cmpint(data.n, ==, 1); 588 589 g_assert(!g_main_context_iteration(NULL, false)); 590 g_assert_cmpint(data.n, ==, 1); 591 qemu_bh_delete(data.bh); 592 } 593 594 static void test_source_set_event_notifier(void) 595 { 596 EventNotifierTestData data = { .n = 0, .active = 0 }; 597 event_notifier_init(&data.e, false); 598 set_event_notifier(ctx, &data.e, event_ready_cb); 599 while (g_main_context_iteration(NULL, false)); 600 g_assert_cmpint(data.n, ==, 0); 601 602 set_event_notifier(ctx, &data.e, NULL); 603 while (g_main_context_iteration(NULL, false)); 604 g_assert_cmpint(data.n, ==, 0); 605 event_notifier_cleanup(&data.e); 606 } 607 608 static void test_source_wait_event_notifier(void) 609 { 610 EventNotifierTestData data = { .n = 0, .active = 1 }; 611 event_notifier_init(&data.e, false); 612 set_event_notifier(ctx, &data.e, event_ready_cb); 613 while (g_main_context_iteration(NULL, false)); 614 g_assert_cmpint(data.n, ==, 0); 615 g_assert_cmpint(data.active, ==, 1); 616 617 event_notifier_set(&data.e); 618 g_assert(g_main_context_iteration(NULL, false)); 619 g_assert_cmpint(data.n, ==, 1); 620 g_assert_cmpint(data.active, ==, 0); 621 622 while (g_main_context_iteration(NULL, false)); 623 g_assert_cmpint(data.n, ==, 1); 624 g_assert_cmpint(data.active, ==, 0); 625 626 set_event_notifier(ctx, &data.e, NULL); 627 while (g_main_context_iteration(NULL, false)); 628 g_assert_cmpint(data.n, ==, 1); 629 630 event_notifier_cleanup(&data.e); 631 } 632 633 static void test_source_flush_event_notifier(void) 634 { 635 EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true }; 636 event_notifier_init(&data.e, false); 637 set_event_notifier(ctx, &data.e, event_ready_cb); 638 while (g_main_context_iteration(NULL, false)); 639 g_assert_cmpint(data.n, ==, 0); 640 g_assert_cmpint(data.active, ==, 10); 641 642 event_notifier_set(&data.e); 643 g_assert(g_main_context_iteration(NULL, false)); 644 g_assert_cmpint(data.n, ==, 1); 645 g_assert_cmpint(data.active, ==, 9); 646 g_assert(g_main_context_iteration(NULL, false)); 647 648 while (g_main_context_iteration(NULL, false)); 649 g_assert_cmpint(data.n, ==, 10); 650 g_assert_cmpint(data.active, ==, 0); 651 g_assert(!g_main_context_iteration(NULL, false)); 652 653 set_event_notifier(ctx, &data.e, NULL); 654 while (g_main_context_iteration(NULL, false)); 655 event_notifier_cleanup(&data.e); 656 } 657 658 static void test_source_wait_event_notifier_noflush(void) 659 { 660 EventNotifierTestData data = { .n = 0 }; 661 EventNotifierTestData dummy = { .n = 0, .active = 1 }; 662 663 event_notifier_init(&data.e, false); 664 set_event_notifier(ctx, &data.e, event_ready_cb); 665 666 while (g_main_context_iteration(NULL, false)); 667 g_assert_cmpint(data.n, ==, 0); 668 669 /* Until there is an active descriptor, glib may or may not call 670 * event_ready_cb. Still, it must not block. */ 671 event_notifier_set(&data.e); 672 g_main_context_iteration(NULL, true); 673 data.n = 0; 674 675 /* An active event notifier forces aio_poll to look at EventNotifiers. */ 676 event_notifier_init(&dummy.e, false); 677 set_event_notifier(ctx, &dummy.e, event_ready_cb); 678 679 event_notifier_set(&data.e); 680 g_assert(g_main_context_iteration(NULL, false)); 681 g_assert_cmpint(data.n, ==, 1); 682 g_assert(!g_main_context_iteration(NULL, false)); 683 g_assert_cmpint(data.n, ==, 1); 684 685 event_notifier_set(&data.e); 686 g_assert(g_main_context_iteration(NULL, false)); 687 g_assert_cmpint(data.n, ==, 2); 688 g_assert(!g_main_context_iteration(NULL, false)); 689 g_assert_cmpint(data.n, ==, 2); 690 691 event_notifier_set(&dummy.e); 692 while (g_main_context_iteration(NULL, false)); 693 g_assert_cmpint(data.n, ==, 2); 694 g_assert_cmpint(dummy.n, ==, 1); 695 g_assert_cmpint(dummy.active, ==, 0); 696 697 set_event_notifier(ctx, &dummy.e, NULL); 698 event_notifier_cleanup(&dummy.e); 699 700 set_event_notifier(ctx, &data.e, NULL); 701 while (g_main_context_iteration(NULL, false)); 702 g_assert_cmpint(data.n, ==, 2); 703 704 event_notifier_cleanup(&data.e); 705 } 706 707 static void test_source_timer_schedule(void) 708 { 709 TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL, 710 .max = 2, 711 .clock_type = QEMU_CLOCK_REALTIME }; 712 EventNotifier e; 713 int64_t expiry; 714 715 /* aio_poll will not block to wait for timers to complete unless it has 716 * an fd to wait on. Fixing this breaks other tests. So create a dummy one. 717 */ 718 event_notifier_init(&e, false); 719 set_event_notifier(ctx, &e, dummy_io_handler_read); 720 do {} while (g_main_context_iteration(NULL, false)); 721 722 aio_timer_init(ctx, &data.timer, data.clock_type, 723 SCALE_NS, timer_test_cb, &data); 724 expiry = qemu_clock_get_ns(data.clock_type) + 725 data.ns; 726 timer_mod(&data.timer, expiry); 727 728 g_assert_cmpint(data.n, ==, 0); 729 730 g_usleep(1 * G_USEC_PER_SEC); 731 g_assert_cmpint(data.n, ==, 0); 732 733 g_assert(g_main_context_iteration(NULL, true)); 734 g_assert_cmpint(data.n, ==, 1); 735 expiry += data.ns; 736 737 while (data.n < 2) { 738 g_main_context_iteration(NULL, true); 739 } 740 741 g_assert_cmpint(data.n, ==, 2); 742 g_assert(qemu_clock_get_ns(data.clock_type) > expiry); 743 744 set_event_notifier(ctx, &e, NULL); 745 event_notifier_cleanup(&e); 746 747 timer_del(&data.timer); 748 } 749 750 /* 751 * Check that aio_co_enter() can chain many times 752 * 753 * Two coroutines should be able to invoke each other via aio_co_enter() many 754 * times without hitting a limit like stack exhaustion. In other words, the 755 * calls should be chained instead of nested. 756 */ 757 758 typedef struct { 759 Coroutine *other; 760 unsigned i; 761 unsigned max; 762 } ChainData; 763 764 static void coroutine_fn chain(void *opaque) 765 { 766 ChainData *data = opaque; 767 768 for (data->i = 0; data->i < data->max; data->i++) { 769 /* Queue up the other coroutine... */ 770 aio_co_enter(ctx, data->other); 771 772 /* ...and give control to it */ 773 qemu_coroutine_yield(); 774 } 775 } 776 777 static void test_queue_chaining(void) 778 { 779 /* This number of iterations hit stack exhaustion in the past: */ 780 ChainData data_a = { .max = 25000 }; 781 ChainData data_b = { .max = 25000 }; 782 783 data_b.other = qemu_coroutine_create(chain, &data_a); 784 data_a.other = qemu_coroutine_create(chain, &data_b); 785 786 qemu_coroutine_enter(data_b.other); 787 788 g_assert_cmpint(data_a.i, ==, data_a.max); 789 g_assert_cmpint(data_b.i, ==, data_b.max - 1); 790 791 /* Allow the second coroutine to terminate */ 792 qemu_coroutine_enter(data_a.other); 793 794 g_assert_cmpint(data_b.i, ==, data_b.max); 795 } 796 797 static void co_check_current_thread(void *opaque) 798 { 799 QemuThread *main_thread = opaque; 800 assert(qemu_thread_is_self(main_thread)); 801 } 802 803 static void *test_aio_co_enter(void *co) 804 { 805 /* 806 * qemu_get_current_aio_context() should not to be the main thread 807 * AioContext, because this is a worker thread that has not taken 808 * the BQL. So aio_co_enter will schedule the coroutine in the 809 * main thread AioContext. 810 */ 811 aio_co_enter(qemu_get_aio_context(), co); 812 return NULL; 813 } 814 815 static void test_worker_thread_co_enter(void) 816 { 817 QemuThread this_thread, worker_thread; 818 Coroutine *co; 819 820 qemu_thread_get_self(&this_thread); 821 co = qemu_coroutine_create(co_check_current_thread, &this_thread); 822 823 qemu_thread_create(&worker_thread, "test_aio_co_enter", 824 test_aio_co_enter, 825 co, QEMU_THREAD_JOINABLE); 826 827 /* Test aio_co_enter from a worker thread. */ 828 qemu_thread_join(&worker_thread); 829 g_assert(aio_poll(ctx, true)); 830 g_assert(!aio_poll(ctx, false)); 831 } 832 833 /* End of tests. */ 834 835 int main(int argc, char **argv) 836 { 837 qemu_init_main_loop(&error_fatal); 838 ctx = qemu_get_aio_context(); 839 840 while (g_main_context_iteration(NULL, false)); 841 842 g_test_init(&argc, &argv, NULL); 843 g_test_add_func("/aio/bh/schedule", test_bh_schedule); 844 g_test_add_func("/aio/bh/schedule10", test_bh_schedule10); 845 g_test_add_func("/aio/bh/cancel", test_bh_cancel); 846 g_test_add_func("/aio/bh/delete", test_bh_delete); 847 g_test_add_func("/aio/bh/callback-delete/one", test_bh_delete_from_cb); 848 g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many); 849 g_test_add_func("/aio/bh/flush", test_bh_flush); 850 g_test_add_func("/aio/event/add-remove", test_set_event_notifier); 851 g_test_add_func("/aio/event/wait", test_wait_event_notifier); 852 g_test_add_func("/aio/event/wait/no-flush-cb", test_wait_event_notifier_noflush); 853 g_test_add_func("/aio/event/flush", test_flush_event_notifier); 854 g_test_add_func("/aio/timer/schedule", test_timer_schedule); 855 856 g_test_add_func("/aio/coroutine/queue-chaining", test_queue_chaining); 857 g_test_add_func("/aio/coroutine/worker-thread-co-enter", test_worker_thread_co_enter); 858 859 g_test_add_func("/aio-gsource/flush", test_source_flush); 860 g_test_add_func("/aio-gsource/bh/schedule", test_source_bh_schedule); 861 g_test_add_func("/aio-gsource/bh/schedule10", test_source_bh_schedule10); 862 g_test_add_func("/aio-gsource/bh/cancel", test_source_bh_cancel); 863 g_test_add_func("/aio-gsource/bh/delete", test_source_bh_delete); 864 g_test_add_func("/aio-gsource/bh/callback-delete/one", test_source_bh_delete_from_cb); 865 g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many); 866 g_test_add_func("/aio-gsource/bh/flush", test_source_bh_flush); 867 g_test_add_func("/aio-gsource/event/add-remove", test_source_set_event_notifier); 868 g_test_add_func("/aio-gsource/event/wait", test_source_wait_event_notifier); 869 g_test_add_func("/aio-gsource/event/wait/no-flush-cb", test_source_wait_event_notifier_noflush); 870 g_test_add_func("/aio-gsource/event/flush", test_source_flush_event_notifier); 871 g_test_add_func("/aio-gsource/timer/schedule", test_source_timer_schedule); 872 return g_test_run(); 873 } 874