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.