[Spice-devel] [PATCH 6/7] qxl: move garbage collector + alloc into qxl_mem.c

airlied at gmail.com airlied at gmail.com
Sun Feb 24 21:31:14 PST 2013


From: Dave Airlie <airlied at gmail.com>

This moves a lot more code out of the qxl_driver.c file.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/qxl_driver.c | 178 -----------------------------------------------------
 src/qxl_mem.c    | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 182 insertions(+), 178 deletions(-)

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index ebc51e9..eac0faf 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -149,184 +149,6 @@ qxl_allocate_monitors_config (qxl_screen_t *qxl)
 	((unsigned long)qxl->ram + qxl->rom->ram_header_offset - qxl->monitors_config_size);
 }
 
-static uint64_t
-qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
-{
-    /* We assume that there the two low bits of a pointer are
-     * available. If the low one is set, then the command in
-     * question is a cursor command
-     */
-#define POINTER_MASK ((1 << 2) - 1)
-	    
-    union QXLReleaseInfo *info = u64_to_pointer (id & ~POINTER_MASK);
-    struct QXLCursorCmd *cmd = (struct QXLCursorCmd *)info;
-    struct QXLDrawable *drawable = (struct QXLDrawable *)info;
-    struct QXLSurfaceCmd *surface_cmd = (struct QXLSurfaceCmd *)info;
-    int is_cursor = FALSE;
-    int is_surface = FALSE;
-    int is_drawable = FALSE;
-    
-    if ((id & POINTER_MASK) == 1)
-	is_cursor = TRUE;
-    else if ((id & POINTER_MASK) == 2)
-	is_surface = TRUE;
-    else
-	is_drawable = TRUE;
-    
-    if (is_cursor && cmd->type == QXL_CURSOR_SET)
-    {
-	struct QXLCursor *cursor = (void *)virtual_address (
-	    qxl, u64_to_pointer (cmd->u.set.shape), qxl->main_mem_slot);
-	
-	qxl_free (qxl->mem, cursor, "cursor image");
-    }
-    else if (is_drawable && drawable->type == QXL_DRAW_COPY)
-    {
-	struct QXLImage *image = virtual_address (
-	    qxl, u64_to_pointer (drawable->u.copy.src_bitmap), qxl->main_mem_slot);
-	
-	if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
-	{
-	    qxl_surface_unref (qxl->surface_cache, image->surface_image.surface_id);
-	    qxl_surface_cache_sanity_check (qxl->surface_cache);
-	    qxl_free (qxl->mem, image, "surface image");
-	}
-	else
-	{
-	    qxl_image_destroy (qxl, image);
-	}
-    }
-    else if (is_drawable && drawable->type == QXL_DRAW_COMPOSITE)
-    {
-	struct QXLTransform *src_trans, *mask_trans;
-	struct QXLImage *src_img, *mask_img;
-	struct QXLComposite *composite = &drawable->u.composite;
-	
-	/* Source */
-	src_img = virtual_address (
-	    qxl, u64_to_pointer (drawable->u.composite.src), qxl->main_mem_slot);
-	qxl_free (qxl->mem, src_img, "image struct");
-	
-	if (composite->src_transform)
-	{
-	    src_trans = virtual_address (
-		qxl, u64_to_pointer (composite->src_transform), qxl->main_mem_slot);
-	    qxl_free (qxl->mem, src_trans, "transform");
-	}
-	
-	/* Mask */
-	if (drawable->u.composite.mask)
-	{
-	    if (drawable->u.composite.mask_transform)
-	    {
-		mask_trans = virtual_address (
-		    qxl, u64_to_pointer (drawable->u.composite.mask_transform), qxl->main_mem_slot);
-		
-		qxl_free (qxl->mem, mask_trans, "transform");
-	    }
-	    
-	    mask_img = virtual_address (
-		qxl, u64_to_pointer (drawable->u.composite.mask), qxl->main_mem_slot);
-	    qxl_free (qxl->mem, mask_img, "image struct");
-	}
-    }
-    else if (is_surface && surface_cmd->type == QXL_SURFACE_CMD_DESTROY)
-    {
-	qxl_surface_recycle (qxl->surface_cache, surface_cmd->surface_id);
-	qxl_surface_cache_sanity_check (qxl->surface_cache);
-    }
-    
-    id = info->next;
-    
-    qxl_free (qxl->mem, info, "command");
-    
-    return id;
-}
-
-int
-qxl_garbage_collect (qxl_screen_t *qxl)
-{
-    uint64_t id;
-    int      i = 0;
-    
-    while (qxl_ring_pop (qxl->release_ring, &id))
-    {
-	while (id)
-	{
-	    id = qxl_garbage_collect_internal (qxl, id);
-	    
-	    i++;
-	}
-    }
-    
-    return i;
-}
-
-static void
-qxl_usleep (int useconds)
-{
-    struct timespec t;
-    
-    t.tv_sec = useconds / 1000000;
-    t.tv_nsec = (useconds - (t.tv_sec * 1000000)) * 1000;
-    
-    errno = 0;
-    while (nanosleep (&t, &t) == -1 && errno == EINTR)
-	;
-}
-
-int
-qxl_handle_oom (qxl_screen_t *qxl)
-{
-    qxl_io_notify_oom (qxl);
-    
-#if 0
-    ErrorF (".");
-    qxl_usleep (10000);
-#endif
-    
-    if (!(qxl_garbage_collect (qxl)))
-	qxl_usleep (10000);
-    
-    return qxl_garbage_collect (qxl);
-}
-
-void *
-qxl_allocnf (qxl_screen_t *qxl, unsigned long size, const char *name)
-{
-    void *result;
-    int n_attempts = 0;
-    
-#if 0
-    static int nth_oom = 1;
-#endif
-    
-    qxl_garbage_collect (qxl);
-    
-    while (!(result = qxl_alloc (qxl->mem, size, name)))
-    {
-#if 0
-	ErrorF ("eliminated memory (%d)\n", nth_oom++);
-#endif
-	if (!qxl_garbage_collect (qxl))
-	{
-	    if (qxl_handle_oom (qxl))
-	    {
-		n_attempts = 0;
-	    }
-	    else if (++n_attempts == 1000)
-	    {
-		ErrorF ("Out of memory allocating %ld bytes\n", size);
-		qxl_mem_dump_stats (qxl->mem, "Out of mem - stats\n");
-		fprintf (stderr, "Out of memory\n");
-		exit (1);
-	    }
-	}
-    }
-    
-    return result;
-}
-
 static Bool
 qxl_blank_screen (ScreenPtr pScreen, int mode)
 {
diff --git a/src/qxl_mem.c b/src/qxl_mem.c
index ffd338f..fe7cff0 100644
--- a/src/qxl_mem.c
+++ b/src/qxl_mem.c
@@ -25,6 +25,9 @@
 #endif
 
 #include <stdarg.h>
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
 
 #include "qxl.h"
 #include "mspace.h"
@@ -239,3 +242,182 @@ qxl_mark_mem_unverifiable (qxl_screen_t *qxl)
     qxl_mem_unverifiable (qxl->mem);
     qxl_mem_unverifiable (qxl->surf_mem);
 }
+
+
+static uint64_t
+qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
+{
+    /* We assume that there the two low bits of a pointer are
+     * available. If the low one is set, then the command in
+     * question is a cursor command
+     */
+#define POINTER_MASK ((1 << 2) - 1)
+	    
+    union QXLReleaseInfo *info = u64_to_pointer (id & ~POINTER_MASK);
+    struct QXLCursorCmd *cmd = (struct QXLCursorCmd *)info;
+    struct QXLDrawable *drawable = (struct QXLDrawable *)info;
+    struct QXLSurfaceCmd *surface_cmd = (struct QXLSurfaceCmd *)info;
+    int is_cursor = FALSE;
+    int is_surface = FALSE;
+    int is_drawable = FALSE;
+    
+    if ((id & POINTER_MASK) == 1)
+	is_cursor = TRUE;
+    else if ((id & POINTER_MASK) == 2)
+	is_surface = TRUE;
+    else
+	is_drawable = TRUE;
+    
+    if (is_cursor && cmd->type == QXL_CURSOR_SET)
+    {
+	struct QXLCursor *cursor = (void *)virtual_address (
+	    qxl, u64_to_pointer (cmd->u.set.shape), qxl->main_mem_slot);
+	
+	qxl_free (qxl->mem, cursor, "cursor image");
+    }
+    else if (is_drawable && drawable->type == QXL_DRAW_COPY)
+    {
+	struct QXLImage *image = virtual_address (
+	    qxl, u64_to_pointer (drawable->u.copy.src_bitmap), qxl->main_mem_slot);
+	
+	if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
+	{
+	    qxl_surface_unref (qxl->surface_cache, image->surface_image.surface_id);
+	    qxl_surface_cache_sanity_check (qxl->surface_cache);
+	    qxl_free (qxl->mem, image, "surface image");
+	}
+	else
+	{
+	    qxl_image_destroy (qxl, image);
+	}
+    }
+    else if (is_drawable && drawable->type == QXL_DRAW_COMPOSITE)
+    {
+	struct QXLTransform *src_trans, *mask_trans;
+	struct QXLImage *src_img, *mask_img;
+	struct QXLComposite *composite = &drawable->u.composite;
+	
+	/* Source */
+	src_img = virtual_address (
+	    qxl, u64_to_pointer (drawable->u.composite.src), qxl->main_mem_slot);
+	qxl_free (qxl->mem, src_img, "image struct");
+	
+	if (composite->src_transform)
+	{
+	    src_trans = virtual_address (
+		qxl, u64_to_pointer (composite->src_transform), qxl->main_mem_slot);
+	    qxl_free (qxl->mem, src_trans, "transform");
+	}
+	
+	/* Mask */
+	if (drawable->u.composite.mask)
+	{
+	    if (drawable->u.composite.mask_transform)
+	    {
+		mask_trans = virtual_address (
+		    qxl, u64_to_pointer (drawable->u.composite.mask_transform), qxl->main_mem_slot);
+		
+		qxl_free (qxl->mem, mask_trans, "transform");
+	    }
+	    
+	    mask_img = virtual_address (
+		qxl, u64_to_pointer (drawable->u.composite.mask), qxl->main_mem_slot);
+	    qxl_free (qxl->mem, mask_img, "image struct");
+	}
+    }
+    else if (is_surface && surface_cmd->type == QXL_SURFACE_CMD_DESTROY)
+    {
+	qxl_surface_recycle (qxl->surface_cache, surface_cmd->surface_id);
+	qxl_surface_cache_sanity_check (qxl->surface_cache);
+    }
+    
+    id = info->next;
+    
+    qxl_free (qxl->mem, info, "command");
+    
+    return id;
+}
+
+int
+qxl_garbage_collect (qxl_screen_t *qxl)
+{
+    uint64_t id;
+    int      i = 0;
+    
+    while (qxl_ring_pop (qxl->release_ring, &id))
+    {
+	while (id)
+	{
+	    id = qxl_garbage_collect_internal (qxl, id);
+	    
+	    i++;
+	}
+    }
+    
+    return i;
+}
+
+static void
+qxl_usleep (int useconds)
+{
+    struct timespec t;
+    
+    t.tv_sec = useconds / 1000000;
+    t.tv_nsec = (useconds - (t.tv_sec * 1000000)) * 1000;
+    
+    errno = 0;
+    while (nanosleep (&t, &t) == -1 && errno == EINTR)
+	;
+}
+
+int
+qxl_handle_oom (qxl_screen_t *qxl)
+{
+    qxl_io_notify_oom (qxl);
+    
+#if 0
+    ErrorF (".");
+    qxl_usleep (10000);
+#endif
+    
+    if (!(qxl_garbage_collect (qxl)))
+	qxl_usleep (10000);
+    
+    return qxl_garbage_collect (qxl);
+}
+
+void *
+qxl_allocnf (qxl_screen_t *qxl, unsigned long size, const char *name)
+{
+    void *result;
+    int n_attempts = 0;
+    
+#if 0
+    static int nth_oom = 1;
+#endif
+    
+    qxl_garbage_collect (qxl);
+    
+    while (!(result = qxl_alloc (qxl->mem, size, name)))
+    {
+#if 0
+	ErrorF ("eliminated memory (%d)\n", nth_oom++);
+#endif
+	if (!qxl_garbage_collect (qxl))
+	{
+	    if (qxl_handle_oom (qxl))
+	    {
+		n_attempts = 0;
+	    }
+	    else if (++n_attempts == 1000)
+	    {
+		ErrorF ("Out of memory allocating %ld bytes\n", size);
+		qxl_mem_dump_stats (qxl->mem, "Out of mem - stats\n");
+		fprintf (stderr, "Out of memory\n");
+		exit (1);
+	    }
+	}
+    }
+    
+    return result;
+}
-- 
1.8.1.2



More information about the Spice-devel mailing list