Commit 5f12fd96 authored by Geoff Simmons's avatar Geoff Simmons

trackrdrd: fixed a bug computing the SPMC queue length at UINT overflow

           (caught by slink)
parent 9a544f78
AC_PREREQ(2.59) AC_PREREQ(2.59)
AC_COPYRIGHT([Copyright (c) 2012 Otto Gmbh & Co KG]) AC_COPYRIGHT([Copyright (c) 2012 Otto Gmbh & Co KG])
AC_INIT([trackrdrd], [1.0]) AC_INIT([trackrdrd], [1.0.1_SNAPSHOT])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR(src/trackrdrd.c) AC_CONFIG_SRCDIR(src/trackrdrd.c)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
......
...@@ -43,10 +43,9 @@ static pthread_mutex_t spmcq_deq_lock; ...@@ -43,10 +43,9 @@ static pthread_mutex_t spmcq_deq_lock;
static inline unsigned static inline unsigned
spmcq_len(void) spmcq_len(void)
{ {
if (spmcq.tail < spmcq.head) if (spmcq.tail >= spmcq.head)
return UINT_MAX - spmcq.head - 1 - spmcq.tail;
else
return spmcq.tail - spmcq.head; return spmcq.tail - spmcq.head;
return UINT_MAX - spmcq.head + 1 + spmcq.tail;
} }
static void static void
...@@ -99,3 +98,30 @@ void ...@@ -99,3 +98,30 @@ void
AZ(pthread_mutex_unlock(&spmcq_deq_lock)); AZ(pthread_mutex_unlock(&spmcq_deq_lock));
return ptr; return ptr;
} }
#ifdef TEST_DRIVER
int
main(int argc, char * const *argv)
{
(void) argc;
printf("\nTEST: %s\n", argv[0]);
printf("... test SMPCQ enqueue at UINT_MAX overflow\n");
config.maxopen_scale = 0;
SPMCQ_Init();
spmcq.head = spmcq.tail = UINT_MAX - 2;
assert(SPMCQ_Enq(NULL));
assert(SPMCQ_Enq(NULL));
assert(SPMCQ_Enq(NULL));
assert(SPMCQ_Enq(NULL));
assert(SPMCQ_Enq(NULL));
assert(SPMCQ_Enq(NULL));
assert(SPMCQ_Enq(NULL));
assert(spmcq_len() == 7);
printf("%s: 1 test run\n", argv[0]);
exit(0);
}
#endif
INCLUDES = -I$(VARNISHSRC)/include -I$(VARNISHSRC) @AMQ_CFLAGS@ INCLUDES = -I$(VARNISHSRC)/include -I$(VARNISHSRC) @AMQ_CFLAGS@
TESTS = test_parse test_data test_mq test_spmcq test_spmcq_loop.sh \ TESTS = test_parse test_data test_mq test_spmcq test_spmcq_loop.sh \
test_worker regress.sh test_spmcq_len test_worker regress.sh
check_PROGRAMS = test_parse test_data test_mq test_spmcq test_worker check_PROGRAMS = test_parse test_data test_mq test_spmcq test_spmcq_len \
test_worker
test_parse_SOURCES = \ test_parse_SOURCES = \
minunit.h \ minunit.h \
...@@ -42,6 +43,16 @@ test_spmcq_LDADD = \ ...@@ -42,6 +43,16 @@ test_spmcq_LDADD = \
$(VARNISHSRC)/lib/libvarnish/libvarnish.la \ $(VARNISHSRC)/lib/libvarnish/libvarnish.la \
../spmcq.$(OBJEXT) ../spmcq.$(OBJEXT)
test_spmcq_len_SOURCES = \
$(VARNISHSRC)/lib/libvarnish/libvarnish.la \
../spmcq.c \
../trackrdrd.h
test_spmcq_len_LDADD = \
$(VARNISHSRC)/lib/libvarnish/libvarnish.la
test_spmcq_len_CFLAGS = -DTEST_DRIVER
test_worker_SOURCES = \ test_worker_SOURCES = \
minunit.h \ minunit.h \
test_worker.c \ test_worker.c \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment