Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / icedax / ringbuff.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
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).
6  *
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.
10  *
11  */
12
13 /* @(#)ringbuff.c       1.8 02/11/21 Copyright 1998,1999,2000 Heiko Eissfeldt */
14 #include "config.h"
15
16 #include <stdxlib.h>
17 #include <stdio.h>
18 #include <standard.h>
19 #include <unixstd.h>
20
21 #if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES)
22 #include <sys/ipc.h>
23 #include <sys/sem.h>
24 #endif
25
26 #include <usal/scsitransp.h>
27
28 #include "mytype.h"
29 #include "global.h"
30 #include "interface.h"
31 #include "ringbuff.h"
32 #include "semshm.h"
33 #include "exitcodes.h"
34
35 #undef WARN_INTERRUPT
36 #undef _DEBUG
37 #include <assert.h>
38
39 static void occupy_buffer(void);
40
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;
49
50 static myringbuff *previous_read_buffer;
51 static unsigned int total_buffers;
52
53 #define SEMS 2
54
55 #define defined_buffers() ((*total_segments_read) - (*total_segments_written))
56 #define free_buffers() (total_buffers - defined_buffers())
57 #define occupied_buffers() (defined_buffers())
58
59 /* ARGSUSED */
60 void set_total_buffers(unsigned int num_buffers, int mysem_id)
61 {
62 #if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES)
63   union my_semun mysemun;
64
65   mysemun.val   = 0;
66   if (semctl(mysem_id,(int) DEF_SEM,SETVAL,mysemun) < 0) {
67     perror("semctl DEF_SEM");
68   }
69
70   mysemun.val   = num_buffers;
71   if (semctl(mysem_id,(int) FREE_SEM,SETVAL,mysemun) < 0) {
72     perror("semctl FREE_SEM");
73   }
74 #endif
75
76   total_buffers = num_buffers;
77
78   /* initialize pointers */
79   *he_fill_buffer = *last_buffer = previous_read_buffer = NULL;
80 #ifdef DEBUG_SHM
81 fprintf(stderr, "init: fill_b = %p,  last_b = %p\n", *he_fill_buffer, *last_buffer);
82 #endif
83 }
84
85 const myringbuff *get_previous_read_buffer()
86 {
87   assert(previous_read_buffer != NULL);
88   assert(previous_read_buffer != *he_fill_buffer);
89   return previous_read_buffer;
90 }
91
92 const myringbuff *get_he_fill_buffer()
93 {
94   assert(*he_fill_buffer != NULL);
95   assert(previous_read_buffer != *he_fill_buffer);
96   return *he_fill_buffer;
97 }
98
99 void define_buffer()
100 {
101   assert(defined_buffers() < total_buffers);
102
103 #ifdef _DEBUG
104 #if 0
105   fprintf(stderr,"stop  reading  %p - %p\n",
106                  *he_fill_buffer, (char *)(*he_fill_buffer) + ENTRY_SIZE -1);
107 #endif
108 #endif
109
110   if (*last_buffer == NULL)
111     *last_buffer = *he_fill_buffer;
112 #ifdef DEBUG_SHM
113 fprintf(stderr, "define: fill_b = %p,  last_b = %p\n", *he_fill_buffer, *last_buffer);
114 #endif
115
116   (*total_segments_read)++;
117   semrelease(sem_id,DEF_SEM,1);
118 }
119
120 void drop_buffer()
121 {
122   assert(free_buffers() < total_buffers);
123   assert(occupied_buffers() > 0);
124
125 #ifdef _DEBUG
126 #if 0
127   fprintf(stderr," stop  writing %p - %p ",
128                  *last_buffer, (char *)(*last_buffer) + ENTRY_SIZE -1);
129 #endif
130 #endif
131
132   if (*last_buffer == NULL)
133     *last_buffer = *he_fill_buffer;
134   else
135     *last_buffer = INC(*last_buffer);
136 #ifdef DEBUG_SHM
137 fprintf(stderr, "drop: fill_b = %p,  last_b = %p\n", *he_fill_buffer, *last_buffer);
138 #endif
139   (*total_segments_written)++;
140   semrelease(sem_id,FREE_SEM, 1);
141 }
142
143 void drop_all_buffers()
144 {
145   (*total_segments_written) = (*total_segments_read);
146   semrelease(sem_id,FREE_SEM, total_buffers);
147 }
148
149 static void occupy_buffer()
150 {
151   assert(occupied_buffers() <= total_buffers);
152
153   previous_read_buffer = *he_fill_buffer;
154
155   if (*he_fill_buffer == NULL) {
156     *he_fill_buffer = RB_BASE;
157   } else {
158     *he_fill_buffer = INC(*he_fill_buffer);
159   }
160 }
161
162 #if defined HAVE_FORK_AND_SHAREDMEM
163 myringbuff * get_next_buffer()
164 {
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);
169   }
170 #endif
171
172   /* wait for a new buffer to become available */
173   if (semrequest(sem_id,FREE_SEM) != 0) {
174     /* semaphore operation failed.
175        try again...
176        */
177     fprintf(stderr, "child reader sem request failed\n");
178     exit(SEMAPHORE_ERROR);
179   }
180 #if 0
181   fprintf(stderr,"start reading  %p - %p\n",
182                  *he_fill_buffer, (char *)(*fill_buffer) + ENTRY_SIZE -1);
183 #endif
184
185   occupy_buffer();
186
187 #ifdef DEBUG_SHM
188 fprintf(stderr, "next: fill_b = %p,  last_b = %p, @last = %p\n", *he_fill_buffer, *last_buffer, last_buffer);
189 #endif
190   return *he_fill_buffer;
191 }
192
193 myringbuff *get_oldest_buffer()
194 {
195   myringbuff *retval;
196
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);
201   }
202 #endif
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");
208   }
209
210   retval = *last_buffer;
211
212 #if 0
213   fprintf(stderr," begin writing %p - %p\n",
214                   retval, (char *)retval + ENTRY_SIZE -1);
215 #endif
216
217   return retval;
218 }
219 #else /* HAVE_FORK_AND_SHAREDMEM */
220 myringbuff * get_next_buffer()
221 {
222   occupy_buffer();
223   return *he_fill_buffer;
224 }
225
226 myringbuff * get_oldest_buffer()
227 {
228   return *he_fill_buffer;
229 }
230 #endif /* HAVE_FORK_AND_SHAREDMEM */
231