diff --git a/gtests/net/packetdrill/run.c b/gtests/net/packetdrill/run.c index 0a7d3751bd667fac6ae65b56133538f363df32ac..54f4ebbdd09d0c67ad960c46b17b7afb5d0ddf42 100644 --- a/gtests/net/packetdrill/run.c +++ b/gtests/net/packetdrill/run.c @@ -62,7 +62,11 @@ * sequence that wait_for_event() must execute while waiting * for the next event. */ +#if defined(__FreeBSD__) +const int MAX_SPIN_USECS = 100; +#else const int MAX_SPIN_USECS = 20; +#endif static struct state *state = NULL; @@ -328,7 +332,7 @@ void wait_for_event(struct state *state) * that we know has a fine-grained usleep(), then * usleep() instead of spinning on the CPU. */ -#if defined(linux) || defined(__FreeBSD__) +#if defined(linux) /* Since the scheduler may not wake us up precisely * when we tell it to, sleep until just before the * event we're waiting for and then spin. @@ -337,6 +341,20 @@ void wait_for_event(struct state *state) usleep(wait_usecs - MAX_SPIN_USECS); } #endif +#if defined(__FreeBSD__) + /* Since the scheduler may not wake us up precisely + * when we tell it to, sleep until just before the + * event we're waiting for and then spin. + * Since FreeBSD is overshooting by about 10 percent, + * take this into account. + */ + if (wait_usecs > MAX_SPIN_USECS) { + useconds_t delta = (useconds_t)(wait_usecs - MAX_SPIN_USECS); + + delta -= delta >> 3; + usleep(delta); + } +#endif /* At this point we should only have a millisecond or * two to wait, so we spin. diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index fa4033bef4b955eaa9ce54068e82db8a117472bb..5a1af9a190b941a1c99be5b0af93b706100b36a7 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -3274,24 +3274,17 @@ static int do_inbound_script_packet( packet_payload_len(live_packet); } - if (live_packet->ipv4 != NULL) { - if (live_packet->ipv4->src_ip.s_addr == 0) { - DEBUGP("live_packet->ipv4->src_ip.s_addr == 0\n"); - state->socket_under_test = setup_new_child_socket(state, packet); + if ((state->socket_under_test == NULL) && + (((live_packet->ipv4 != NULL) && + (live_packet->ipv4->src_ip.s_addr == htonl(INADDR_ANY))) || + ((live_packet->ipv6 != NULL) && + (IN6_IS_ADDR_UNSPECIFIED(&live_packet->ipv6->src_ip))))) { struct tuple live_inbound; - socket_get_inbound(&state->socket_under_test->live, &live_inbound); - set_packet_tuple(live_packet, &live_inbound); - } - } - if (live_packet->ipv6 != NULL) { - if (IN6_IS_ADDR_UNSPECIFIED(&live_packet->ipv6->src_ip)) { - DEBUGP("live_packet->ipv6->src_ip.s_addr == 0\n"); + DEBUGP("live_packet has wildcard source address\n"); state->socket_under_test = setup_new_child_socket(state, packet); - struct tuple live_inbound; socket_get_inbound(&state->socket_under_test->live, &live_inbound); set_packet_tuple(live_packet, &live_inbound); - } } /* Inject live packet into kernel. */ diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 3f87f607d0b1bb74aa253be2afb4315a46be6673..13f0b086ea4213b023360157ef062d6d4e6ffac2 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -6659,22 +6659,25 @@ void syscalls_free(struct state *state, struct syscalls *syscalls, int about_to_ syscalls->event->line_number); } - if (status == STATUS_OK) { + if (status == STATUS_ERR) { + /* Canceling the thread. */ + DEBUGP("main thread: canceling syscall thread \n"); + pthread_cancel(syscalls->thread); + } else { /* Send a request to terminate the thread. */ DEBUGP("main thread: signaling syscall thread to exit\n"); syscalls->state = SYSCALL_EXITING; if (pthread_cond_signal(&syscalls->enqueued) != 0) die_perror("pthread_cond_signal"); - - /* Release the lock briefly and wait for syscall thread to finish. */ - run_unlock(state); - DEBUGP("main thread: unlocking, waiting for syscall thread exit\n"); - void *thread_result = NULL; - if (pthread_join(syscalls->thread, &thread_result) != 0) - die_perror("pthread_cancel"); - DEBUGP("main thread: joined syscall thread; relocking\n"); - run_lock(state); } + /* Release the lock briefly and wait for syscall thread to finish. */ + run_unlock(state); + DEBUGP("main thread: unlocking, waiting for syscall thread exit\n"); + void *thread_result = NULL; + if (pthread_join(syscalls->thread, &thread_result) != 0) + die_perror("pthread_cancel"); + DEBUGP("main thread: joined syscall thread; relocking\n"); + run_lock(state); if ((pthread_cond_destroy(&syscalls->idle) != 0) || (pthread_cond_destroy(&syscalls->enqueued) != 0) || (pthread_cond_destroy(&syscalls->dequeued) != 0)) {