[cairo-commit] cairo/src cairo-cache.c, 1.12, 1.13 cairo-font.c, 1.50, 1.51 cairo-ft-font.c, 1.68, 1.69 cairo-xlib-surface.c, 1.83, 1.84 cairoint.h, 1.157, 1.158

Keith Packard commit at pdx.freedesktop.org
Sat Jun 25 23:24:21 PDT 2005


Committed by: keithp

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv16980/src

Modified Files:
	cairo-cache.c cairo-font.c cairo-ft-font.c 
	cairo-xlib-surface.c cairoint.h 
Log Message:
2005-06-25  Keith Packard  <keithp at keithp.com>

	reviewed by: cworth

	* configure.in:
	* src/cairo-cache.c: (_cairo_cache_shrink_to),
	(_cairo_cache_lookup):
	* src/cairo-font.c: (_lock_global_simple_cache),
	(_unlock_global_simple_cache), (_lock_global_font_cache),
	(_unlock_global_font_cache),
	(_cairo_lock_global_image_glyph_cache),
	(_cairo_unlock_global_image_glyph_cache),
	(_cairo_get_global_image_glyph_cache):
	* src/cairo-ft-font.c: (_lock_global_ft_cache),
	(_unlock_global_ft_cache):
	* src/cairo-xlib-surface.c: (_xlib_glyphset_cache_create_entry),
	(_xlib_glyphset_cache_destroy_entry), (_lock_xlib_glyphset_caches),
	(_unlock_xlib_glyphset_caches), (_get_glyphset_cache),
	(_cairo_xlib_surface_show_glyphs):
	* src/cairoint.h:
	Provide locking macros, implement with pthreads.
	
	Add _cairo_cache_shrink_to which reduces cache memory usage
	to a specified level.

	Change global glyph and xlib glyphset caches behaviour to only
	shrink cache on unlock.  This is done by telling the cache code to
	never shrink (max_memory == 0), and then manually shrinking using
	_cairo_cache_shrink_to from the unlock function.

	Fix Carl's variable renaming mixing (cache = cache).


Index: cairo-cache.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-cache.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- cairo-cache.c	3 Jun 2005 23:22:27 -0000	1.12
+++ cairo-cache.c	26 Jun 2005 06:24:19 -0000	1.13
@@ -383,6 +383,19 @@
     cache->backend->destroy_cache (cache);
 }
 
+void
+_cairo_cache_shrink_to (cairo_cache_t *cache,
+			unsigned long max_memory)
+{
+    unsigned long idx;
+    /* Make some entries die if we're under memory pressure. */
+    while (cache->live_entries > 0 && cache->used_memory > max_memory) {
+	idx =  _random_entry (cache, NULL) - cache->entries;
+	assert (idx < cache->arrangement->size);
+	_entry_destroy (cache, idx);
+    }
+}
+
 cairo_status_t
 _cairo_cache_lookup (cairo_cache_t *cache,
 		     void          *key,
@@ -390,7 +403,6 @@
 		     int           *created_entry)
 {
 
-    unsigned long idx;
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_cache_entry_base_t **slot = NULL, *new_entry;
 
@@ -440,14 +452,8 @@
     /* Store the hash value in case the backend forgot. */
     new_entry->hashcode = cache->backend->hash (cache, key);
 
-    /* Make some entries die if we're under memory pressure. */
-    while (cache->live_entries > 0 &&
-	   cache->max_memory > 0 &&
-	   ((cache->max_memory - cache->used_memory) < new_entry->memory)) {
-	idx =  _random_entry (cache, NULL) - cache->entries;
-	assert (idx < cache->arrangement->size);
-	_entry_destroy (cache, idx);
-    }
+    if (cache->live_entries && cache->max_memory)
+        _cairo_cache_shrink_to (cache, cache->max_memory);
     
     /* Can't assert this; new_entry->memory may be larger than max_memory */
     /* assert(cache->max_memory >= (cache->used_memory + new_entry->memory)); */

Index: cairo-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-font.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- cairo-font.c	10 Jun 2005 19:18:21 -0000	1.50
+++ cairo-font.c	26 Jun 2005 06:24:19 -0000	1.51
@@ -183,16 +183,18 @@
 
 static const cairo_cache_backend_t _cairo_simple_font_cache_backend;
 
+CAIRO_MUTEX_DECLARE(_global_simple_cache_mutex);
+
 static void
 _lock_global_simple_cache (void)
 {
-    /* FIXME: Perform locking here. */
+    CAIRO_MUTEX_LOCK (_global_simple_cache_mutex);
 }
 
 static void
 _unlock_global_simple_cache (void)
 {
-    /* FIXME: Perform locking here. */
+    CAIRO_MUTEX_UNLOCK (_global_simple_cache_mutex);
 }
 
 static cairo_cache_t *
@@ -451,16 +453,18 @@
 static const cairo_cache_backend_t _cairo_outer_font_cache_backend;
 static const cairo_cache_backend_t _cairo_inner_font_cache_backend;
 
+CAIRO_MUTEX_DECLARE(_global_font_cache_mutex);
+
 static void
 _lock_global_font_cache (void)
 {
-    /* FIXME: Perform locking here. */
+    CAIRO_MUTEX_LOCK (_global_font_cache_mutex);
 }
 
 static void
 _unlock_global_font_cache (void)
 {
-    /* FIXME: Perform locking here. */
+    CAIRO_MUTEX_UNLOCK (_global_font_cache_mutex);
 }
 
 static cairo_cache_t *
@@ -1177,21 +1181,25 @@
     _image_glyph_cache_destroy_cache
 };
 
+CAIRO_MUTEX_DECLARE(_global_image_glyph_cache_mutex);
+
+static cairo_cache_t *
+_global_image_glyph_cache = NULL;
+
 void
 _cairo_lock_global_image_glyph_cache()
 {
-    /* FIXME: implement locking. */
+    CAIRO_MUTEX_LOCK (_global_image_glyph_cache_mutex);
 }
 
 void
 _cairo_unlock_global_image_glyph_cache()
 {
-    /* FIXME: implement locking. */
+    _cairo_cache_shrink_to (_global_image_glyph_cache, 
+			    CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT);
+    CAIRO_MUTEX_UNLOCK (_global_image_glyph_cache_mutex);
 }
 
-static cairo_cache_t *
-_global_image_glyph_cache = NULL;
-
 cairo_cache_t *
 _cairo_get_global_image_glyph_cache ()
 {
@@ -1203,7 +1211,7 @@
 	
 	if (_cairo_cache_init (_global_image_glyph_cache,
 			       &cairo_image_cache_backend,
-			       CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT))
+			       0))
 	    goto FAIL;
     }
 

Index: cairo-ft-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ft-font.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -d -r1.68 -r1.69
--- cairo-ft-font.c	25 Jun 2005 20:51:22 -0000	1.68
+++ cairo-ft-font.c	26 Jun 2005 06:24:19 -0000	1.69
@@ -274,16 +274,18 @@
 
 static ft_cache_t *_global_ft_cache = NULL;
 
+CAIRO_MUTEX_DECLARE(_global_ft_cache_mutex);
+
 static void
 _lock_global_ft_cache (void)
 {
-    /* FIXME: Perform locking here. */
+    CAIRO_MUTEX_LOCK(_global_ft_cache_mutex);
 }
 
 static void
 _unlock_global_ft_cache (void)
 {
-    /* FIXME: Perform locking here. */
+    CAIRO_MUTEX_UNLOCK(_global_ft_cache_mutex);
 }
 
 static cairo_cache_t *

Index: cairo-xlib-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib-surface.c,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -d -r1.83 -r1.84
--- cairo-xlib-surface.c	24 Jun 2005 22:09:42 -0000	1.83
+++ cairo-xlib-surface.c	26 Jun 2005 06:24:19 -0000	1.84
@@ -1510,7 +1510,6 @@
 typedef struct {
     cairo_glyph_cache_key_t key;
     Glyph glyph;
-    int refcount;
 } glyphset_cache_entry_t;
 
 static Glyph
@@ -1549,7 +1548,6 @@
 	return CAIRO_STATUS_NO_MEMORY;
     }
 
-    entry->refcount = 1;
     entry->key = *key;
     _cairo_unscaled_font_reference (entry->key.unscaled);
 
@@ -1610,12 +1608,6 @@
     return CAIRO_STATUS_SUCCESS;
 }
 
-static void
-_glyphset_cache_entry_reference (glyphset_cache_entry_t *entry)
-{
-    entry->refcount++;
-}
-
 static void 
 _xlib_glyphset_cache_destroy_cache (void *cache)
 {
@@ -1626,12 +1618,9 @@
 _xlib_glyphset_cache_destroy_entry (void *abstract_cache,
 				    void *abstract_entry)
 {
-    glyphset_cache_t *cache = cache;
+    glyphset_cache_t *cache = abstract_cache;
     glyphset_cache_entry_t *entry = abstract_entry;
 
-    if (--entry->refcount > 0)
-	return;
-
     _cairo_unscaled_font_destroy (entry->key.unscaled);
     XRenderFreeGlyphs (cache->display, cache->glyphset, &(entry->glyph), 1);
     free (entry);	
@@ -1645,6 +1634,7 @@
     _xlib_glyphset_cache_destroy_cache
 };
 
+CAIRO_MUTEX_DECLARE(_xlib_glyphset_caches_mutex);
 
 static glyphset_cache_t *
 _xlib_glyphset_caches = NULL;
@@ -1652,13 +1642,15 @@
 static void
 _lock_xlib_glyphset_caches (void)
 {
-    /* FIXME: implement locking */
+    CAIRO_MUTEX_LOCK(_xlib_glyphset_caches_mutex);
 }
 
 static void
-_unlock_xlib_glyphset_caches (void)
+_unlock_xlib_glyphset_caches (glyphset_cache_t *cache)
 {
-    /* FIXME: implement locking */
+    _cairo_cache_shrink_to (&cache->base,
+			    CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT);
+    CAIRO_MUTEX_UNLOCK(_xlib_glyphset_caches_mutex);
 }
 
 static glyphset_cache_t *
@@ -1680,20 +1672,19 @@
     if (cache == NULL) 
 	goto ERR;
 
-    cache->counter = 0;
-    cache->display = d;
-    cache->a8_pict_format = XRenderFindStandardFormat (d, PictStandardA8);
-    if (cache->a8_pict_format == NULL)
-	goto ERR;
-    
     if (_cairo_cache_init (&cache->base,
-			   &_xlib_glyphset_cache_backend,
-			   CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT))
+			   &_xlib_glyphset_cache_backend, 0))
 	goto FREE_GLYPHSET_CACHE;
-    
+
+    cache->display = d;
+    cache->counter = 0;
+
+    cache->a8_pict_format = XRenderFindStandardFormat (d, PictStandardA8);
     cache->glyphset = XRenderCreateGlyphSet (d, cache->a8_pict_format);
+    
     cache->next = _xlib_glyphset_caches;
     _xlib_glyphset_caches = cache;
+
     return cache;
     
  FREE_GLYPHSET_CACHE:
@@ -2010,15 +2001,6 @@
 	if (status != CAIRO_STATUS_SUCCESS || entries[i] == NULL) 
 	    goto UNLOCK;
 
-	/* Referencing the glyph entries we use prevents them from
-	 * being freed if lookup of later entries causes them to
-	 * be ejected from the cache. It would be more efficient
-	 * (though more complex) to prevent them from being ejected
-	 * from the cache at all, so they could get reused later
-	 * in the same string.
-	 */
-	_glyphset_cache_entry_reference (entries[i]);
-
 	if (elt_size == 8 && entries[i]->glyph > 0xff)
 	    elt_size = 16;
 	if (elt_size == 16 && entries[i]->glyph > 0xffff) {
@@ -2052,11 +2034,8 @@
 						    glyphs, entries, num_glyphs);
     }
 
-    for (i = 0; i < num_glyphs; ++i)
-	_xlib_glyphset_cache_destroy_entry (cache, entries[i]);
-
  UNLOCK:
-    _unlock_xlib_glyphset_caches ();
+    _unlock_xlib_glyphset_caches (cache);
 
     if (num_glyphs >= N_STACK_BUF)
 	free (entries); 

Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.157
retrieving revision 1.158
diff -u -d -r1.157 -r1.158
--- cairoint.h	20 Jun 2005 18:09:51 -0000	1.157
+++ cairoint.h	26 Jun 2005 06:24:19 -0000	1.158
@@ -55,6 +55,10 @@
 #include <string.h>
 #include <stdarg.h>
 
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
 #ifdef _MSC_VER
 #define _USE_MATH_DEFINES
 #endif
@@ -116,6 +120,21 @@
 #define __attribute__(x)
 #endif
 
+#if HAVE_PTHREAD_H
+#define CAIRO_MUTEX_DECLARE(name) static pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
+#define CAIRO_MUTEX_DECLARE_GLOBAL(name) pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
+#define CAIRO_MUTEX_LOCK(name) pthread_mutex_lock (&name)
+#define CAIRO_MUTEX_UNLOCK(name) pthread_mutex_unlock (&name)
+#endif
+
+#ifndef CAIRO_MUTEX_DECLARE
+#warning "No mutex declarations, assuming single-threaded code"
+#define CAIRO_MUTEX_DECLARE(name)
+#define CAIRO_MUTEX_DECLARE_GLOBAL(name)
+#define CAIRO_MUTEX_LOCK(name)
+#define CAIRO_MUTEX_UNLOCK(name)
+#endif
+
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 
@@ -382,6 +401,10 @@
 cairo_private void
 _cairo_cache_destroy (cairo_cache_t *cache);
 
+cairo_private void
+_cairo_cache_shrink_to (cairo_cache_t *cache,
+			unsigned long max_memory);
+
 cairo_private cairo_status_t
 _cairo_cache_lookup (cairo_cache_t *cache,
 		     void          *key,




More information about the cairo-commit mailing list