|
7 | 7 | * Kernel loop code stolen from Steven Rostedt <[email protected]>
|
8 | 8 | */
|
9 | 9 | #define _GNU_SOURCE
|
| 10 | +#include <sys/prctl.h> |
10 | 11 | #include <sys/time.h>
|
11 | 12 | #include <sys/types.h>
|
12 | 13 | #include <stdio.h>
|
@@ -599,14 +600,84 @@ static void check_overrun(int which, const char *name)
|
599 | 600 | "check_overrun %s\n", name);
|
600 | 601 | }
|
601 | 602 |
|
| 603 | +#include <sys/syscall.h> |
| 604 | + |
| 605 | +static int do_timer_create(int *id) |
| 606 | +{ |
| 607 | + return syscall(__NR_timer_create, CLOCK_MONOTONIC, NULL, id); |
| 608 | +} |
| 609 | + |
| 610 | +static int do_timer_delete(int id) |
| 611 | +{ |
| 612 | + return syscall(__NR_timer_delete, id); |
| 613 | +} |
| 614 | + |
| 615 | +#ifndef PR_TIMER_CREATE_RESTORE_IDS |
| 616 | +# define PR_TIMER_CREATE_RESTORE_IDS 77 |
| 617 | +# define PR_TIMER_CREATE_RESTORE_IDS_OFF 0 |
| 618 | +# define PR_TIMER_CREATE_RESTORE_IDS_ON 1 |
| 619 | +# define PR_TIMER_CREATE_RESTORE_IDS_GET 2 |
| 620 | +#endif |
| 621 | + |
| 622 | +static void check_timer_create_exact(void) |
| 623 | +{ |
| 624 | + int id; |
| 625 | + |
| 626 | + if (prctl(PR_TIMER_CREATE_RESTORE_IDS, PR_TIMER_CREATE_RESTORE_IDS_ON, 0, 0, 0)) { |
| 627 | + switch (errno) { |
| 628 | + case EINVAL: |
| 629 | + ksft_test_result_skip("check timer create exact, not supported\n"); |
| 630 | + return; |
| 631 | + default: |
| 632 | + ksft_test_result_skip("check timer create exact, errno = %d\n", errno); |
| 633 | + return; |
| 634 | + } |
| 635 | + } |
| 636 | + |
| 637 | + if (prctl(PR_TIMER_CREATE_RESTORE_IDS, PR_TIMER_CREATE_RESTORE_IDS_GET, 0, 0, 0) != 1) |
| 638 | + fatal_error(NULL, "prctl(GET) failed\n"); |
| 639 | + |
| 640 | + id = 8; |
| 641 | + if (do_timer_create(&id) < 0) |
| 642 | + fatal_error(NULL, "timer_create()"); |
| 643 | + |
| 644 | + if (do_timer_delete(id)) |
| 645 | + fatal_error(NULL, "timer_delete()"); |
| 646 | + |
| 647 | + if (prctl(PR_TIMER_CREATE_RESTORE_IDS, PR_TIMER_CREATE_RESTORE_IDS_OFF, 0, 0, 0)) |
| 648 | + fatal_error(NULL, "prctl(OFF)"); |
| 649 | + |
| 650 | + if (prctl(PR_TIMER_CREATE_RESTORE_IDS, PR_TIMER_CREATE_RESTORE_IDS_GET, 0, 0, 0) != 0) |
| 651 | + fatal_error(NULL, "prctl(GET) failed\n"); |
| 652 | + |
| 653 | + if (id != 8) { |
| 654 | + ksft_test_result_fail("check timer create exact %d != 8\n", id); |
| 655 | + return; |
| 656 | + } |
| 657 | + |
| 658 | + /* Validate that it went back to normal mode and allocates ID 9 */ |
| 659 | + if (do_timer_create(&id) < 0) |
| 660 | + fatal_error(NULL, "timer_create()"); |
| 661 | + |
| 662 | + if (do_timer_delete(id)) |
| 663 | + fatal_error(NULL, "timer_delete()"); |
| 664 | + |
| 665 | + if (id == 9) |
| 666 | + ksft_test_result_pass("check timer create exact\n"); |
| 667 | + else |
| 668 | + ksft_test_result_fail("check timer create exact. Disabling failed.\n"); |
| 669 | +} |
| 670 | + |
602 | 671 | int main(int argc, char **argv)
|
603 | 672 | {
|
604 | 673 | ksft_print_header();
|
605 |
| - ksft_set_plan(18); |
| 674 | + ksft_set_plan(19); |
606 | 675 |
|
607 | 676 | ksft_print_msg("Testing posix timers. False negative may happen on CPU execution \n");
|
608 | 677 | ksft_print_msg("based timers if other threads run on the CPU...\n");
|
609 | 678 |
|
| 679 | + check_timer_create_exact(); |
| 680 | + |
610 | 681 | check_itimer(ITIMER_VIRTUAL, "ITIMER_VIRTUAL");
|
611 | 682 | check_itimer(ITIMER_PROF, "ITIMER_PROF");
|
612 | 683 | check_itimer(ITIMER_REAL, "ITIMER_REAL");
|
|
0 commit comments