summaryrefslogtreecommitdiff
path: root/icedax/ringbuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'icedax/ringbuff.c')
-rw-r--r--icedax/ringbuff.c231
1 files changed, 231 insertions, 0 deletions
diff --git a/icedax/ringbuff.c b/icedax/ringbuff.c
new file mode 100644
index 0000000..6678ffb
--- /dev/null
+++ b/icedax/ringbuff.c
@@ -0,0 +1,231 @@
+/*
+ * This file has been modified for the cdrkit suite.
+ *
+ * The behaviour and appearence of the program code below can differ to a major
+ * extent from the version distributed by the original author(s).
+ *
+ * For details, see Changelog file distributed with the cdrkit package. If you
+ * received this file from another source then ask the distributing person for
+ * a log of modifications.
+ *
+ */
+
+/* @(#)ringbuff.c 1.8 02/11/21 Copyright 1998,1999,2000 Heiko Eissfeldt */
+#include "config.h"
+
+#include <stdxlib.h>
+#include <stdio.h>
+#include <standard.h>
+#include <unixstd.h>
+
+#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES)
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#endif
+
+#include <usal/scsitransp.h>
+
+#include "mytype.h"
+#include "global.h"
+#include "interface.h"
+#include "ringbuff.h"
+#include "semshm.h"
+#include "exitcodes.h"
+
+#undef WARN_INTERRUPT
+#undef _DEBUG
+#include <assert.h>
+
+static void occupy_buffer(void);
+
+myringbuff **he_fill_buffer;
+myringbuff **last_buffer;
+volatile unsigned long *total_segments_read;
+volatile unsigned long *total_segments_written;
+volatile int *child_waits;
+volatile int *parent_waits;
+volatile int *in_lendian;
+volatile int *eorecording;
+
+static myringbuff *previous_read_buffer;
+static unsigned int total_buffers;
+
+#define SEMS 2
+
+#define defined_buffers() ((*total_segments_read) - (*total_segments_written))
+#define free_buffers() (total_buffers - defined_buffers())
+#define occupied_buffers() (defined_buffers())
+
+/* ARGSUSED */
+void set_total_buffers(unsigned int num_buffers, int mysem_id)
+{
+#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES)
+ union my_semun mysemun;
+
+ mysemun.val = 0;
+ if (semctl(mysem_id,(int) DEF_SEM,SETVAL,mysemun) < 0) {
+ perror("semctl DEF_SEM");
+ }
+
+ mysemun.val = num_buffers;
+ if (semctl(mysem_id,(int) FREE_SEM,SETVAL,mysemun) < 0) {
+ perror("semctl FREE_SEM");
+ }
+#endif
+
+ total_buffers = num_buffers;
+
+ /* initialize pointers */
+ *he_fill_buffer = *last_buffer = previous_read_buffer = NULL;
+#ifdef DEBUG_SHM
+fprintf(stderr, "init: fill_b = %p, last_b = %p\n", *he_fill_buffer, *last_buffer);
+#endif
+}
+
+const myringbuff *get_previous_read_buffer()
+{
+ assert(previous_read_buffer != NULL);
+ assert(previous_read_buffer != *he_fill_buffer);
+ return previous_read_buffer;
+}
+
+const myringbuff *get_he_fill_buffer()
+{
+ assert(*he_fill_buffer != NULL);
+ assert(previous_read_buffer != *he_fill_buffer);
+ return *he_fill_buffer;
+}
+
+void define_buffer()
+{
+ assert(defined_buffers() < total_buffers);
+
+#ifdef _DEBUG
+#if 0
+ fprintf(stderr,"stop reading %p - %p\n",
+ *he_fill_buffer, (char *)(*he_fill_buffer) + ENTRY_SIZE -1);
+#endif
+#endif
+
+ if (*last_buffer == NULL)
+ *last_buffer = *he_fill_buffer;
+#ifdef DEBUG_SHM
+fprintf(stderr, "define: fill_b = %p, last_b = %p\n", *he_fill_buffer, *last_buffer);
+#endif
+
+ (*total_segments_read)++;
+ semrelease(sem_id,DEF_SEM,1);
+}
+
+void drop_buffer()
+{
+ assert(free_buffers() < total_buffers);
+ assert(occupied_buffers() > 0);
+
+#ifdef _DEBUG
+#if 0
+ fprintf(stderr," stop writing %p - %p ",
+ *last_buffer, (char *)(*last_buffer) + ENTRY_SIZE -1);
+#endif
+#endif
+
+ if (*last_buffer == NULL)
+ *last_buffer = *he_fill_buffer;
+ else
+ *last_buffer = INC(*last_buffer);
+#ifdef DEBUG_SHM
+fprintf(stderr, "drop: fill_b = %p, last_b = %p\n", *he_fill_buffer, *last_buffer);
+#endif
+ (*total_segments_written)++;
+ semrelease(sem_id,FREE_SEM, 1);
+}
+
+void drop_all_buffers()
+{
+ (*total_segments_written) = (*total_segments_read);
+ semrelease(sem_id,FREE_SEM, total_buffers);
+}
+
+static void occupy_buffer()
+{
+ assert(occupied_buffers() <= total_buffers);
+
+ previous_read_buffer = *he_fill_buffer;
+
+ if (*he_fill_buffer == NULL) {
+ *he_fill_buffer = RB_BASE;
+ } else {
+ *he_fill_buffer = INC(*he_fill_buffer);
+ }
+}
+
+#if defined HAVE_FORK_AND_SHAREDMEM
+myringbuff * get_next_buffer()
+{
+#ifdef WARN_INTERRUPT
+ if (free_buffers() <= 0) {
+ fprintf(stderr, "READER waits!! r=%lu, w=%lu\n", *total_segments_read,
+*total_segments_written);
+ }
+#endif
+
+ /* wait for a new buffer to become available */
+ if (semrequest(sem_id,FREE_SEM) != 0) {
+ /* semaphore operation failed.
+ try again...
+ */
+ fprintf(stderr, "child reader sem request failed\n");
+ exit(SEMAPHORE_ERROR);
+ }
+#if 0
+ fprintf(stderr,"start reading %p - %p\n",
+ *he_fill_buffer, (char *)(*fill_buffer) + ENTRY_SIZE -1);
+#endif
+
+ occupy_buffer();
+
+#ifdef DEBUG_SHM
+fprintf(stderr, "next: fill_b = %p, last_b = %p, @last = %p\n", *he_fill_buffer, *last_buffer, last_buffer);
+#endif
+ return *he_fill_buffer;
+}
+
+myringbuff *get_oldest_buffer()
+{
+ myringbuff *retval;
+
+#ifdef WARN_INTERRUPT
+ if (free_buffers() == total_buffers) {
+ fprintf(stderr, "WRITER waits!! r=%lu, w=%lu\n", *total_segments_read,
+ *total_segments_written);
+ }
+#endif
+ /* wait for buffer to be defined */
+ if (semrequest(sem_id,DEF_SEM) != 0) {
+ /* semaphore operation failed. */
+ perror("request defined buff:");
+ fprintf(stderr, "parent writer sem request failed\n");
+ }
+
+ retval = *last_buffer;
+
+#if 0
+ fprintf(stderr," begin writing %p - %p\n",
+ retval, (char *)retval + ENTRY_SIZE -1);
+#endif
+
+ return retval;
+}
+#else /* HAVE_FORK_AND_SHAREDMEM */
+myringbuff * get_next_buffer()
+{
+ occupy_buffer();
+ return *he_fill_buffer;
+}
+
+myringbuff * get_oldest_buffer()
+{
+ return *he_fill_buffer;
+}
+#endif /* HAVE_FORK_AND_SHAREDMEM */
+