Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2006 Joonas Pihlaja
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and its
  5.  * documentation for any purpose is hereby granted without fee, provided that
  6.  * the above copyright notice appear in all copies and that both that copyright
  7.  * notice and this permission notice appear in supporting documentation, and
  8.  * that the name of the copyright holders not be used in advertising or
  9.  * publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  The copyright holders make no representations
  11.  * about the suitability of this software for any purpose.  It is provided "as
  12.  * is" without express or implied warranty.
  13.  *
  14.  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16.  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  20.  * OF THIS SOFTWARE.
  21.  */
  22. #ifndef CAIRO_FREELIST_H
  23. #define CAIRO_FREELIST_H
  24.  
  25. #include "cairo-types-private.h"
  26. #include "cairo-compiler-private.h"
  27. #include "cairo-freelist-type-private.h"
  28.  
  29. /* for stand-alone compilation*/
  30. #ifndef VG
  31. #define VG(x)
  32. #endif
  33.  
  34. #ifndef NULL
  35. #define NULL (void *) 0
  36. #endif
  37.  
  38. /* Initialise a freelist that will be responsible for allocating
  39.  * nodes of size nodesize. */
  40. cairo_private void
  41. _cairo_freelist_init (cairo_freelist_t *freelist, unsigned nodesize);
  42.  
  43. /* Deallocate any nodes in the freelist. */
  44. cairo_private void
  45. _cairo_freelist_fini (cairo_freelist_t *freelist);
  46.  
  47. /* Allocate a new node from the freelist.  If the freelist contains no
  48.  * nodes, a new one will be allocated using malloc().  The caller is
  49.  * responsible for calling _cairo_freelist_free() or free() on the
  50.  * returned node.  Returns %NULL on memory allocation error. */
  51. cairo_private void *
  52. _cairo_freelist_alloc (cairo_freelist_t *freelist);
  53.  
  54. /* Allocate a new node from the freelist.  If the freelist contains no
  55.  * nodes, a new one will be allocated using calloc().  The caller is
  56.  * responsible for calling _cairo_freelist_free() or free() on the
  57.  * returned node.  Returns %NULL on memory allocation error. */
  58. cairo_private void *
  59. _cairo_freelist_calloc (cairo_freelist_t *freelist);
  60.  
  61. /* Return a node to the freelist. This does not deallocate the memory,
  62.  * but makes it available for later reuse by
  63.  * _cairo_freelist_alloc(). */
  64. cairo_private void
  65. _cairo_freelist_free (cairo_freelist_t *freelist, void *node);
  66.  
  67.  
  68. cairo_private void
  69. _cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize);
  70.  
  71. cairo_private void
  72. _cairo_freepool_fini (cairo_freepool_t *freepool);
  73.  
  74. static inline void
  75. _cairo_freepool_reset (cairo_freepool_t *freepool)
  76. {
  77.     while (freepool->pools != &freepool->embedded_pool) {
  78.         cairo_freelist_pool_t *pool = freepool->pools;
  79.         freepool->pools = pool->next;
  80.         pool->next = freepool->freepools;
  81.         freepool->freepools = pool;
  82.     }
  83.  
  84.     freepool->embedded_pool.rem = sizeof (freepool->embedded_data);
  85.     freepool->embedded_pool.data = freepool->embedded_data;
  86. }
  87.  
  88. cairo_private void *
  89. _cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool);
  90.  
  91. static inline void *
  92. _cairo_freepool_alloc_from_pool (cairo_freepool_t *freepool)
  93. {
  94.     cairo_freelist_pool_t *pool;
  95.     uint8_t *ptr;
  96.  
  97.     pool = freepool->pools;
  98.     if (unlikely (freepool->nodesize > pool->rem))
  99.         return _cairo_freepool_alloc_from_new_pool (freepool);
  100.  
  101.     ptr = pool->data;
  102.     pool->data += freepool->nodesize;
  103.     pool->rem -= freepool->nodesize;
  104.     VG (VALGRIND_MAKE_MEM_UNDEFINED (ptr, freepool->nodesize));
  105.     return ptr;
  106. }
  107.  
  108. static inline void *
  109. _cairo_freepool_alloc (cairo_freepool_t *freepool)
  110. {
  111.     cairo_freelist_node_t *node;
  112.  
  113.     node = freepool->first_free_node;
  114.     if (node == NULL)
  115.         return _cairo_freepool_alloc_from_pool (freepool);
  116.  
  117.     VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next)));
  118.     freepool->first_free_node = node->next;
  119.     VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freepool->nodesize));
  120.  
  121.     return node;
  122. }
  123.  
  124. cairo_private cairo_status_t
  125. _cairo_freepool_alloc_array (cairo_freepool_t *freepool,
  126.                              int count,
  127.                              void **array);
  128.  
  129. static inline void
  130. _cairo_freepool_free (cairo_freepool_t *freepool, void *ptr)
  131. {
  132.     cairo_freelist_node_t *node = ptr;
  133.  
  134.     node->next = freepool->first_free_node;
  135.     freepool->first_free_node = node;
  136.     VG (VALGRIND_MAKE_MEM_NOACCESS (node, freepool->nodesize));
  137. }
  138.  
  139. #endif /* CAIRO_FREELIST_H */
  140.