thread_t* context_select (void) { thread_t *t, *x; #ifdef CLASS_HACKERY_NONDET if (!readyQh) { ch_update_readyQ (); } #endif q_del (readyQh, readyQt, t); if (!t) { context_cleanup (); if (thread_cleanup) (*thread_cleanup)(); #ifdef DEBUG_MODE2 printf("\nNo more processes.\n"); #endif /* DEBUG_MODE2 */ exit (0); } t->in_readyq = 0; inconsistent_timer = time_max (inconsistent_timer, t->time); while (timerQh && inconsistent_timer >= timerQh->time) { q_del (timerQh, timerQl, x); x->in_readyq = 1; q_ins (readyQh, readyQt, x); } return t; }
int main(int argc, char **argv) { int create_tap = 1; int num_tests; int ret = 0; int j = 0; int k = -1; int list = 0; int opt; int i; #ifdef __FreeBSD__ PLAIN_REQUIRE_KERNEL_MODULE("if_tap", 0); PLAIN_REQUIRE_KERNEL_MODULE("netmap", 0); #endif memset(&ctx_, 0, sizeof(ctx_)); { struct timespec t; int idx; clock_gettime(CLOCK_REALTIME, &t); srand((unsigned int)t.tv_nsec); idx = rand() % 8000 + 100; snprintf(ctx_.ifname, sizeof(ctx_.ifname), "tap%d", idx); idx = rand() % 800 + 100; snprintf(ctx_.bdgname, sizeof(ctx_.bdgname), "vale%d", idx); } while ((opt = getopt(argc, argv, "hi:j:l")) != -1) { switch (opt) { case 'h': usage(argv[0]); return 0; case 'i': strncpy(ctx_.ifname, optarg, sizeof(ctx_.ifname) - 1); create_tap = 0; break; case 'j': if (parse_interval(optarg, &j, &k) < 0) { usage(argv[0]); return -1; } break; case 'l': list = 1; create_tap = 0; break; default: printf(" Unrecognized option %c\n", opt); usage(argv[0]); return -1; } } num_tests = sizeof(tests) / sizeof(tests[0]); if (j < 0 || j >= num_tests || k > num_tests) { fprintf(stderr, "Test interval %d-%d out of range (%d-%d)\n", j + 1, k, 1, num_tests + 1); return -1; } if (k < 0) k = num_tests; if (list) { printf("Available tests:\n"); for (i = 0; i < num_tests; i++) { printf("#%03d: %s\n", i + 1, tests[i].name); } return 0; } if (create_tap) { struct sigaction sa; const char *av[8]; int ac = 0; #ifdef __FreeBSD__ ARGV_APPEND(av, ac, "ifconfig"); ARGV_APPEND(av, ac, ctx_.ifname); ARGV_APPEND(av, ac, "create"); ARGV_APPEND(av, ac, "up"); #else ARGV_APPEND(av, ac, "ip"); ARGV_APPEND(av, ac, "tuntap"); ARGV_APPEND(av, ac, "add"); ARGV_APPEND(av, ac, "mode"); ARGV_APPEND(av, ac, "tap"); ARGV_APPEND(av, ac, "name"); ARGV_APPEND(av, ac, ctx_.ifname); #endif ARGV_APPEND(av, ac, NULL); if (exec_command(ac, av)) { printf("Failed to create tap interface\n"); return -1; } sa.sa_handler = tap_cleanup; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; ret = sigaction(SIGINT, &sa, NULL); if (ret) { perror("sigaction(SIGINT)"); goto out; } ret = sigaction(SIGTERM, &sa, NULL); if (ret) { perror("sigaction(SIGTERM)"); goto out; } } for (i = j; i < k; i++) { struct TestContext ctxcopy; int fd; printf("==> Start of Test #%d [%s]\n", i + 1, tests[i].name); fd = open("/dev/netmap", O_RDWR); if (fd < 0) { perror("open(/dev/netmap)"); ret = fd; goto out; } memcpy(&ctxcopy, &ctx_, sizeof(ctxcopy)); ctxcopy.fd = fd; memcpy(ctxcopy.ifname_ext, ctxcopy.ifname, sizeof(ctxcopy.ifname)); ret = tests[i].test(&ctxcopy); if (ret != 0) { printf("Test #%d [%s] failed\n", i + 1, tests[i].name); goto out; } printf("==> Test #%d [%s] successful\n", i + 1, tests[i].name); context_cleanup(&ctxcopy); } out: tap_cleanup(0); return ret; }