SDL  2.0
SDL_dataqueue.c File Reference
#include "./SDL_internal.h"
#include "SDL.h"
#include "./SDL_dataqueue.h"
#include "SDL_assert.h"
+ Include dependency graph for SDL_dataqueue.c:

Go to the source code of this file.

Data Structures

struct  SDL_DataQueuePacket
 
struct  SDL_DataQueue
 

Functions

static void SDL_FreeDataQueueList (SDL_DataQueuePacket *packet)
 
SDL_DataQueueSDL_NewDataQueue (const size_t _packetlen, const size_t initialslack)
 
void SDL_FreeDataQueue (SDL_DataQueue *queue)
 
void SDL_ClearDataQueue (SDL_DataQueue *queue, const size_t slack)
 
static SDL_DataQueuePacketAllocateDataQueuePacket (SDL_DataQueue *queue)
 
int SDL_WriteToDataQueue (SDL_DataQueue *queue, const void *_data, const size_t _len)
 
size_t SDL_PeekIntoDataQueue (SDL_DataQueue *queue, void *_buf, const size_t _len)
 
size_t SDL_ReadFromDataQueue (SDL_DataQueue *queue, void *_buf, const size_t _len)
 
size_t SDL_CountDataQueue (SDL_DataQueue *queue)
 
voidSDL_ReserveSpaceInDataQueue (SDL_DataQueue *queue, const size_t len)
 

Function Documentation

◆ AllocateDataQueuePacket()

static SDL_DataQueuePacket* AllocateDataQueuePacket ( SDL_DataQueue queue)
static

Definition at line 141 of file SDL_dataqueue.c.

References SDL_DataQueuePacket::datalen, SDL_DataQueue::head, SDL_DataQueuePacket::next, NULL, SDL_DataQueue::packet_size, SDL_DataQueue::pool, SDL_DataQueue::queued_bytes, SDL_assert, SDL_malloc, SDL_DataQueuePacket::startpos, and SDL_DataQueue::tail.

Referenced by SDL_ReserveSpaceInDataQueue(), and SDL_WriteToDataQueue().

142 {
143  SDL_DataQueuePacket *packet;
144 
145  SDL_assert(queue != NULL);
146 
147  packet = queue->pool;
148  if (packet != NULL) {
149  /* we have one available in the pool. */
150  queue->pool = packet->next;
151  } else {
152  /* Have to allocate a new one! */
153  packet = (SDL_DataQueuePacket *) SDL_malloc(sizeof (SDL_DataQueuePacket) + queue->packet_size);
154  if (packet == NULL) {
155  return NULL;
156  }
157  }
158 
159  packet->datalen = 0;
160  packet->startpos = 0;
161  packet->next = NULL;
162 
163  SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0));
164  if (queue->tail == NULL) {
165  queue->head = packet;
166  } else {
167  queue->tail->next = packet;
168  }
169  queue->tail = packet;
170  return packet;
171 }
SDL_DataQueuePacket * head
Definition: SDL_dataqueue.c:37
size_t queued_bytes
Definition: SDL_dataqueue.c:41
SDL_DataQueuePacket * pool
Definition: SDL_dataqueue.c:39
struct SDL_DataQueuePacket * next
Definition: SDL_dataqueue.c:31
SDL_DataQueuePacket * tail
Definition: SDL_dataqueue.c:38
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define NULL
Definition: begin_code.h:164
#define SDL_malloc
size_t packet_size
Definition: SDL_dataqueue.c:40

◆ SDL_ClearDataQueue()

void SDL_ClearDataQueue ( SDL_DataQueue queue,
const size_t  slack 
)

Definition at line 98 of file SDL_dataqueue.c.

References SDL_DataQueue::head, i, SDL_DataQueuePacket::next, NULL, SDL_DataQueue::packet_size, SDL_DataQueue::pool, SDL_DataQueue::queued_bytes, SDL_FreeDataQueueList(), and SDL_DataQueue::tail.

Referenced by SDL_AudioStreamClear(), and SDL_ClearQueuedAudio().

99 {
100  const size_t packet_size = queue ? queue->packet_size : 1;
101  const size_t slackpackets = (slack + (packet_size-1)) / packet_size;
102  SDL_DataQueuePacket *packet;
103  SDL_DataQueuePacket *prev = NULL;
104  size_t i;
105 
106  if (!queue) {
107  return;
108  }
109 
110  packet = queue->head;
111 
112  /* merge the available pool and the current queue into one list. */
113  if (packet) {
114  queue->tail->next = queue->pool;
115  } else {
116  packet = queue->pool;
117  }
118 
119  /* Remove the queued packets from the device. */
120  queue->tail = NULL;
121  queue->head = NULL;
122  queue->queued_bytes = 0;
123  queue->pool = packet;
124 
125  /* Optionally keep some slack in the pool to reduce malloc pressure. */
126  for (i = 0; packet && (i < slackpackets); i++) {
127  prev = packet;
128  packet = packet->next;
129  }
130 
131  if (prev) {
132  prev->next = NULL;
133  } else {
134  queue->pool = NULL;
135  }
136 
137  SDL_FreeDataQueueList(packet); /* free extra packets */
138 }
SDL_DataQueuePacket * head
Definition: SDL_dataqueue.c:37
size_t queued_bytes
Definition: SDL_dataqueue.c:41
SDL_DataQueuePacket * pool
Definition: SDL_dataqueue.c:39
static void SDL_FreeDataQueueList(SDL_DataQueuePacket *packet)
Definition: SDL_dataqueue.c:45
struct SDL_DataQueuePacket * next
Definition: SDL_dataqueue.c:31
SDL_DataQueuePacket * tail
Definition: SDL_dataqueue.c:38
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:164
size_t packet_size
Definition: SDL_dataqueue.c:40

◆ SDL_CountDataQueue()

size_t SDL_CountDataQueue ( SDL_DataQueue queue)

Definition at line 294 of file SDL_dataqueue.c.

References SDL_DataQueue::queued_bytes.

Referenced by SDL_AudioStreamAvailable(), SDL_BufferQueueDrainCallback(), and SDL_GetQueuedAudioSize().

295 {
296  return queue ? queue->queued_bytes : 0;
297 }
size_t queued_bytes
Definition: SDL_dataqueue.c:41

◆ SDL_FreeDataQueue()

void SDL_FreeDataQueue ( SDL_DataQueue queue)

Definition at line 88 of file SDL_dataqueue.c.

References SDL_DataQueue::head, SDL_DataQueue::pool, SDL_free, and SDL_FreeDataQueueList().

Referenced by close_audio_device(), and SDL_FreeAudioStream().

89 {
90  if (queue) {
93  SDL_free(queue);
94  }
95 }
SDL_DataQueuePacket * head
Definition: SDL_dataqueue.c:37
SDL_DataQueuePacket * pool
Definition: SDL_dataqueue.c:39
static void SDL_FreeDataQueueList(SDL_DataQueuePacket *packet)
Definition: SDL_dataqueue.c:45
#define SDL_free

◆ SDL_FreeDataQueueList()

static void SDL_FreeDataQueueList ( SDL_DataQueuePacket packet)
static

Definition at line 45 of file SDL_dataqueue.c.

References SDL_DataQueuePacket::next, and SDL_free.

Referenced by SDL_ClearDataQueue(), SDL_FreeDataQueue(), and SDL_WriteToDataQueue().

46 {
47  while (packet) {
48  SDL_DataQueuePacket *next = packet->next;
49  SDL_free(packet);
50  packet = next;
51  }
52 }
struct SDL_DataQueuePacket * next
Definition: SDL_dataqueue.c:31
#define SDL_free

◆ SDL_NewDataQueue()

SDL_DataQueue* SDL_NewDataQueue ( const size_t  _packetlen,
const size_t  initialslack 
)

Definition at line 58 of file SDL_dataqueue.c.

References SDL_DataQueuePacket::datalen, i, SDL_DataQueuePacket::next, NULL, SDL_DataQueue::packet_size, SDL_DataQueue::pool, SDL_malloc, SDL_OutOfMemory, SDL_zerop, and SDL_DataQueuePacket::startpos.

Referenced by open_audio_device(), and SDL_NewAudioStream().

59 {
60  SDL_DataQueue *queue = (SDL_DataQueue *) SDL_malloc(sizeof (SDL_DataQueue));
61 
62  if (!queue) {
64  return NULL;
65  } else {
66  const size_t packetlen = _packetlen ? _packetlen : 1024;
67  const size_t wantpackets = (initialslack + (packetlen - 1)) / packetlen;
68  size_t i;
69 
70  SDL_zerop(queue);
71  queue->packet_size = packetlen;
72 
73  for (i = 0; i < wantpackets; i++) {
74  SDL_DataQueuePacket *packet = (SDL_DataQueuePacket *) SDL_malloc(sizeof (SDL_DataQueuePacket) + packetlen);
75  if (packet) { /* don't care if this fails, we'll deal later. */
76  packet->datalen = 0;
77  packet->startpos = 0;
78  packet->next = queue->pool;
79  queue->pool = packet;
80  }
81  }
82  }
83 
84  return queue;
85 }
SDL_DataQueuePacket * pool
Definition: SDL_dataqueue.c:39
#define SDL_zerop(x)
Definition: SDL_stdinc.h:417
struct SDL_DataQueuePacket * next
Definition: SDL_dataqueue.c:31
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_malloc
size_t packet_size
Definition: SDL_dataqueue.c:40

◆ SDL_PeekIntoDataQueue()

size_t SDL_PeekIntoDataQueue ( SDL_DataQueue queue,
void _buf,
const size_t  _len 
)

Definition at line 229 of file SDL_dataqueue.c.

References SDL_DataQueuePacket::data, SDL_DataQueuePacket::datalen, SDL_DataQueue::head, SDL_DataQueuePacket::next, SDL_DataQueue::queued_bytes, SDL_assert, SDL_memcpy, SDL_min, and SDL_DataQueuePacket::startpos.

230 {
231  size_t len = _len;
232  Uint8 *buf = (Uint8 *) _buf;
233  Uint8 *ptr = buf;
234  SDL_DataQueuePacket *packet;
235 
236  if (!queue) {
237  return 0;
238  }
239 
240  for (packet = queue->head; len && packet; packet = packet->next) {
241  const size_t avail = packet->datalen - packet->startpos;
242  const size_t cpy = SDL_min(len, avail);
243  SDL_assert(queue->queued_bytes >= avail);
244 
245  SDL_memcpy(ptr, packet->data + packet->startpos, cpy);
246  ptr += cpy;
247  len -= cpy;
248  }
249 
250  return (size_t) (ptr - buf);
251 }
SDL_DataQueuePacket * head
Definition: SDL_dataqueue.c:37
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
size_t queued_bytes
Definition: SDL_dataqueue.c:41
Uint8 data[SDL_VARIABLE_LENGTH_ARRAY]
Definition: SDL_dataqueue.c:32
GLenum GLsizei len
struct SDL_DataQueuePacket * next
Definition: SDL_dataqueue.c:31
#define SDL_memcpy
uint8_t Uint8
Definition: SDL_stdinc.h:157
GLenum GLuint GLenum GLsizei const GLchar * buf
#define SDL_assert(condition)
Definition: SDL_assert.h:169

◆ SDL_ReadFromDataQueue()

size_t SDL_ReadFromDataQueue ( SDL_DataQueue queue,
void _buf,
const size_t  _len 
)

Definition at line 254 of file SDL_dataqueue.c.

References SDL_DataQueuePacket::data, SDL_DataQueuePacket::datalen, SDL_DataQueue::head, SDL_DataQueuePacket::next, NULL, SDL_DataQueue::pool, SDL_DataQueue::queued_bytes, SDL_assert, SDL_memcpy, SDL_min, SDL_DataQueuePacket::startpos, and SDL_DataQueue::tail.

Referenced by SDL_AudioStreamGet(), SDL_BufferQueueDrainCallback(), and SDL_DequeueAudio().

255 {
256  size_t len = _len;
257  Uint8 *buf = (Uint8 *) _buf;
258  Uint8 *ptr = buf;
259  SDL_DataQueuePacket *packet;
260 
261  if (!queue) {
262  return 0;
263  }
264 
265  while ((len > 0) && ((packet = queue->head) != NULL)) {
266  const size_t avail = packet->datalen - packet->startpos;
267  const size_t cpy = SDL_min(len, avail);
268  SDL_assert(queue->queued_bytes >= avail);
269 
270  SDL_memcpy(ptr, packet->data + packet->startpos, cpy);
271  packet->startpos += cpy;
272  ptr += cpy;
273  queue->queued_bytes -= cpy;
274  len -= cpy;
275 
276  if (packet->startpos == packet->datalen) { /* packet is done, put it in the pool. */
277  queue->head = packet->next;
278  SDL_assert((packet->next != NULL) || (packet == queue->tail));
279  packet->next = queue->pool;
280  queue->pool = packet;
281  }
282  }
283 
284  SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0));
285 
286  if (queue->head == NULL) {
287  queue->tail = NULL; /* in case we drained the queue entirely. */
288  }
289 
290  return (size_t) (ptr - buf);
291 }
SDL_DataQueuePacket * head
Definition: SDL_dataqueue.c:37
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
size_t queued_bytes
Definition: SDL_dataqueue.c:41
SDL_DataQueuePacket * pool
Definition: SDL_dataqueue.c:39
Uint8 data[SDL_VARIABLE_LENGTH_ARRAY]
Definition: SDL_dataqueue.c:32
GLenum GLsizei len
struct SDL_DataQueuePacket * next
Definition: SDL_dataqueue.c:31
#define SDL_memcpy
uint8_t Uint8
Definition: SDL_stdinc.h:157
SDL_DataQueuePacket * tail
Definition: SDL_dataqueue.c:38
GLenum GLuint GLenum GLsizei const GLchar * buf
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define NULL
Definition: begin_code.h:164

◆ SDL_ReserveSpaceInDataQueue()

void* SDL_ReserveSpaceInDataQueue ( SDL_DataQueue queue,
const size_t  len 
)

Definition at line 300 of file SDL_dataqueue.c.

References AllocateDataQueuePacket(), SDL_DataQueuePacket::data, SDL_DataQueuePacket::datalen, SDL_DataQueue::head, NULL, SDL_DataQueue::packet_size, SDL_DataQueue::queued_bytes, retval, SDL_InvalidParamError, SDL_OutOfMemory, and SDL_SetError.

301 {
302  SDL_DataQueuePacket *packet;
303 
304  if (!queue) {
305  SDL_InvalidParamError("queue");
306  return NULL;
307  } else if (len == 0) {
308  SDL_InvalidParamError("len");
309  return NULL;
310  } else if (len > queue->packet_size) {
311  SDL_SetError("len is larger than packet size");
312  return NULL;
313  }
314 
315  packet = queue->head;
316  if (packet) {
317  const size_t avail = queue->packet_size - packet->datalen;
318  if (len <= avail) { /* we can use the space at end of this packet. */
319  void *retval = packet->data + packet->datalen;
320  packet->datalen += len;
321  queue->queued_bytes += len;
322  return retval;
323  }
324  }
325 
326  /* Need a fresh packet. */
327  packet = AllocateDataQueuePacket(queue);
328  if (!packet) {
329  SDL_OutOfMemory();
330  return NULL;
331  }
332 
333  packet->datalen = len;
334  queue->queued_bytes += len;
335  return packet->data;
336 }
SDL_DataQueuePacket * head
Definition: SDL_dataqueue.c:37
size_t queued_bytes
Definition: SDL_dataqueue.c:41
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
Uint8 data[SDL_VARIABLE_LENGTH_ARRAY]
Definition: SDL_dataqueue.c:32
GLenum GLsizei len
SDL_bool retval
static SDL_DataQueuePacket * AllocateDataQueuePacket(SDL_DataQueue *queue)
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_SetError
size_t packet_size
Definition: SDL_dataqueue.c:40

◆ SDL_WriteToDataQueue()

int SDL_WriteToDataQueue ( SDL_DataQueue queue,
const void _data,
const size_t  _len 
)

Definition at line 175 of file SDL_dataqueue.c.

References AllocateDataQueuePacket(), SDL_DataQueuePacket::data, SDL_DataQueuePacket::datalen, SDL_DataQueue::head, SDL_DataQueuePacket::next, NULL, SDL_DataQueue::packet_size, SDL_DataQueue::pool, SDL_DataQueue::queued_bytes, SDL_assert, SDL_FreeDataQueueList(), SDL_InvalidParamError, SDL_memcpy, SDL_min, SDL_OutOfMemory, and SDL_DataQueue::tail.

Referenced by SDL_AudioStreamPut(), SDL_AudioStreamPutInternal(), SDL_BufferQueueFillCallback(), and SDL_QueueAudio().

176 {
177  size_t len = _len;
178  const Uint8 *data = (const Uint8 *) _data;
179  const size_t packet_size = queue ? queue->packet_size : 0;
180  SDL_DataQueuePacket *orighead;
181  SDL_DataQueuePacket *origtail;
182  size_t origlen;
183  size_t datalen;
184 
185  if (!queue) {
186  return SDL_InvalidParamError("queue");
187  }
188 
189  orighead = queue->head;
190  origtail = queue->tail;
191  origlen = origtail ? origtail->datalen : 0;
192 
193  while (len > 0) {
194  SDL_DataQueuePacket *packet = queue->tail;
195  SDL_assert(!packet || (packet->datalen <= packet_size));
196  if (!packet || (packet->datalen >= packet_size)) {
197  /* tail packet missing or completely full; we need a new packet. */
198  packet = AllocateDataQueuePacket(queue);
199  if (!packet) {
200  /* uhoh, reset so we've queued nothing new, free what we can. */
201  if (!origtail) {
202  packet = queue->head; /* whole queue. */
203  } else {
204  packet = origtail->next; /* what we added to existing queue. */
205  origtail->next = NULL;
206  origtail->datalen = origlen;
207  }
208  queue->head = orighead;
209  queue->tail = origtail;
210  queue->pool = NULL;
211 
212  SDL_FreeDataQueueList(packet); /* give back what we can. */
213  return SDL_OutOfMemory();
214  }
215  }
216 
217  datalen = SDL_min(len, packet_size - packet->datalen);
218  SDL_memcpy(packet->data + packet->datalen, data, datalen);
219  data += datalen;
220  len -= datalen;
221  packet->datalen += datalen;
222  queue->queued_bytes += datalen;
223  }
224 
225  return 0;
226 }
SDL_DataQueuePacket * head
Definition: SDL_dataqueue.c:37
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
size_t queued_bytes
Definition: SDL_dataqueue.c:41
SDL_DataQueuePacket * pool
Definition: SDL_dataqueue.c:39
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
static void SDL_FreeDataQueueList(SDL_DataQueuePacket *packet)
Definition: SDL_dataqueue.c:45
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
Uint8 data[SDL_VARIABLE_LENGTH_ARRAY]
Definition: SDL_dataqueue.c:32
GLenum GLsizei len
struct SDL_DataQueuePacket * next
Definition: SDL_dataqueue.c:31
#define SDL_memcpy
uint8_t Uint8
Definition: SDL_stdinc.h:157
SDL_DataQueuePacket * tail
Definition: SDL_dataqueue.c:38
static SDL_DataQueuePacket * AllocateDataQueuePacket(SDL_DataQueue *queue)
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
size_t packet_size
Definition: SDL_dataqueue.c:40