diff options
-rw-r--r-- | lib/qpselect.c | 165 |
1 files changed, 132 insertions, 33 deletions
diff --git a/lib/qpselect.c b/lib/qpselect.c index aafb2ca7..9f5417d0 100644 --- a/lib/qpselect.c +++ b/lib/qpselect.c @@ -401,15 +401,7 @@ qps_dispatch_next(qps_selection qps) } ; qps->pend_count -= 1 ; /* one less pending */ - - if (qps->pend_count > 0) - qps->pend_fd = fd ; /* update scan */ - else - { - qps->pend_mnum = 0 ; /* tidy up as we complete */ - qps->pend_fd = 0 ; - qps->tried_fd_last = 0 ; - } ; + qps->pend_fd = fd ; /* update scan */ qf = qps_file_lookup_fd(qps, fd, NULL) ; @@ -579,15 +571,6 @@ qps_disable_modes(qps_file qf, qps_mbit_t mbits) { FD_CLR(qf->fd, &(qps->results[mnum].fdset)) ; --qps->pend_count ; - if (qps->pend_count == 0) - { - qps_mnum_t m ; - qps->tried_fd_last = 0 ; - for (m = 0 ; m < qps_mnum_count ; ++m) - qps->tried_count[mnum] = 0 ; - qps->pend_mnum = 0 ; - qps->pend_fd = 0 ; - } ; } ; mbits ^= qps_mbit(mnum) ; @@ -631,7 +614,7 @@ qps_file_lookup_fd(qps_selection qps, int fd, qps_file insert) vector_index i ; int ret ; - dassert((fd >= 0) && (fd <= qps->fd_last)) ; + dassert((fd >= 0) && (fd < FD_SETSIZE)) ; /* Look-up */ /* */ @@ -785,6 +768,64 @@ static uint8_t fd_bit_map [FD_SETSIZE] ; /* maps fd to bit in byte */ static int8_t fd_first_map[256] ; /* maps byte value to 0..7, where that */ /* is the lowest fd bit set in byte. */ +#define QPS_TESTING 0 /* true => testing */ + +#if !QPS_TESTING + +/* Not testing, so map to the standard FD_SET etc. functions. */ +# define qFD_SET FD_SET +# define qFD_CLR FD_CLR +# define qFD_ISSET FD_ISSET +# define qFD_ZERO FD_ZERO + +#else + +/* Set up the testing */ + +# define QPS_TEST_WORD 4 /* Wordsize */ +# define QPS_TEST_BE 1 /* true => big-endian */ +# define QPS_TEST_B_ORD 07 /* 07 => bits 0..7, 70 => bits 7..0 */ + +# define QPS_TEST_WORD_BITS (QPS_TEST_WORD * 8) +# if QPS_TEST_BE +# define QPS_BYTE(fd) ( ((fd / QPS_TEST_WORD_BITS) * QPS_TEST_WORD) \ + + (QPS_TEST_WORD - 1) - ((fd % QPS_TEST_WORD_BITS) / 8) ) +#else +# define QPS_BYTE(fd) ( fd / 8 ) +#endif + +# if QPS_TEST_B_ORD == 07 +# define QPS_BIT(fd) (0x01 << (fd & 0x7)) +# else +# define QPS_BIT(fd) (0x80 >> (fd & 0x7)) +# endif + + static void + qFD_SET(int fd, fd_set* set) + { + *((uint8_t*)set + QPS_BYTE(fd)) |= QPS_BIT(fd) ; + } ; + + static void + qFD_CLR(int fd, fd_set* set) + { + *((uint8_t*)set + QPS_BYTE(fd)) &= ~QPS_BIT(fd) ; + } ; + + static int + qFD_ISSET(int fd, fd_set* set) + { + return (*((uint8_t*)set + QPS_BYTE(fd)) & QPS_BIT(fd)) != 0 ; + } ; + + static void + qFD_ZERO(fd_set* set) + { + memset(set, 0, sizeof(fd_set)) ; + } ; + +#endif + /* Scan for next fd in given fd set, and clear it. * * Starts at the given fd, will not consider anything above fd_last. @@ -841,11 +882,11 @@ qps_make_super_set_map(void) qps_super_set_zero(&test, 1) ; for (fd = 0 ; fd < FD_SETSIZE ; ++fd) - if (FD_ISSET(fd, &test.fdset)) + if (qFD_ISSET(fd, &test.fdset)) zabort("Zeroised fd_super_set is not empty") ; /* (2) check that zeroising the fd_set doesn't change things */ - FD_ZERO(&test.fdset) ; + qFD_ZERO(&test.fdset) ; for (iw = 0 ; iw < FD_SUPER_SET_WORD_SIZE ; ++iw) if (test.words[iw] != 0) zabort("Zeroised fd_super_set is not all zero words") ; @@ -856,7 +897,7 @@ qps_make_super_set_map(void) { fd_word_t w ; - FD_SET(fd, &test.fdset) ; + qFD_SET(fd, &test.fdset) ; w = 0 ; for (iw = 0 ; iw < FD_SUPER_SET_WORD_SIZE ; ++iw) @@ -887,7 +928,7 @@ qps_make_super_set_map(void) if (w == 0) zabort("FD_SET did not set any bit in any word") ; - FD_CLR(fd, &test.fdset) ; + qFD_CLR(fd, &test.fdset) ; for (iw = 0 ; iw < FD_SUPER_SET_WORD_SIZE ; ++iw) if (test.words[iw] != 0) @@ -964,6 +1005,70 @@ qps_make_super_set_map(void) fd_byte_count[fd] = c ; } ; +#if QPS_TESTING + + /* Checking that the maps have been correctly deduced */ + + for (fd = 0 ; fd < FD_SETSIZE ; ++fd) + { + uint8_t b ; + short c ; + + iw = fd / QPS_TEST_WORD_BITS ; + if (QPS_TEST_BE) + ib = ( ((fd / QPS_TEST_WORD_BITS) * QPS_TEST_WORD) + + (QPS_TEST_WORD - 1) - ((fd % QPS_TEST_WORD_BITS) / 8) ) ; + else + ib = ( fd / 8 ) ; + + if (QPS_TEST_B_ORD == 07) + b = 0x01 << (fd % 8) ; + else + b = 0x80 >> (fd % 8) ; + + if (QPS_TEST_BE) + c = (iw + 1) * QPS_TEST_WORD ; + else + c = (ib + 1) ; + + if (fd_word_map[fd] != iw) + zabort("Broken fd_word_map") ; + if (fd_byte_map[fd] != ib) + zabort("Broken fd_byte_map") ; + if (fd_bit_map[fd] != b) + zabort("Broken fd_bit_map") ; + if (fd_byte_count[fd] != c) + zabort("Broken fd_byte_count") ; + } ; + + for (i = 1 ; i < 256 ; ++i) + { + uint8_t b = i ; + fd = 0 ; + if (QPS_TEST_B_ORD == 07) + { + while ((b & 1) == 0) + { + b >>= 1 ; + ++fd ; + } ; + } + else + { + while ((b & 0x80) == 0) + { + b <<= 1 ; + ++fd ; + } ; + } ; + + if (fd_first_map[i] != fd) + zabort("Broken fd_first_map") ; + } ; + + zabort("OK fd mapping") ; +#endif + /* Phew -- we're all set now */ qps_super_set_map_made = 1 ; } ; @@ -1044,8 +1149,7 @@ qps_super_set_count(fd_super_set* p_set, int n) * * If there are no pending fds: * - * 10) if there are no pending fds, that the results vectors are empty - * that tried_fd_last, tried_count[], pend_mnum and pend_fd are all zero. + * 10) if there are no pending fds, that the results vectors are empty. * * If there are pending fds: * @@ -1143,16 +1247,11 @@ qps_selection_validate(qps_selection qps) if (qps_super_set_cmp(enabled, qps->enabled, qps_mnum_count) != 0) zabort("Enabled bit vectors do not tally") ; - /* 10) if there are no pending fds, check that everything is zero. */ + /* 10) if there are no pending fds, check result vectors empty. */ if (qps->pend_count == 0) { - n = (qps_super_set_count(qps->results, qps_mnum_count) != 0) ; - for (mnum = 0 ; mnum < qps_mnum_count ; ++mnum) - n |= (qps->tried_count[mnum] != 0) ; - n |= (qps->tried_fd_last != 0) || (qps->pend_mnum != 0) - || (qps->pend_fd != 0) ; - if (n) - zabort("Nothing pending, but pending state not zero") ; + if (qps_super_set_count(qps->results, qps_mnum_count) != 0) + zabort("Nothing pending, but result vectors not empty") ; return ; } ; |