2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)ringbuff.c 1.8 02/11/21 Copyright 1998,1999,2000 Heiko Eissfeldt */
21 #if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES)
26 #include <usal/scsitransp.h>
30 #include "interface.h"
33 #include "exitcodes.h"
39 static void occupy_buffer(void);
41 myringbuff **he_fill_buffer;
42 myringbuff **last_buffer;
43 volatile unsigned long *total_segments_read;
44 volatile unsigned long *total_segments_written;
45 volatile int *child_waits;
46 volatile int *parent_waits;
47 volatile int *in_lendian;
48 volatile int *eorecording;
50 static myringbuff *previous_read_buffer;
51 static unsigned int total_buffers;
55 #define defined_buffers() ((*total_segments_read) - (*total_segments_written))
56 #define free_buffers() (total_buffers - defined_buffers())
57 #define occupied_buffers() (defined_buffers())
60 void set_total_buffers(unsigned int num_buffers, int mysem_id)
62 #if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES)
63 union my_semun mysemun;
66 if (semctl(mysem_id,(int) DEF_SEM,SETVAL,mysemun) < 0) {
67 perror("semctl DEF_SEM");
70 mysemun.val = num_buffers;
71 if (semctl(mysem_id,(int) FREE_SEM,SETVAL,mysemun) < 0) {
72 perror("semctl FREE_SEM");
76 total_buffers = num_buffers;
78 /* initialize pointers */
79 *he_fill_buffer = *last_buffer = previous_read_buffer = NULL;
81 fprintf(stderr, "init: fill_b = %p, last_b = %p\n", *he_fill_buffer, *last_buffer);
85 const myringbuff *get_previous_read_buffer()
87 assert(previous_read_buffer != NULL);
88 assert(previous_read_buffer != *he_fill_buffer);
89 return previous_read_buffer;
92 const myringbuff *get_he_fill_buffer()
94 assert(*he_fill_buffer != NULL);
95 assert(previous_read_buffer != *he_fill_buffer);
96 return *he_fill_buffer;
101 assert(defined_buffers() < total_buffers);
105 fprintf(stderr,"stop reading %p - %p\n",
106 *he_fill_buffer, (char *)(*he_fill_buffer) + ENTRY_SIZE -1);
110 if (*last_buffer == NULL)
111 *last_buffer = *he_fill_buffer;
113 fprintf(stderr, "define: fill_b = %p, last_b = %p\n", *he_fill_buffer, *last_buffer);
116 (*total_segments_read)++;
117 semrelease(sem_id,DEF_SEM,1);
122 assert(free_buffers() < total_buffers);
123 assert(occupied_buffers() > 0);
127 fprintf(stderr," stop writing %p - %p ",
128 *last_buffer, (char *)(*last_buffer) + ENTRY_SIZE -1);
132 if (*last_buffer == NULL)
133 *last_buffer = *he_fill_buffer;
135 *last_buffer = INC(*last_buffer);
137 fprintf(stderr, "drop: fill_b = %p, last_b = %p\n", *he_fill_buffer, *last_buffer);
139 (*total_segments_written)++;
140 semrelease(sem_id,FREE_SEM, 1);
143 void drop_all_buffers()
145 (*total_segments_written) = (*total_segments_read);
146 semrelease(sem_id,FREE_SEM, total_buffers);
149 static void occupy_buffer()
151 assert(occupied_buffers() <= total_buffers);
153 previous_read_buffer = *he_fill_buffer;
155 if (*he_fill_buffer == NULL) {
156 *he_fill_buffer = RB_BASE;
158 *he_fill_buffer = INC(*he_fill_buffer);
162 #if defined HAVE_FORK_AND_SHAREDMEM
163 myringbuff * get_next_buffer()
165 #ifdef WARN_INTERRUPT
166 if (free_buffers() <= 0) {
167 fprintf(stderr, "READER waits!! r=%lu, w=%lu\n", *total_segments_read,
168 *total_segments_written);
172 /* wait for a new buffer to become available */
173 if (semrequest(sem_id,FREE_SEM) != 0) {
174 /* semaphore operation failed.
177 fprintf(stderr, "child reader sem request failed\n");
178 exit(SEMAPHORE_ERROR);
181 fprintf(stderr,"start reading %p - %p\n",
182 *he_fill_buffer, (char *)(*fill_buffer) + ENTRY_SIZE -1);
188 fprintf(stderr, "next: fill_b = %p, last_b = %p, @last = %p\n", *he_fill_buffer, *last_buffer, last_buffer);
190 return *he_fill_buffer;
193 myringbuff *get_oldest_buffer()
197 #ifdef WARN_INTERRUPT
198 if (free_buffers() == total_buffers) {
199 fprintf(stderr, "WRITER waits!! r=%lu, w=%lu\n", *total_segments_read,
200 *total_segments_written);
203 /* wait for buffer to be defined */
204 if (semrequest(sem_id,DEF_SEM) != 0) {
205 /* semaphore operation failed. */
206 perror("request defined buff:");
207 fprintf(stderr, "parent writer sem request failed\n");
210 retval = *last_buffer;
213 fprintf(stderr," begin writing %p - %p\n",
214 retval, (char *)retval + ENTRY_SIZE -1);
219 #else /* HAVE_FORK_AND_SHAREDMEM */
220 myringbuff * get_next_buffer()
223 return *he_fill_buffer;
226 myringbuff * get_oldest_buffer()
228 return *he_fill_buffer;
230 #endif /* HAVE_FORK_AND_SHAREDMEM */