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 assert(g_main_context_iteration(NULL, false)); 531 assert(!g_main_context_iteration(NULL, false)); 532 } 533 534 static void test_source_bh_delete_from_cb_many(void) 535 { 536 BHTestData data1 = { .n = 0, .max = 1 }; 537 BHTestData data2 = { .n = 0, .max = 3 }; 538 BHTestData data3 = { .n = 0, .max = 2 }; 539 BHTestData data4 = { .n = 0, .max = 4 }; 540 541 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); 542 data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2); 543 data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3); 544 data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4); 545 546 qemu_bh_schedule(data1.bh); 547 qemu_bh_schedule(data2.bh); 548 qemu_bh_schedule(data3.bh); 549 qemu_bh_schedule(data4.bh); 550 g_assert_cmpint(data1.n, ==, 0); 551 g_assert_cmpint(data2.n, ==, 0); 552 g_assert_cmpint(data3.n, ==, 0); 553 g_assert_cmpint(data4.n, ==, 0); 554 555 g_assert(g_main_context_iteration(NULL, false)); 556 g_assert_cmpint(data1.n, ==, 1); 557 g_assert_cmpint(data2.n, ==, 1); 558 g_assert_cmpint(data3.n, ==, 1); 559 g_assert_cmpint(data4.n, ==, 1); 560 g_assert(data1.bh == NULL); 561 562 while (g_main_context_iteration(NULL, false)); 563 g_assert_cmpint(data1.n, ==, data1.max); 564 g_assert_cmpint(data2.n, ==, data2.max); 565 g_assert_cmpint(data3.n, ==, data3.max); 566 g_assert_cmpint(data4.n, ==, data4.max); 567 g_assert(data1.bh == NULL); 568 g_assert(data2.bh == NULL); 569 g_assert(data3.bh == NULL); 570 g_assert(data4.bh == NULL); 571 } 572 573 static void test_source_bh_flush(void) 574 { 575 BHTestData data = { .n = 0 }; 576 data.bh = aio_bh_new(ctx, bh_test_cb, &data); 577 578 qemu_bh_schedule(data.bh); 579 g_assert_cmpint(data.n, ==, 0); 580 581 g_assert(g_main_context_iteration(NULL, true)); 582 g_assert_cmpint(data.n, ==, 1); 583 584 g_assert(!g_main_context_iteration(NULL, false)); 585 g_assert_cmpint(data.n, ==, 1); 586 qemu_bh_delete(data.bh); 587 } 588 589 static void test_source_set_event_notifier(void) 590 { 591 EventNotifierTestData data = { .n = 0, .active = 0 }; 592 event_notifier_init(&data.e, false); 593 set_event_notifier(ctx, &data.e, event_ready_cb); 594 while (g_main_context_iteration(NULL, false)); 595 g_assert_cmpint(data.n, ==, 0); 596 597 set_event_notifier(ctx, &data.e, NULL); 598 while (g_main_context_iteration(NULL, false)); 599 g_assert_cmpint(data.n, ==, 0); 600 event_notifier_cleanup(&data.e); 601 } 602 603 static void test_source_wait_event_notifier(void) 604 { 605 EventNotifierTestData data = { .n = 0, .active = 1 }; 606 event_notifier_init(&data.e, false); 607 set_event_notifier(ctx, &data.e, event_ready_cb); 608 while (g_main_context_iteration(NULL, false)); 609 g_assert_cmpint(data.n, ==, 0); 610 g_assert_cmpint(data.active, ==, 1); 611 612 event_notifier_set(&data.e); 613 g_assert(g_main_context_iteration(NULL, false)); 614 g_assert_cmpint(data.n, ==, 1); 615 g_assert_cmpint(data.active, ==, 0); 616 617 while (g_main_context_iteration(NULL, false)); 618 g_assert_cmpint(data.n, ==, 1); 619 g_assert_cmpint(data.active, ==, 0); 620 621 set_event_notifier(ctx, &data.e, NULL); 622 while (g_main_context_iteration(NULL, false)); 623 g_assert_cmpint(data.n, ==, 1); 624 625 event_notifier_cleanup(&data.e); 626 } 627 628 static void test_source_flush_event_notifier(void) 629 { 630 EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true }; 631 event_notifier_init(&data.e, false); 632 set_event_notifier(ctx, &data.e, event_ready_cb); 633 while (g_main_context_iteration(NULL, false)); 634 g_assert_cmpint(data.n, ==, 0); 635 g_assert_cmpint(data.active, ==, 10); 636 637 event_notifier_set(&data.e); 638 g_assert(g_main_context_iteration(NULL, false)); 639 g_assert_cmpint(data.n, ==, 1); 640 g_assert_cmpint(data.active, ==, 9); 641 g_assert(g_main_context_iteration(NULL, false)); 642 643 while (g_main_context_iteration(NULL, false)); 644 g_assert_cmpint(data.n, ==, 10); 645 g_assert_cmpint(data.active, ==, 0); 646 g_assert(!g_main_context_iteration(NULL, false)); 647 648 set_event_notifier(ctx, &data.e, NULL); 649 while (g_main_context_iteration(NULL, false)); 650 event_notifier_cleanup(&data.e); 651 } 652 653 static void test_source_wait_event_notifier_noflush(void) 654 { 655 EventNotifierTestData data = { .n = 0 }; 656 EventNotifierTestData dummy = { .n = 0, .active = 1 }; 657 658 event_notifier_init(&data.e, false); 659 set_event_notifier(ctx, &data.e, event_ready_cb); 660 661 while (g_main_context_iteration(NULL, false)); 662 g_assert_cmpint(data.n, ==, 0); 663 664 /* Until there is an active descriptor, glib may or may not call 665 * event_ready_cb. Still, it must not block. */ 666 event_notifier_set(&data.e); 667 g_main_context_iteration(NULL, true); 668 data.n = 0; 669 670 /* An active event notifier forces aio_poll to look at EventNotifiers. */ 671 event_notifier_init(&dummy.e, false); 672 set_event_notifier(ctx, &dummy.e, event_ready_cb); 673 674 event_notifier_set(&data.e); 675 g_assert(g_main_context_iteration(NULL, false)); 676 g_assert_cmpint(data.n, ==, 1); 677 g_assert(!g_main_context_iteration(NULL, false)); 678 g_assert_cmpint(data.n, ==, 1); 679 680 event_notifier_set(&data.e); 681 g_assert(g_main_context_iteration(NULL, false)); 682 g_assert_cmpint(data.n, ==, 2); 683 g_assert(!g_main_context_iteration(NULL, false)); 684 g_assert_cmpint(data.n, ==, 2); 685 686 event_notifier_set(&dummy.e); 687 while (g_main_context_iteration(NULL, false)); 688 g_assert_cmpint(data.n, ==, 2); 689 g_assert_cmpint(dummy.n, ==, 1); 690 g_assert_cmpint(dummy.active, ==, 0); 691 692 set_event_notifier(ctx, &dummy.e, NULL); 693 event_notifier_cleanup(&dummy.e); 694 695 set_event_notifier(ctx, &data.e, NULL); 696 while (g_main_context_iteration(NULL, false)); 697 g_assert_cmpint(data.n, ==, 2); 698 699 event_notifier_cleanup(&data.e); 700 } 701 702 static void test_source_timer_schedule(void) 703 { 704 TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL, 705 .max = 2, 706 .clock_type = QEMU_CLOCK_REALTIME }; 707 EventNotifier e; 708 int64_t expiry; 709 710 /* aio_poll will not block to wait for timers to complete unless it has 711 * an fd to wait on. Fixing this breaks other tests. So create a dummy one. 712 */ 713 event_notifier_init(&e, false); 714 set_event_notifier(ctx, &e, dummy_io_handler_read); 715 do {} while (g_main_context_iteration(NULL, false)); 716 717 aio_timer_init(ctx, &data.timer, data.clock_type, 718 SCALE_NS, timer_test_cb, &data); 719 expiry = qemu_clock_get_ns(data.clock_type) + 720 data.ns; 721 timer_mod(&data.timer, expiry); 722 723 g_assert_cmpint(data.n, ==, 0); 724 725 g_usleep(1 * G_USEC_PER_SEC); 726 g_assert_cmpint(data.n, ==, 0); 727 728 g_assert(g_main_context_iteration(NULL, true)); 729 g_assert_cmpint(data.n, ==, 1); 730 expiry += data.ns; 731 732 while (data.n < 2) { 733 g_main_context_iteration(NULL, true); 734 } 735 736 g_assert_cmpint(data.n, ==, 2); 737 g_assert(qemu_clock_get_ns(data.clock_type) > expiry); 738 739 set_event_notifier(ctx, &e, NULL); 740 event_notifier_cleanup(&e); 741 742 timer_del(&data.timer); 743 } 744 745 /* 746 * Check that aio_co_enter() can chain many times 747 * 748 * Two coroutines should be able to invoke each other via aio_co_enter() many 749 * times without hitting a limit like stack exhaustion. In other words, the 750 * calls should be chained instead of nested. 751 */ 752 753 typedef struct { 754 Coroutine *other; 755 unsigned i; 756 unsigned max; 757 } ChainData; 758 759 static void coroutine_fn chain(void *opaque) 760 { 761 ChainData *data = opaque; 762 763 for (data->i = 0; data->i < data->max; data->i++) { 764 /* Queue up the other coroutine... */ 765 aio_co_enter(ctx, data->other); 766 767 /* ...and give control to it */ 768 qemu_coroutine_yield(); 769 } 770 } 771 772 static void test_queue_chaining(void) 773 { 774 /* This number of iterations hit stack exhaustion in the past: */ 775 ChainData data_a = { .max = 25000 }; 776 ChainData data_b = { .max = 25000 }; 777 778 data_b.other = qemu_coroutine_create(chain, &data_a); 779 data_a.other = qemu_coroutine_create(chain, &data_b); 780 781 qemu_coroutine_enter(data_b.other); 782 783 g_assert_cmpint(data_a.i, ==, data_a.max); 784 g_assert_cmpint(data_b.i, ==, data_b.max - 1); 785 786 /* Allow the second coroutine to terminate */ 787 qemu_coroutine_enter(data_a.other); 788 789 g_assert_cmpint(data_b.i, ==, data_b.max); 790 } 791 792 static void co_check_current_thread(void *opaque) 793 { 794 QemuThread *main_thread = opaque; 795 assert(qemu_thread_is_self(main_thread)); 796 } 797 798 static void *test_aio_co_enter(void *co) 799 { 800 /* 801 * qemu_get_current_aio_context() should not to be the main thread 802 * AioContext, because this is a worker thread that has not taken 803 * the BQL. So aio_co_enter will schedule the coroutine in the 804 * main thread AioContext. 805 */ 806 aio_co_enter(qemu_get_aio_context(), co); 807 return NULL; 808 } 809 810 static void test_worker_thread_co_enter(void) 811 { 812 QemuThread this_thread, worker_thread; 813 Coroutine *co; 814 815 qemu_thread_get_self(&this_thread); 816 co = qemu_coroutine_create(co_check_current_thread, &this_thread); 817 818 qemu_thread_create(&worker_thread, "test_aio_co_enter", 819 test_aio_co_enter, 820 co, QEMU_THREAD_JOINABLE); 821 822 /* Test aio_co_enter from a worker thread. */ 823 qemu_thread_join(&worker_thread); 824 g_assert(aio_poll(ctx, true)); 825 g_assert(!aio_poll(ctx, false)); 826 } 827 828 /* End of tests. */ 829 830 int main(int argc, char **argv) 831 { 832 qemu_init_main_loop(&error_fatal); 833 ctx = qemu_get_aio_context(); 834 835 while (g_main_context_iteration(NULL, false)); 836 837 g_test_init(&argc, &argv, NULL); 838 g_test_add_func("/aio/bh/schedule", test_bh_schedule); 839 g_test_add_func("/aio/bh/schedule10", test_bh_schedule10); 840 g_test_add_func("/aio/bh/cancel", test_bh_cancel); 841 g_test_add_func("/aio/bh/delete", test_bh_delete); 842 g_test_add_func("/aio/bh/callback-delete/one", test_bh_delete_from_cb); 843 g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many); 844 g_test_add_func("/aio/bh/flush", test_bh_flush); 845 g_test_add_func("/aio/event/add-remove", test_set_event_notifier); 846 g_test_add_func("/aio/event/wait", test_wait_event_notifier); 847 g_test_add_func("/aio/event/wait/no-flush-cb", test_wait_event_notifier_noflush); 848 g_test_add_func("/aio/event/flush", test_flush_event_notifier); 849 g_test_add_func("/aio/timer/schedule", test_timer_schedule); 850 851 g_test_add_func("/aio/coroutine/queue-chaining", test_queue_chaining); 852 g_test_add_func("/aio/coroutine/worker-thread-co-enter", test_worker_thread_co_enter); 853 854 g_test_add_func("/aio-gsource/flush", test_source_flush); 855 g_test_add_func("/aio-gsource/bh/schedule", test_source_bh_schedule); 856 g_test_add_func("/aio-gsource/bh/schedule10", test_source_bh_schedule10); 857 g_test_add_func("/aio-gsource/bh/cancel", test_source_bh_cancel); 858 g_test_add_func("/aio-gsource/bh/delete", test_source_bh_delete); 859 g_test_add_func("/aio-gsource/bh/callback-delete/one", test_source_bh_delete_from_cb); 860 g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many); 861 g_test_add_func("/aio-gsource/bh/flush", test_source_bh_flush); 862 g_test_add_func("/aio-gsource/event/add-remove", test_source_set_event_notifier); 863 g_test_add_func("/aio-gsource/event/wait", test_source_wait_event_notifier); 864 g_test_add_func("/aio-gsource/event/wait/no-flush-cb", test_source_wait_event_notifier_noflush); 865 g_test_add_func("/aio-gsource/event/flush", test_source_flush_event_notifier); 866 g_test_add_func("/aio-gsource/timer/schedule", test_source_timer_schedule); 867 return g_test_run(); 868 } 869