mirror of
				https://github.com/Ryujinx/SDL.git
				synced 2025-11-04 14:14:49 +00:00 
			
		
		
		
	Added SDL_ReserveSpaceInDataQueue() to make space without copying data.
This commit is contained in:
		
							parent
							
								
									18d9b23c65
								
							
						
					
					
						commit
						2e2572a4f1
					
				| 
						 | 
				
			
			@ -137,6 +137,40 @@ SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack)
 | 
			
		|||
    SDL_FreeDataQueueList(packet);  /* free extra packets */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SDL_DataQueuePacket *
 | 
			
		||||
AllocateDataQueuePacket(SDL_DataQueue *queue)
 | 
			
		||||
{
 | 
			
		||||
    SDL_DataQueuePacket *packet;
 | 
			
		||||
 | 
			
		||||
    SDL_assert(queue != NULL);
 | 
			
		||||
 | 
			
		||||
    packet = queue->pool;
 | 
			
		||||
    if (packet != NULL) {
 | 
			
		||||
        /* we have one available in the pool. */
 | 
			
		||||
        queue->pool = packet->next;
 | 
			
		||||
    } else {
 | 
			
		||||
        /* Have to allocate a new one! */
 | 
			
		||||
        packet = (SDL_DataQueuePacket *) SDL_malloc(sizeof (SDL_DataQueuePacket) + queue->packet_size);
 | 
			
		||||
        if (packet == NULL) {
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    packet->datalen = 0;
 | 
			
		||||
    packet->startpos = 0;
 | 
			
		||||
    packet->next = NULL;
 | 
			
		||||
                
 | 
			
		||||
    SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0));
 | 
			
		||||
    if (queue->tail == NULL) {
 | 
			
		||||
        queue->head = packet;
 | 
			
		||||
    } else {
 | 
			
		||||
        queue->tail->next = packet;
 | 
			
		||||
    }
 | 
			
		||||
    queue->tail = packet;
 | 
			
		||||
    return packet;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -161,42 +195,23 @@ SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len)
 | 
			
		|||
        SDL_assert(!packet || (packet->datalen <= packet_size));
 | 
			
		||||
        if (!packet || (packet->datalen >= packet_size)) {
 | 
			
		||||
            /* tail packet missing or completely full; we need a new packet. */
 | 
			
		||||
            packet = queue->pool;
 | 
			
		||||
            if (packet != NULL) {
 | 
			
		||||
                /* we have one available in the pool. */
 | 
			
		||||
                queue->pool = packet->next;
 | 
			
		||||
            } else {
 | 
			
		||||
                /* Have to allocate a new one! */
 | 
			
		||||
                packet = (SDL_DataQueuePacket *) SDL_malloc(sizeof (SDL_DataQueuePacket) + packet_size);
 | 
			
		||||
                if (packet == NULL) {
 | 
			
		||||
                    /* uhoh, reset so we've queued nothing new, free what we can. */
 | 
			
		||||
                    if (!origtail) {
 | 
			
		||||
                        packet = queue->head;  /* whole queue. */
 | 
			
		||||
                    } else {
 | 
			
		||||
                        packet = origtail->next;  /* what we added to existing queue. */
 | 
			
		||||
                        origtail->next = NULL;
 | 
			
		||||
                        origtail->datalen = origlen;
 | 
			
		||||
                    }
 | 
			
		||||
                    queue->head = orighead;
 | 
			
		||||
                    queue->tail = origtail;
 | 
			
		||||
                    queue->pool = NULL;
 | 
			
		||||
 | 
			
		||||
                    SDL_FreeDataQueueList(packet);  /* give back what we can. */
 | 
			
		||||
 | 
			
		||||
                    return SDL_OutOfMemory();
 | 
			
		||||
            packet = AllocateDataQueuePacket(queue);
 | 
			
		||||
            if (!packet) {
 | 
			
		||||
                /* uhoh, reset so we've queued nothing new, free what we can. */
 | 
			
		||||
                if (!origtail) {
 | 
			
		||||
                    packet = queue->head;  /* whole queue. */
 | 
			
		||||
                } else {
 | 
			
		||||
                    packet = origtail->next;  /* what we added to existing queue. */
 | 
			
		||||
                    origtail->next = NULL;
 | 
			
		||||
                    origtail->datalen = origlen;
 | 
			
		||||
                }
 | 
			
		||||
                queue->head = orighead;
 | 
			
		||||
                queue->tail = origtail;
 | 
			
		||||
                queue->pool = NULL;
 | 
			
		||||
 | 
			
		||||
                SDL_FreeDataQueueList(packet);  /* give back what we can. */
 | 
			
		||||
                return SDL_OutOfMemory();
 | 
			
		||||
            }
 | 
			
		||||
            packet->datalen = 0;
 | 
			
		||||
            packet->startpos = 0;
 | 
			
		||||
            packet->next = NULL;
 | 
			
		||||
                
 | 
			
		||||
            SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0));
 | 
			
		||||
            if (queue->tail == NULL) {
 | 
			
		||||
                queue->head = packet;
 | 
			
		||||
            } else {
 | 
			
		||||
                queue->tail->next = packet;
 | 
			
		||||
            }
 | 
			
		||||
            queue->tail = packet;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        datalen = SDL_min(len, packet_size - packet->datalen);
 | 
			
		||||
| 
						 | 
				
			
			@ -256,5 +271,44 @@ SDL_CountDataQueue(SDL_DataQueue *queue)
 | 
			
		|||
    return queue ? queue->queued_bytes : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *
 | 
			
		||||
SDL_ReserveSpaceInDataQueue(SDL_DataQueue *queue, const size_t len)
 | 
			
		||||
{
 | 
			
		||||
    SDL_DataQueuePacket *packet;
 | 
			
		||||
 | 
			
		||||
    if (!queue) {
 | 
			
		||||
        SDL_InvalidParamError("queue");
 | 
			
		||||
        return NULL;
 | 
			
		||||
    } else if (len == 0) {
 | 
			
		||||
        SDL_InvalidParamError("len");
 | 
			
		||||
        return NULL;
 | 
			
		||||
    } else if (len > queue->packet_size) {
 | 
			
		||||
        SDL_SetError("len is larger than packet size");
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    packet = queue->head;
 | 
			
		||||
    if (packet) {
 | 
			
		||||
        const size_t avail = queue->packet_size - packet->datalen;
 | 
			
		||||
        if (len <= avail) {  /* we can use the space at end of this packet. */
 | 
			
		||||
            void *retval = packet->data + packet->datalen;
 | 
			
		||||
            packet->datalen += len;
 | 
			
		||||
            queue->queued_bytes += len;
 | 
			
		||||
            return retval;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Need a fresh packet. */
 | 
			
		||||
    packet = AllocateDataQueuePacket(queue);
 | 
			
		||||
    if (!packet) {
 | 
			
		||||
        SDL_OutOfMemory();
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    packet->datalen = len;
 | 
			
		||||
    queue->queued_bytes += len;
 | 
			
		||||
    return packet->data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* vi: set ts=4 sw=4 expandtab: */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,21 @@ int SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *data, const size_t le
 | 
			
		|||
size_t SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *buf, const size_t len);
 | 
			
		||||
size_t SDL_CountDataQueue(SDL_DataQueue *queue);
 | 
			
		||||
 | 
			
		||||
/* this sets a section of the data queue aside (possibly allocating memory for it)
 | 
			
		||||
   as if it's been written to, but returns a pointer to that space. You may write
 | 
			
		||||
   to this space until a read would consume it. Writes (and other calls to this
 | 
			
		||||
   function) will safely append their data after this reserved space and can
 | 
			
		||||
   be in flight at the same time. There is no thread safety.
 | 
			
		||||
   If there isn't an existing block of memory that can contain the reserved
 | 
			
		||||
   space, one will be allocated for it. You can not (currently) allocate
 | 
			
		||||
   a space larger than the packetlen requested in SDL_NewDataQueue.
 | 
			
		||||
   Returned buffer is uninitialized.
 | 
			
		||||
   This lets you avoid an extra copy in some cases, but it's safer to use
 | 
			
		||||
   SDL_WriteToDataQueue() unless you know what you're doing.
 | 
			
		||||
   Returns pointer to buffer of at least (len) bytes, NULL on error.
 | 
			
		||||
*/
 | 
			
		||||
void *SDL_ReserveSpaceInDataQueue(SDL_DataQueue *queue, const size_t len);
 | 
			
		||||
 | 
			
		||||
#endif /* SDL_dataqueue_h_ */
 | 
			
		||||
 | 
			
		||||
/* vi: set ts=4 sw=4 expandtab: */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue