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.

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}
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define SDL_malloc
#define NULL
Definition: begin_code.h:167
SDL_DataQueuePacket * pool
Definition: SDL_dataqueue.c:39
size_t queued_bytes
Definition: SDL_dataqueue.c:41
SDL_DataQueuePacket * tail
Definition: SDL_dataqueue.c:38
size_t packet_size
Definition: SDL_dataqueue.c:40
SDL_DataQueuePacket * head
Definition: SDL_dataqueue.c:37
struct SDL_DataQueuePacket * next
Definition: SDL_dataqueue.c:31

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().

◆ SDL_ClearDataQueue()

void SDL_ClearDataQueue ( SDL_DataQueue queue,
const size_t  slack 
)

Definition at line 98 of file SDL_dataqueue.c.

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;
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}
static void SDL_FreeDataQueueList(SDL_DataQueuePacket *packet)
Definition: SDL_dataqueue.c:45
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

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().

◆ SDL_CountDataQueue()

size_t SDL_CountDataQueue ( SDL_DataQueue queue)

Definition at line 294 of file SDL_dataqueue.c.

295{
296 return queue ? queue->queued_bytes : 0;
297}

References SDL_DataQueue::queued_bytes.

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

◆ SDL_FreeDataQueue()

void SDL_FreeDataQueue ( SDL_DataQueue queue)

Definition at line 88 of file SDL_dataqueue.c.

89{
90 if (queue) {
93 SDL_free(queue);
94 }
95}
#define SDL_free

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

Referenced by close_audio_device(), and SDL_FreeAudioStream().

◆ SDL_FreeDataQueueList()

static void SDL_FreeDataQueueList ( SDL_DataQueuePacket packet)
static

Definition at line 45 of file SDL_dataqueue.c.

46{
47 while (packet) {
48 SDL_DataQueuePacket *next = packet->next;
49 SDL_free(packet);
50 packet = next;
51 }
52}

References SDL_DataQueuePacket::next, and SDL_free.

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

◆ SDL_NewDataQueue()

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

Definition at line 58 of file SDL_dataqueue.c.

59{
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++) {
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}
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_zerop(x)
Definition: SDL_stdinc.h:417

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().

◆ SDL_PeekIntoDataQueue()

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

Definition at line 229 of file SDL_dataqueue.c.

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}
#define SDL_memcpy
GLenum GLsizei len
GLenum GLuint GLenum GLsizei const GLchar * buf
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
uint8_t Uint8
Definition: SDL_stdinc.h:179
Uint8 data[SDL_VARIABLE_LENGTH_ARRAY]
Definition: SDL_dataqueue.c:32

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.

◆ SDL_ReadFromDataQueue()

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

Definition at line 254 of file SDL_dataqueue.c.

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}

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().

◆ SDL_ReserveSpaceInDataQueue()

void * SDL_ReserveSpaceInDataQueue ( SDL_DataQueue queue,
const size_t  len 
)

Definition at line 300 of file SDL_dataqueue.c.

301{
302 SDL_DataQueuePacket *packet;
303
304 if (!queue) {
305 SDL_InvalidParamError("queue");
306 return NULL;
307 } else if (len == 0) {
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) {
330 return NULL;
331 }
332
333 packet->datalen = len;
334 queue->queued_bytes += len;
335 return packet->data;
336}
static SDL_DataQueuePacket * AllocateDataQueuePacket(SDL_DataQueue *queue)
#define SDL_SetError
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
SDL_bool retval

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.

◆ SDL_WriteToDataQueue()

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

Definition at line 175 of file SDL_dataqueue.c.

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}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974

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().