Adds a "magazine" allocator for chunks of fixed size
This adds a very minimal and fast allocator for chunks of memory of a predetermined size. This has some similarities to the glib slice allocator although notably it is not thread safe and instead of internally tracking multiple magazines for various sized allocations the api lets you explicitly allocate a single magazine for a single specific size and a pointer to the magazine is passed explicitly to the allocate and free functions. This allocator builds on the CoglMemoryStack allocator as an underlying heap allocator and just never rewinds the stack. This means the heap is effectively a grow only linked list of malloc()'d blocks of memory. A CoglMagazine tracks a singly linked list of chunks of a predetermined size and _cogl_magazine_chunk_alloc() simply unlinks and returns the head of the list. If the list is empty it falls back to allocating from the underlying stack. _cogl_magazine_chunk_free() links the chunk back into the singly linked list for re-use. The chunk size passed to _cogl_magazine_new() is automatically rounded to a multiple of 8 bytes to ensure that all stack allocations end up aligned to 8 bytes. This also ensures that when a chunk is freed then it will be large enough to store a pointer to the next free chunk as part of a singly linked list. Reviewed-by: Neil Roberts <neil@linux.intel.com> (cherry picked from commit 17799c2f109a008d6cf767f501b81aa9b32bbda8)
This commit is contained in:
parent
97d5406aef
commit
882ff5612b
@ -358,6 +358,8 @@ cogl_sources_c = \
|
||||
$(srcdir)/gl-prototypes/cogl-glsl-functions.h \
|
||||
$(srcdir)/cogl-memory-stack-private.h \
|
||||
$(srcdir)/cogl-memory-stack.c \
|
||||
$(srcdir)/cogl-magazine-private.h \
|
||||
$(srcdir)/cogl-magazine.c \
|
||||
$(NULL)
|
||||
|
||||
if USE_GLIB
|
||||
|
82
cogl/cogl-magazine-private.h
Normal file
82
cogl/cogl-magazine-private.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||
*
|
||||
* Copyright (C) 2011 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cogl/cogl.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __COGL_MAGAZINE_PRIVATE_H__
|
||||
#define __COGL_MAGAZINE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "cogl-memory-stack-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _CoglMagazineChunk CoglMagazineChunk;
|
||||
|
||||
struct _CoglMagazineChunk
|
||||
{
|
||||
CoglMagazineChunk *next;
|
||||
};
|
||||
|
||||
typedef struct _CoglMagazine
|
||||
{
|
||||
size_t chunk_size;
|
||||
|
||||
CoglMemoryStack *stack;
|
||||
CoglMagazineChunk *head;
|
||||
} CoglMagazine;
|
||||
|
||||
CoglMagazine *
|
||||
_cogl_magazine_new (size_t chunk_size, int initial_chunk_count);
|
||||
|
||||
static inline void *
|
||||
_cogl_magazine_chunk_alloc (CoglMagazine *magazine)
|
||||
{
|
||||
if (G_LIKELY (magazine->head))
|
||||
{
|
||||
CoglMagazineChunk *chunk = magazine->head;
|
||||
magazine->head = chunk->next;
|
||||
return chunk;
|
||||
}
|
||||
else
|
||||
return _cogl_memory_stack_alloc (magazine->stack, magazine->chunk_size);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_cogl_magazine_chunk_free (CoglMagazine *magazine, void *data)
|
||||
{
|
||||
CoglMagazineChunk *chunk = data;
|
||||
|
||||
chunk->next = magazine->head;
|
||||
magazine->head = chunk;
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_magazine_free (CoglMagazine *magazine);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_MAGAZINE_PRIVATE_H__ */
|
78
cogl/cogl-magazine.c
Normal file
78
cogl/cogl-magazine.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||
*
|
||||
* Copyright (C) 2012 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*
|
||||
* CoglMagazine provides a really light weight allocator for chunks
|
||||
* of memory with a pre-determined size.
|
||||
*
|
||||
* This allocator builds on CoglMemoryStack for making all initial
|
||||
* allocations but never frees memory back to the stack.
|
||||
*
|
||||
* Memory chunks that haven't been allocated yet are stored in a
|
||||
* singly linked, fifo, list.
|
||||
*
|
||||
* Allocating from a magazine is simply a question of popping an entry
|
||||
* from the head of the fifo list. If no entries are available then
|
||||
* instead allocate from the memory stack instead.
|
||||
*
|
||||
* When an entry is freed, it is put back into the fifo list for
|
||||
* re-use.
|
||||
*
|
||||
* No attempt is ever made to shrink the amount of memory associated
|
||||
* with a CoglMagazine.
|
||||
*
|
||||
*
|
||||
* Authors:
|
||||
* Robert Bragg <robert@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "cogl-memory-stack-private.h"
|
||||
#include "cogl-magazine-private.h"
|
||||
#include <glib.h>
|
||||
|
||||
#define ROUND_UP_8(X) ((X + (8 - 1)) & ~(8 - 1))
|
||||
|
||||
CoglMagazine *
|
||||
_cogl_magazine_new (size_t chunk_size, int initial_chunk_count)
|
||||
{
|
||||
CoglMagazine *magazine = g_new0 (CoglMagazine, 1);
|
||||
|
||||
chunk_size = MAX (chunk_size, sizeof (CoglMagazineChunk));
|
||||
chunk_size = ROUND_UP_8 (chunk_size);
|
||||
|
||||
magazine->chunk_size = chunk_size;
|
||||
magazine->stack = _cogl_memory_stack_new (chunk_size * initial_chunk_count);
|
||||
magazine->head = NULL;
|
||||
|
||||
return magazine;
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_magazine_free (CoglMagazine *magazine)
|
||||
{
|
||||
_cogl_memory_stack_free (magazine->stack);
|
||||
g_free (magazine);
|
||||
}
|
Loading…
Reference in New Issue
Block a user