summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/patree.c3
-rw-r--r--src/ring.c15
-rw-r--r--test/ring_test.c96
-rwxr-xr-xwafbin86496 -> 91079 bytes
-rw-r--r--wscript38
-rw-r--r--zix/ring.h2
6 files changed, 126 insertions, 28 deletions
diff --git a/src/patree.c b/src/patree.c
index b8fd183..0cb74d3 100644
--- a/src/patree.c
+++ b/src/patree.c
@@ -289,7 +289,6 @@ change_index_c(const char* a, const char* b, size_t len)
static inline int
change_index_sse(const char* a, const char* b, const size_t len)
{
- int ret;
for (size_t i = 0; i < len; i += sizeof(__m128i)) {
const __m128i r = _mm_loadu_si128((const __m128i*)(a + i));
const __m128i* s = (const __m128i*)(b + i);
@@ -297,7 +296,7 @@ change_index_sse(const char* a, const char* b, const size_t len)
r, *s, _SIDD_SBYTE_OPS|_SIDD_CMP_EQUAL_EACH|_SIDD_NEGATIVE_POLARITY);
if (index != sizeof(__m128i)) {
- int ret = i + index;
+ size_t ret = i + index;
if (ret > len) {
ret = len;
}
diff --git a/src/ring.c b/src/ring.c
index 5edc200..fd5133a 100644
--- a/src/ring.c
+++ b/src/ring.c
@@ -14,7 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -70,8 +69,6 @@ zix_ring_new(uint32_t size)
ring->size = next_power_of_two(size);
ring->size_mask = ring->size - 1;
ring->buf = malloc(ring->size);
- assert(zix_ring_read_space(ring) == 0);
- assert(zix_ring_write_space(ring) == ring->size - 1);
return ring;
}
@@ -103,7 +100,7 @@ zix_ring_reset(ZixRing* ring)
static inline uint32_t
read_space_internal(const ZixRing* ring, uint32_t r, uint32_t w)
{
- if (w > r) {
+ if (r < w) {
return w - r;
} else {
return (w - r + ring->size) & ring->size_mask;
@@ -119,12 +116,12 @@ zix_ring_read_space(const ZixRing* ring)
static inline uint32_t
write_space_internal(const ZixRing* ring, uint32_t r, uint32_t w)
{
- if (w > r) {
+ if (r == w) {
+ return ring->size - 1;
+ } else if (r < w) {
return ((r - w + ring->size) & ring->size_mask) - 1;
- } else if (w < r) {
- return (r - w) - 1;
} else {
- return ring->size - 1;
+ return (r - w) - 1;
}
}
@@ -212,8 +209,6 @@ zix_ring_write(ZixRing* ring, const void* src, uint32_t size)
ring->write_head = (w + size) & ring->size_mask;
} else {
const uint32_t this_size = ring->size - w;
- assert(this_size < size);
- assert(w + this_size <= ring->size);
memcpy(&ring->buf[w], src, this_size);
memcpy(&ring->buf[0], (char*)src + this_size, size - this_size);
ZIX_WRITE_BARRIER();
diff --git a/test/ring_test.c b/test/ring_test.c
index 7cde650..658f6af 100644
--- a/test/ring_test.c
+++ b/test/ring_test.c
@@ -16,6 +16,7 @@
#include <limits.h>
#include <pthread.h>
+#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -30,6 +31,17 @@ size_t n_writes = 0;
bool read_error = false;
static int
+failure(const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ fprintf(stderr, "error: ");
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ return 1;
+}
+
+static int
gen_msg(int* msg, int start)
{
for (int i = 0; i < MSG_SIZE; ++i) {
@@ -120,26 +132,100 @@ main(int argc, char** argv)
n_writes, MSG_SIZE, size);
ring = zix_ring_new(size);
+ if (zix_ring_read_space(ring) != 0) {
+ return failure("New ring is not empty\n");
+ }
+ if (zix_ring_write_space(ring) != zix_ring_capacity(ring)) {
+ return failure("New ring write space != capacity\n");
+ }
+
+ zix_ring_mlock(ring);
pthread_t reader_thread;
if (pthread_create(&reader_thread, NULL, reader, NULL)) {
- fprintf(stderr, "Failed to create reader thread\n");
- return 1;
+ return failure("Failed to create reader thread\n");
}
pthread_t writer_thread;
if (pthread_create(&writer_thread, NULL, writer, NULL)) {
- fprintf(stderr, "Failed to create writer thread\n");
- return 1;
+ return failure("Failed to create writer thread\n");
}
pthread_join(reader_thread, NULL);
pthread_join(writer_thread, NULL);
if (read_error) {
- fprintf(stderr, "FAIL: Read error\n");
+ return failure("Read error\n");
+ }
+
+ zix_ring_reset(ring);
+ if (zix_ring_read_space(ring) > 0) {
+ fprintf(stderr, "Reset did not empty ring.\n");
return 1;
}
+ if (zix_ring_write_space(ring) != zix_ring_capacity(ring)) {
+ fprintf(stderr, "Empty write space != capacity\n");
+ return 1;
+ }
+
+ zix_ring_write(ring, "a", 1);
+ zix_ring_write(ring, "b", 1);
+
+ char buf;
+ uint32_t n = zix_ring_peek(ring, &buf, 1);
+ if (n != 1) {
+ return failure("Peek n (%d) != 1\n", n);
+ }
+ if (buf != 'a') {
+ return failure("Peek error: '%c' != 'a'\n", buf);
+ }
+
+ n = zix_ring_skip(ring, 1);
+ if (n != 1) {
+ return failure("Skip n (%d) != 1\n", n);
+ }
+
+ if (zix_ring_read_space(ring) != 1) {
+ return failure("Read space %d != 1\n", zix_ring_read_space(ring));
+ }
+
+ n = zix_ring_read(ring, &buf, 1);
+ if (n != 1) {
+ return failure("Peek n (%d) != 1\n", n);
+ }
+ if (buf != 'b') {
+ return failure("Peek error: '%c' != 'b'\n", buf);
+ }
+
+ if (zix_ring_read_space(ring) != 0) {
+ return failure("Read space %d != 0\n", zix_ring_read_space(ring));
+ }
+
+ n = zix_ring_peek(ring, &buf, 1);
+ if (n > 0) {
+ return failure("Successful underrun peak\n");
+ }
+
+ n = zix_ring_read(ring, &buf, 1);
+ if (n > 0) {
+ return failure("Successful underrun read\n");
+ }
+
+ n = zix_ring_skip(ring, 1);
+ if (n > 0) {
+ return failure("Successful underrun read\n");
+ }
+
+ char* big_buf = calloc(size, 1);
+ n = zix_ring_write(ring, big_buf, size - 1);
+ if (n != (uint32_t)size - 1) {
+ return failure("Maximum size write failed (wrote %u)\n", n);
+ }
+
+ n = zix_ring_write(ring, big_buf, size);
+ if (n != 0) {
+ return failure("Successful overrun write (size %u)\n", n);
+ }
zix_ring_free(ring);
return 0;
diff --git a/waf b/waf
index ccc19b6..67f6ed2 100755
--- a/waf
+++ b/waf
Binary files differ
diff --git a/wscript b/wscript
index 7c86b4c..965426d 100644
--- a/wscript
+++ b/wscript
@@ -9,7 +9,8 @@ from waflib.extras import autowaf as autowaf
import waflib.Logs as Logs, waflib.Options as Options
# Version of this package (even if built as a child)
-ZIX_VERSION = '0.0.2'
+ZIX_VERSION = '0.0.2'
+ZIX_MAJOR_VERSION = '0'
# Library version (UNIX style major, minor, micro)
# major increment <=> incompatible changes
@@ -41,14 +42,21 @@ def configure(conf):
conf.load('compiler_c')
conf.env.append_value('CFLAGS', '-std=c99')
+ conf.env['BUILD_BENCH'] = Options.options.build_bench
+ conf.env['BUILD_TESTS'] = Options.options.build_tests
+
# Check for mlock
conf.check(function_name='mlock',
header_name='sys/mman.h',
define_name='HAVE_MLOCK',
mandatory=False)
- conf.env['BUILD_BENCH'] = Options.options.build_bench
- conf.env['BUILD_TESTS'] = Options.options.build_tests
+ # Check for gcov library (for test coverage)
+ if conf.env['BUILD_TESTS']:
+ conf.check_cc(lib='gcov',
+ define_name='HAVE_GCOV',
+ mandatory=False)
+
if Options.options.build_bench:
autowaf.check_pkg(conf, 'glib-2.0', uselib_store='GLIB',
atleast_version='2.0.0', mandatory=False)
@@ -77,7 +85,8 @@ def build(bld):
bld.install_files('${INCLUDEDIR}/zix', bld.path.ant_glob('zix/*.h'))
# Pkgconfig file
- autowaf.build_pc(bld, 'ZIX', ZIX_VERSION, [])
+ autowaf.build_pc(bld, 'ZIX', ZIX_VERSION, ZIX_MAJOR_VERSION, [],
+ {'ZIX_MAJOR_VERSION' : ZIX_MAJOR_VERSION})
framework = ''
if Options.platform == 'darwin':
@@ -108,27 +117,34 @@ def build(bld):
'-DZIX_INTERNAL' ])
if bld.env['BUILD_TESTS']:
+ test_libs = ['pthread']
+ test_cflags = []
+ if bld.is_defined('HAVE_GCOV'):
+ test_libs += ['gcov']
+ test_cflags += ['-fprofile-arcs', '-ftest-coverage']
+
# Static library (for unit test code coverage)
obj = bld(features = 'c cstlib',
source = lib_source,
includes = ['.', './src'],
- name = 'libzix_static',
- target = 'zix_static',
+ lib = test_libs,
+ name = 'libzix_profiled',
+ target = 'zix_profiled',
install_path = '',
framework = framework,
- cflags = ['-fprofile-arcs', '-ftest-coverage'])
+ cflags = test_cflags + ['-DZIX_INTERNAL'])
# Unit test programs
for i in tests:
obj = bld(features = 'c cprogram',
source = 'test/%s.c' % i,
includes = ['.'],
- use = 'libzix_static',
- linkflags = ['-lgcov', '-lpthread'],
+ use = 'libzix_profiled',
+ lib = test_libs,
target = 'test/%s' % i,
install_path = '',
framework = framework,
- cflags = ['-fprofile-arcs', '-ftest-coverage' ])
+ cflags = test_cflags)
if bld.env['BUILD_BENCH']:
# Benchmark programs
@@ -138,7 +154,7 @@ def build(bld):
includes = ['.'],
use = 'libzix',
uselib = 'GLIB',
- linkflags = '-lrt',
+ lib = ['rt'],
target = 'test/%s' % i,
framework = framework,
install_path = '')
diff --git a/zix/ring.h b/zix/ring.h
index 67b71f5..3abb1e8 100644
--- a/zix/ring.h
+++ b/zix/ring.h
@@ -32,6 +32,8 @@ typedef struct ZixRingImpl ZixRing;
/**
Create a new ring.
@param size Size in bytes (note this may be rounded up).
+
+ At most @c size - 1 bytes may be stored in the ring at once.
*/
ZixRing*
zix_ring_new(uint32_t size);