diff options
-rw-r--r-- | include/rb.h | 4 | ||||
-rw-r--r-- | man/rb_overview.7 | 4 | ||||
-rw-r--r-- | man/rb_space.3 | 11 | ||||
-rw-r--r-- | rb/rb.c | 102 | ||||
-rw-r--r-- | rb/tests.c | 39 |
5 files changed, 141 insertions, 19 deletions
diff --git a/include/rb.h b/include/rb.h index aa17de8..99816b8 100644 --- a/include/rb.h +++ b/include/rb.h @@ -38,7 +38,7 @@ int rb_destroy(struct rb *); int rb_stop(struct rb *); size_t rb_discard(struct rb *, size_t); const char *rb_version(char *, char *, char *); -size_t rb_count(const struct rb *); -size_t rb_space(const struct rb *); +long rb_count(struct rb *); +long rb_space(struct rb *); #endif diff --git a/man/rb_overview.7 b/man/rb_overview.7 index f6581cd..1476fcf 100644 --- a/man/rb_overview.7 +++ b/man/rb_overview.7 @@ -32,9 +32,9 @@ unsigned long " flags ");" size_t " count ", unsigned long " flags ");" .BI "int rb_clear(struct rb *" rb ", int " clear ");" .br -.BI "size_t rb_count(struct rb *" rb ");" +.BI "long rb_count(struct rb *" rb ");" .br -.BI "size_t rb_space(struct rb *" rb ");" +.BI "long rb_space(struct rb *" rb ");" .br .BI "int rb_stop(struct rb *" rb ");" .br diff --git a/man/rb_space.3 b/man/rb_space.3 index 7f8f113..35e2ef1 100644 --- a/man/rb_space.3 +++ b/man/rb_space.3 @@ -8,9 +8,9 @@ .PP .BI "#include <librb.h>" .PP -.BI "size_t rb_count(struct rb *" rb ");" +.BI "long rb_count(struct rb *" rb ");" .br -.BI "size_t rb_space(struct rb *" rb ");" +.BI "long rb_space(struct rb *" rb ");" .SH RETURN VALUES .PP .BR rb_count (3) @@ -21,6 +21,13 @@ that are currently stored in buffer, and returns number of how many .B elements you can put on the buffer. +.SH ERRORS +.PP +.TP +.B EINVAL +Passed +.I rb +object is invalid. .SH SEE ALSO .PP .BR rb_overview (7), @@ -90,6 +90,36 @@ struct rb /* ========================================================================== + Calculates number of elements in ring buffer. ns stands for not safe as + in there are no checks. + ========================================================================== */ + + +static size_t rb_count_ns +( + const struct rb *rb /* rb object */ +) +{ + return (rb->head - rb->tail) & (rb->count - 1); +} + + +/* ========================================================================== + Calculates how many elements can be pushed into ring buffer. ns stands + for nos safe as in there are no checks. + ========================================================================== */ + + +static size_t rb_space_ns +( + const struct rb *rb /* rb object */ +) +{ + return (rb->tail - (rb->head + 1)) & (rb->count - 1); +} + + +/* ========================================================================== Calculates number of elements in ring buffer until the end of buffer memory. If elements don't overlap memory, function acts like rb_count ========================================================================== */ @@ -174,7 +204,7 @@ static long rb_recvs unsigned char* buf; /* buffer treated as unsigned char type */ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - if (count > (rbcount = rb_count(rb))) + if (count > (rbcount = rb_count_ns(rb))) { /* * Caller requested more data then is available, adjust count @@ -271,7 +301,7 @@ static long rb_recvt pthread_mutex_lock(&rb->lock); - while (rb_count(rb) == 0 && rb->force_exit == 0) + while (rb_count_ns(rb) == 0 && rb->force_exit == 0) { struct timespec ts; /* timeout for pthread_cond_timedwait */ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ @@ -390,7 +420,7 @@ static long rb_sends (void)flags; - if (count > (rbspace = rb_space(rb))) + if (count > (rbspace = rb_space_ns(rb))) { /* * Caller wants to store more data then there is space available @@ -475,7 +505,7 @@ long rb_sendt pthread_mutex_lock(&rb->lock); - while (rb_space(rb) == 0 && rb->force_exit == 0) + while (rb_space_ns(rb) == 0 && rb->force_exit == 0) { struct timespec ts; /* timeout for pthread_cond_timedwait */ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ @@ -1015,7 +1045,7 @@ size_t rb_discard #endif cnte = rb_count_end(rb); - rbcount = rb_count(rb); + rbcount = rb_count_ns(rb); if (count > rbcount) { @@ -1072,28 +1102,74 @@ const char* rb_version /* ========================================================================== - Calculates number of elements in ring buffer + Returns number of elements in buffer. ========================================================================== */ -size_t rb_count +long rb_count ( - const struct rb *rb /* rb object */ + struct rb *rb /* rb object */ ) { - return (rb->head - rb->tail) & (rb->count - 1); + size_t count; /* number of elements in buffer */ + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + + + VALID(EINVAL, rb); + VALID(EINVAL, rb->buffer); + +#if ENABLE_THREADS + if ((rb->flags & O_NONBLOCK) == 0) + { + pthread_mutex_lock(&rb->lock); + } +#endif + + count = rb_count_ns(rb); + +#if ENABLE_THREADS + if ((rb->flags & O_NONBLOCK) == 0) + { + pthread_mutex_unlock(&rb->lock); + } +#endif + + return (long)count; } /* ========================================================================== - Calculates how many elements can be pushed into ring buffer + Return number of free space in buffer ========================================================================== */ -size_t rb_space +long rb_space ( - const struct rb *rb /* rb object */ + struct rb *rb /* rb object */ ) { - return (rb->tail - (rb->head + 1)) & (rb->count - 1); + size_t space; /* number of free slots in buffer */ + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + + + VALID(EINVAL, rb); + VALID(EINVAL, rb->buffer); + +#if ENABLE_THREADS + if ((rb->flags & O_NONBLOCK) == 0) + { + pthread_mutex_lock(&rb->lock); + } +#endif + + space = rb_space_ns(rb); + +#if ENABLE_THREADS + if ((rb->flags & O_NONBLOCK) == 0) + { + pthread_mutex_unlock(&rb->lock); + } +#endif + + return (long)space; } @@ -527,6 +527,44 @@ static void discard(void) } } +static void count_and_space(void) +{ + char d[4]; + struct rb *rb; + + rb = rb_new(16, 1, 0); + + mt_fail(rb_space(rb) == 15); + mt_fail(rb_count(rb) == 0); + + rb_write(rb, "123", 3); + + mt_fail(rb_space(rb) == 12); + mt_fail(rb_count(rb) == 3); + + rb_write(rb, "1234567", 7); + + mt_fail(rb_space(rb) == 5); + mt_fail(rb_count(rb) == 10); + + rb_read(rb, d, 4); + + mt_fail(rb_space(rb) == 9); + mt_fail(rb_count(rb) == 6); + + rb_discard(rb, 5); + + mt_fail(rb_space(rb) == 14); + mt_fail(rb_count(rb) == 1); + + rb_discard(rb, 999); + + mt_fail(rb_space(rb) == 15); + mt_fail(rb_count(rb) == 0); + + rb_destroy(rb); +} + static void bad_count_value(void) { struct rb *rb; @@ -588,6 +626,7 @@ int main(void) mt_run(nonblocking_flag); mt_run(singlethread_eagain); mt_run(discard); + mt_run(count_and_space); #if ENABLE_THREADS mt_run(multithread_eagain); |