diff --git a/src/dnsperf.c b/src/dnsperf.c index 8c731be..f124f64 100644 --- a/src/dnsperf.c +++ b/src/dnsperf.c @@ -853,6 +853,40 @@ wait_for_start(void) PERF_UNLOCK(&start_lock); } +static inline void +bit_set(unsigned char* bits, unsigned int bit) +{ + unsigned int shift, mask; + + shift = 7 - (bit % 8); + mask = 1 << shift; + + bits[bit / 8] |= mask; +} + +static inline void +bit_clear(unsigned char* bits, unsigned int bit) +{ + unsigned int shift, mask; + + shift = 7 - (bit % 8); + mask = 1 << shift; + + bits[bit / 8] &= ~mask; +} + +static inline bool +bit_check(unsigned char* bits, unsigned int bit) +{ + unsigned int shift; + + shift = 7 - (bit % 8); + + if ((bits[bit / 8] >> shift) & 0x01) + return true; + return false; +} + static void* do_send(void* arg) { @@ -871,9 +905,10 @@ do_send(void* arg) unsigned char packet_buffer[MAX_EDNS_PACKET]; unsigned char* base; unsigned int length; - int n, i, any_inprogress = 0; + int n, i, any_inprogress = 0, sock = 0; perf_result_t result; bool all_fail; + unsigned char socketbits[(MAX_SOCKETS / 8) + 1] = {}; tinfo = (threadinfo_t*)arg; config = tinfo->config; @@ -904,8 +939,13 @@ do_send(void* arg) if (any_inprogress) { any_inprogress = 0; for (i = 0; i < tinfo->nsocks; i++) { + if (!bit_check(socketbits, i)) { + continue; + } if (!perf_net_sockready(tinfo->socks[i], threadpipe[0], TIMEOUT_CHECK_TIME)) { any_inprogress = 1; + } else { + bit_clear(socketbits, i); } } } @@ -980,7 +1020,8 @@ do_send(void* arg) i = tinfo->nsocks * 2; all_fail = true; while (i--) { - q->sock = tinfo->socks[tinfo->current_sock++ % tinfo->nsocks]; + sock = tinfo->current_sock++ % tinfo->nsocks; + q->sock = tinfo->socks[sock]; switch (perf_net_sockready(q->sock, threadpipe[0], TIMEOUT_CHECK_TIME)) { case 0: if (config->verbose && !config->suppress.sockready) { @@ -1076,6 +1117,7 @@ do_send(void* arg) perf_log_warning("network congested, packet sending in progress"); } any_inprogress = 1; + bit_set(socketbits, sock); } else { if (config->verbose && !config->suppress.sendfailed) { char __s[256]; @@ -1201,29 +1243,6 @@ recv_one(threadinfo_t* tinfo, int which_sock, return true; } -static inline void -bit_set(unsigned char* bits, unsigned int bit) -{ - unsigned int shift, mask; - - shift = 7 - (bit % 8); - mask = 1 << shift; - - bits[bit / 8] |= mask; -} - -static inline bool -bit_check(unsigned char* bits, unsigned int bit) -{ - unsigned int shift; - - shift = 7 - (bit % 8); - - if ((bits[bit / 8] >> shift) & 0x01) - return true; - return false; -} - static void* do_recv(void* arg) { @@ -1233,7 +1252,7 @@ do_recv(void* arg) received_query_t recvd[RECV_BATCH_SIZE] = { { 0, 0, 0, 0, 0, 0, false, false, 0 } }; unsigned int nrecvd; int saved_errno; - unsigned char socketbits[MAX_SOCKETS / 8]; + unsigned char socketbits[(MAX_SOCKETS / 8) + 1]; uint64_t now, latency; query_info* q; unsigned int current_socket, last_socket; @@ -1656,8 +1675,7 @@ int main(int argc, char** argv) perf_os_handlesignal(SIGINT, handle_sigint); perf_os_blocksignal(SIGINT, false); sock.fd = mainpipe[0]; - result = perf_os_waituntilreadable(&sock, intrpipe[0], - times.stop_time - times.start_time); + result = perf_os_waituntilreadable(&sock, intrpipe[0], times.stop_time - times.start_time); if (result == PERF_R_CANCELED) interrupted = true;