Changeset d04e46e in mainline for uspace/app/rcutest/rcutest.c
- Timestamp:
- 2012-11-24T00:26:11Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3ac5086
- Parents:
- a879d73
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/rcutest/rcutest.c
ra879d73 rd04e46e 48 48 #include <rcu.h> 49 49 50 #include "fibril_synch.h" 51 50 52 51 53 #define USECS_PER_SEC (1000 * 1000) 52 54 #define USECS_PER_MS 1000 53 55 56 /* fwd decl. */ 57 struct test_info; 54 58 55 59 typedef struct test_desc { … … 61 65 T_STRESS 62 66 } type; 63 bool (*func)( void);67 bool (*func)(struct test_info*); 64 68 const char *name; 65 69 const char *desc; … … 67 71 68 72 69 static bool run_all_tests(void); 70 static bool run_sanity_tests(void); 71 static bool run_stress_tests(void); 72 73 static bool wait_for_one_reader(void); 74 static bool basic_sanity_check(void); 75 static bool dont_wait_for_new_reader(void); 76 static bool wait_for_exiting_reader(void); 73 typedef struct test_info { 74 size_t thread_cnt; 75 test_desc_t *desc; 76 } test_info_t; 77 78 79 80 static bool run_all_tests(struct test_info*); 81 static bool run_sanity_tests(struct test_info*); 82 static bool run_stress_tests(struct test_info*); 83 84 static bool wait_for_one_reader(struct test_info*); 85 static bool basic_sanity_check(struct test_info*); 86 static bool dont_wait_for_new_reader(struct test_info*); 87 static bool wait_for_exiting_reader(struct test_info*); 77 88 78 89 static test_desc_t test_desc[] = { … … 157 168 /*--------------------------------------------------------------------*/ 158 169 159 static bool run_tests( bool (*include_filter)(test_desc_t *))170 static bool run_tests(test_info_t *info, bool (*include_filter)(test_desc_t *)) 160 171 { 161 172 size_t failed_cnt = 0; … … 167 178 if (t->func && !t->aggregate && include_filter(t)) { 168 179 printf("Running \'%s\'...\n", t->name); 169 bool ok = test_desc[i].func( );180 bool ok = test_desc[i].func(info); 170 181 171 182 if (ok) { … … 198 209 199 210 /* Runs all available tests tests one-by-one. */ 200 static bool run_all_tests( void)211 static bool run_all_tests(test_info_t *test_info) 201 212 { 202 213 printf("Running all tests...\n"); 203 return run_tests( all_tests_include_filter);214 return run_tests(test_info, all_tests_include_filter); 204 215 } 205 216 … … 212 223 213 224 /* Runs all available stress tests one-by-one. */ 214 static bool run_stress_tests( void)225 static bool run_stress_tests(test_info_t *test_info) 215 226 { 216 227 printf("Running stress tests...\n"); 217 return run_tests( stress_tests_include_filter);228 return run_tests(test_info, stress_tests_include_filter); 218 229 } 219 230 … … 226 237 227 238 /* Runs all available sanity tests one-by-one. */ 228 static bool run_sanity_tests( void)239 static bool run_sanity_tests(test_info_t *test_info) 229 240 { 230 241 printf("Running sanity tests...\n"); 231 return run_tests( sanity_tests_include_filter);242 return run_tests(test_info, sanity_tests_include_filter); 232 243 } 233 244 … … 235 246 236 247 /* Locks/unlocks rcu and synchronizes without contention in a single fibril. */ 237 static bool basic_sanity_check( void)248 static bool basic_sanity_check(test_info_t *test_info) 238 249 { 239 250 rcu_read_lock(); … … 309 320 } 310 321 311 static bool wait_for_one_reader( void)322 static bool wait_for_one_reader(test_info_t *test_info) 312 323 { 313 324 one_reader_info_t info = { 0 }; … … 446 457 } 447 458 448 static bool dont_wait_for_new_reader( void)459 static bool dont_wait_for_new_reader(test_info_t *test_info) 449 460 { 450 461 two_reader_info_t info = { 0 }; … … 553 564 554 565 555 static bool wait_for_exiting_reader( void)566 static bool wait_for_exiting_reader(test_info_t *test_info) 556 567 { 557 568 exit_reader_info_t info = { 0 }; … … 588 599 589 600 /*--------------------------------------------------------------------*/ 601 602 static FIBRIL_MUTEX_INITIALIZE(blocking_mtx); 603 604 static void dummy_fibril(void *arg) 605 { 606 /* Block on an already locked mutex - enters the fibril manager. */ 607 fibril_mutex_lock(&blocking_mtx); 608 assert(false); 609 } 610 611 static bool create_threads(size_t cnt) 612 { 613 /* Sanity check. */ 614 assert(cnt < 1024); 615 616 /* Keep this mutex locked so that dummy fibrils never exit. */ 617 bool success = fibril_mutex_trylock(&blocking_mtx); 618 assert(success); 619 620 for (size_t k = 0; k < cnt; ++k) { 621 thread_id_t tid; 622 623 int ret = thread_create(dummy_fibril, NULL, "urcu-test-worker", &tid); 624 if (EOK != ret) { 625 printf("Failed to create thread '%zu' (error: %d)\n", k + 1, ret); 626 return false; 627 } 628 } 629 630 return true; 631 } 632 590 633 /*--------------------------------------------------------------------*/ 591 634 static test_desc_t *find_test(const char *name) … … 604 647 if (EOK == str_uint32_t(name, NULL, 0, true, &test_num)) { 605 648 if (test_num < test_desc_cnt && test_desc[test_num].func) { 606 printf("[%u]\n", test_num);607 649 return &test_desc[test_num]; 608 650 } … … 636 678 static void print_usage(void) 637 679 { 638 printf("Usage: rcutest [test_name|test_number] \n");680 printf("Usage: rcutest [test_name|test_number] {number_of_threads}\n"); 639 681 list_tests(); 640 682 … … 645 687 646 688 689 static bool parse_cmd_line(int argc, char **argv, test_info_t *info) 690 { 691 if (argc != 2 && argc != 3) { 692 print_usage(); 693 return false; 694 } 695 696 info->desc = find_test(argv[1]); 697 698 if (!info->desc) { 699 printf("Non-existent test '%s'.\n", argv[1]); 700 list_tests(); 701 return false; 702 } 703 704 if (argc == 3) { 705 uint32_t thread_cnt = 0; 706 int ret = str_uint32_t(argv[2], NULL, 0, true, &thread_cnt); 707 708 if (ret == EOK && 1 <= thread_cnt && thread_cnt <= 64) { 709 info->thread_cnt = thread_cnt; 710 } else { 711 info->thread_cnt = 1; 712 printf("Err: Invalid number of threads '%s'; using 1.\n", argv[2]); 713 } 714 } 715 716 return true; 717 } 718 647 719 int main(int argc, char **argv) 648 720 { 649 721 rcu_register_fibril(); 650 722 651 if (argc != 2) { 652 print_usage(); 653 723 test_info_t info; 724 725 bool ok = parse_cmd_line(argc, argv, &info); 726 ok = ok && create_threads(info.thread_cnt - 1); 727 728 if (ok) { 729 assert(1 <= info.thread_cnt); 730 test_desc_t *t = info.desc; 731 732 printf("Running '%s' (in %zu threads)...\n", t->name, info.thread_cnt); 733 ok = t->func(&info); 734 735 printf("%s: '%s'\n", ok ? "Passed" : "FAILED", t->name); 736 737 rcu_deregister_fibril(); 738 739 /* Let the kernel clean up the created background threads. */ 740 return ok ? 0 : 1; 741 } else { 654 742 rcu_deregister_fibril(); 655 743 return 2; 656 }657 658 test_desc_t *t = find_test(argv[1]);659 660 if (t) {661 printf("Running '%s'...\n", t->name);662 bool ok = t->func();663 664 printf("%s: '%s'\n", ok ? "Passed" : "FAILED", t->name);665 666 rcu_deregister_fibril();667 return ok ? 0 : 1;668 } else {669 printf("Non-existent test name.\n");670 list_tests();671 672 rcu_deregister_fibril();673 return 3;674 744 } 675 745 }
Note:
See TracChangeset
for help on using the changeset viewer.