Watt-32 tcp/ip  2.2 dev-rel.10
pcqueue.c
Go to the documentation of this file.
1 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stddef.h>
38 
39 #include "wattcp.h"
40 #include "strings.h"
41 #include "misc.h"
42 #include "x32vm.h"
43 #include "powerpak.h"
44 #include "pcpkt.h"
45 #include "pcqueue.h"
46 
47 #if defined(USE_DEBUG)
48 int pktq_check (struct pkt_ringbuf *q)
49 {
50  int i;
51  char *buf;
52 
53  if (!q || !q->num_buf || !q->buf_start)
54  return (0);
55 
56  buf = (char*) q->buf_start;
57 
58  for (i = 0; i < q->num_buf; i++)
59  {
60  buf += q->buf_size;
61  if (*(DWORD*)(buf - sizeof(DWORD)) != PKTQ_MARKER)
62  return (0);
63  }
64  return (1);
65 }
66 #endif /* USE_DEBUG */
67 
68 
69 int pktq_init (struct pkt_ringbuf *q, int size, int num, char *buf)
70 {
71  q->buf_size = size;
72  q->num_buf = num;
73  q->buf_start = (DWORD_PTR) buf;
74  q->in_index = 0;
75  q->out_index = 0;
76 #if (DOSX & DOS4GW)
77  q->dos_ofs = 0; /* must be set manually */
78 #endif
79 
80 #if defined(USE_DEBUG)
81  WATT_ASSERT (size > 0);
82  WATT_ASSERT (num > 0);
83  WATT_ASSERT (buf != NULL);
84  {
85  int i;
86  for (i = 0; i < q->num_buf; i++)
87  {
88  buf += q->buf_size;
89  *(DWORD*) (buf - sizeof(DWORD)) = PKTQ_MARKER;
90  }
91  }
92 #endif
93  return (1);
94 }
95 
96 /*
97  * Increment the queue 'in_index' (head).
98  * Check for wraps.
99  */
100 int pktq_inc_in (struct pkt_ringbuf *q)
101 {
102  q->in_index++;
103  if (q->in_index >= q->num_buf)
104  q->in_index = 0;
105  return (q->in_index);
106 }
107 
108 /*
109  * Increment the queue 'out_index' (tail).
110  * Check for wraps.
111  */
112 int pktq_inc_out (struct pkt_ringbuf *q)
113 {
114  q->out_index++;
115  if (q->out_index >= q->num_buf)
116  q->out_index = 0;
117  return (q->out_index);
118 }
119 
120 /*
121  * Return the queue's next 'in_index' (head).
122  * Check for wraps. Caller is responsible for using cli/sti
123  * around this function when needed.
124  */
125 int pktq_in_index (struct pkt_ringbuf *q)
126 {
127  int index = q->in_index + 1;
128 
129  if (index >= q->num_buf)
130  index = 0;
131  return (index);
132 }
133 
134 /*
135  * Return the queue's head-buffer.
136  * Should be interruptable because 'in_index' is 'volatile'.
137  */
138 char *pktq_in_buf (struct pkt_ringbuf *q)
139 {
140  return ((char*)q->buf_start + (q->buf_size * q->in_index));
141 }
142 
143 /*
144  * Return the queue's tail-buffer.
145  */
146 char *pktq_out_buf (struct pkt_ringbuf *q)
147 {
148  return ((char*)q->buf_start + (q->buf_size * q->out_index));
149 }
150 
151 
152 /*
153  * Clear the queue ring-buffer by setting head = tail.
154  */
155 void pktq_clear (struct pkt_ringbuf *q)
156 {
157 #if defined(USE_FAST_PKT) && defined(__MSDOS__)
158  WORD out_ofs;
159 
160  DISABLE();
161  out_ofs = FAR_PEEK_WORD (struct pkt_info, pkt_queue.out_index);
162  FAR_POKE_WORD (struct pkt_info, pkt_queue.in_index, out_ofs);
163  ENABLE();
164  ARGSUSED (q);
165 #else
166  DISABLE();
167  q->in_index = q->out_index;
168  ENABLE();
169 #endif
170 }
171 
172 /*
173  * Return number of buffers waiting in queue. Check for wraps.
174  * Should be interruptable because 'in_index' is 'volatile'.
175  */
176 int pktq_queued (struct pkt_ringbuf *q)
177 {
178  register int index = q->out_index;
179  register int num = 0;
180 
181  DISABLE();
182 
183  while (index != q->in_index)
184  {
185  num++;
186  if (++index >= q->num_buf)
187  index = 0;
188  }
189  ENABLE();
190  return (num);
191 }
192 
193 
194 #if defined(USE_FAST_PKT) && defined(__MSDOS__)
195 
196 #if (DOSX == 0)
197 #error USE_FAST_PKT is not for real-mode targets.
198 #endif
199 
200 DWORD asmpkt_rm_base;
201 
202 #if defined(USE_DEBUG)
203 int pktq_far_check (struct pkt_ringbuf *q)
204 {
205  DWORD buf_start, buf, marker;
206  int i, size;
207 
208  i = FAR_PEEK_WORD (struct pkt_info, pkt_queue.num_buf);
209  if (i != q->num_buf)
210  {
211  (*_printf) ("pktq_far_check(): num = %d\n", i);
212  pkt_dump_real_mem();
213  return (0);
214  }
215 
216  buf = FAR_PEEK_DWORD (struct pkt_info, pkt_queue.buf_start);
217  size = FAR_PEEK_WORD (struct pkt_info, pkt_queue.buf_size);
218  buf_start = buf;
219 
220  for (i = 0; i < q->num_buf; i++)
221  {
222  buf += size;
223 
224  if (buf < asmpkt_rm_base || buf > asmpkt_rm_base + 64*1024)
225  {
226  (*_printf) ("pktq_far_check(): illegal buf = %08lX, size %d\n",
227  buf, size);
228  pkt_dump_real_mem();
229  return (0);
230  }
231  marker = PEEKL (0, buf - sizeof(DWORD));
232  if (marker != PKTQ_MARKER)
233  {
234  (*_printf) ("pktq_far_check(): size = %d, buf_start = %08lX, "
235  "marker[%d] = %08lX\n", size, buf_start, i, marker);
236  pkt_dump_real_mem();
237  return (0);
238  }
239  }
240  return (1);
241 }
242 #endif /* USE_DEBUG */
243 
244 
245 int pktq_far_init (int size, int num, DWORD real_base)
246 {
247  struct pkt_ringbuf q;
248  DWORD dos_addr;
249  size_t rx_buf_ofs = sizeof(struct pkt_info); /* rx_buf[] after _pkt_inf */
250  int i;
251 
252  memset (&q, 0, sizeof(q));
253  q.buf_size = size;
254  q.buf_start = real_base + rx_buf_ofs;
255  q.num_buf = num;
256  q.dos_ofs = rx_buf_ofs;
257  asmpkt_rm_base = real_base;
258 
259  WATT_ASSERT (size > 0);
260  WATT_ASSERT (num > 0);
261 
262  for (i = 0; i < q.num_buf; i++)
263  {
264  real_base += q.buf_size;
265  POKEL (0, q.dos_ofs + real_base - sizeof(DWORD), PKTQ_MARKER);
266  }
267 
268  dos_addr = asmpkt_rm_base + offsetof(struct pkt_info,pkt_queue);
269 
270 #if (DOSX & (PHARLAP|X32VM|POWERPAK))
271  WriteRealMem (dos_addr, &q, sizeof(q));
272 #elif (DOSX & DOS4GW)
273  memcpy ((void*)dos_addr, &q, sizeof(q));
274 #elif (DOSX & DJGPP)
275  dosmemput (&q, sizeof(q), dos_addr);
276 #else
277  #error Help!
278 #endif
279  return (1);
280 }
281 #endif /* USE_FAST_PKT && __MSDOS__ */
Core definitions.
Placeholder for vital data accessed by capture thread.
Definition: pcpkt.h:206