summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <ssp@redhat.com>2012-08-21 12:56:52 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-08-23 17:45:31 -0400
commitf81be0914b8208f99bdfce5685b54db15fa05af1 (patch)
treee1e6eb1c0d22024e342970f124635f897682dc92
parentbdf042a1552680014a6ccd5f3aaf8f190a831e3c (diff)
better memory debugging
-rw-r--r--src/qxl.h9
-rw-r--r--src/qxl_cursor.c4
-rw-r--r--src/qxl_driver.c34
-rw-r--r--src/qxl_image.c8
-rw-r--r--src/qxl_mem.c31
-rw-r--r--src/qxl_surface.c18
6 files changed, 63 insertions, 41 deletions
diff --git a/src/qxl.h b/src/qxl.h
index 90ac44e..8494550 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -460,12 +460,15 @@ struct qxl_mem * qxl_mem_create (void *base,
void qxl_mem_dump_stats (struct qxl_mem *mem,
const char *header);
void * qxl_alloc (struct qxl_mem *mem,
- unsigned long n_bytes);
+ unsigned long n_bytes,
+ const char * name);
void qxl_free (struct qxl_mem *mem,
- void *d);
+ void *d,
+ const char * name);
void qxl_mem_free_all (struct qxl_mem *mem);
void * qxl_allocnf (qxl_screen_t *qxl,
- unsigned long size);
+ unsigned long size,
+ const char * name);
int qxl_garbage_collect (qxl_screen_t *qxl);
#ifdef DEBUG_QXL_MEM
diff --git a/src/qxl_cursor.c b/src/qxl_cursor.c
index 72c6c9f..459cbd7 100644
--- a/src/qxl_cursor.c
+++ b/src/qxl_cursor.c
@@ -50,7 +50,7 @@ static struct QXLCursorCmd *
qxl_alloc_cursor_cmd(qxl_screen_t *qxl)
{
struct QXLCursorCmd *cmd =
- qxl_allocnf (qxl, sizeof(struct QXLCursorCmd));
+ qxl_allocnf (qxl, sizeof(struct QXLCursorCmd), "cursor command");
cmd->release_info.id = pointer_to_u64 (cmd) | 1;
@@ -94,7 +94,7 @@ qxl_load_cursor_argb (ScrnInfoPtr pScrn, CursorPtr pCurs)
struct QXLCursorCmd *cmd = qxl_alloc_cursor_cmd (qxl);
struct QXLCursor *cursor =
- qxl_allocnf(qxl, sizeof(struct QXLCursor) + size);
+ qxl_allocnf(qxl, sizeof(struct QXLCursor) + size, "cursor data");
cursor->header.unique = 0;
cursor->header.type = SPICE_CURSOR_TYPE_ALPHA;
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index a42ef72..5d932a7 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -331,7 +331,7 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
* 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;
@@ -339,34 +339,31 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
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;
-
- cursor = (void *)virtual_address (
+ struct QXLCursor *cursor = (void *)virtual_address (
qxl, u64_to_pointer (cmd->u.set.shape), qxl->main_mem_slot);
- qxl_free (qxl->mem, cursor);
+
+ qxl_free (qxl->mem, cursor, "cursor image");
}
else if (is_drawable && drawable->type == QXL_DRAW_COPY)
{
- struct QXLImage *image;
-
- image = virtual_address (
- qxl, u64_to_pointer (drawable->u.copy.src_bitmap),
- qxl->main_mem_slot);
+ 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);
+ qxl_free (qxl->mem, image, "surface image");
}
else
{
@@ -378,10 +375,11 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
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);
-
+
+ qxl_free (qxl->mem, info, "command");
+
return id;
}
@@ -421,7 +419,7 @@ qxl_handle_oom (qxl_screen_t *qxl)
}
void *
-qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
+qxl_allocnf (qxl_screen_t *qxl, unsigned long size, const char *name)
{
void *result;
int n_attempts = 0;
@@ -432,7 +430,7 @@ qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
qxl_garbage_collect (qxl);
- while (!(result = qxl_alloc (qxl->mem, size)))
+ while (!(result = qxl_alloc (qxl->mem, size, name)))
{
#if 0
ErrorF ("eliminated memory (%d)\n", nth_oom++);
diff --git a/src/qxl_image.c b/src/qxl_image.c
index ece1d99..fcecf8a 100644
--- a/src/qxl_image.c
+++ b/src/qxl_image.c
@@ -160,7 +160,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
int chunk_size = MAX (512 * 512, dest_stride);
int n_lines = MIN ((chunk_size / dest_stride), h);
QXLDataChunk *chunk =
- qxl_allocnf (qxl, sizeof *chunk + n_lines * dest_stride);
+ qxl_allocnf (qxl, sizeof *chunk + n_lines * dest_stride, "image data");
chunk->data_size = n_lines * dest_stride;
hash = hash_and_copy (data, stride,
@@ -187,7 +187,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
}
/* Image */
- image = qxl_allocnf (qxl, sizeof *image);
+ image = qxl_allocnf (qxl, sizeof *image, "image struct");
image->descriptor.id = 0;
image->descriptor.type = SPICE_IMAGE_TYPE_BITMAP;
@@ -276,10 +276,10 @@ qxl_image_destroy (qxl_screen_t *qxl,
chunk = virtual->next_chunk;
- qxl_free (qxl->mem, virtual);
+ qxl_free (qxl->mem, virtual, "image data");
}
- qxl_free (qxl->mem, image);
+ qxl_free (qxl->mem, image, "image struct");
}
void
diff --git a/src/qxl_mem.c b/src/qxl_mem.c
index 3d9acfd..c32eba6 100644
--- a/src/qxl_mem.c
+++ b/src/qxl_mem.c
@@ -24,6 +24,8 @@
#include "config.h"
#endif
+#include <stdarg.h>
+
#include "qxl.h"
#include "mspace.h"
@@ -51,6 +53,18 @@ qxl_mem_unverifiable(struct qxl_mem *mem)
}
#endif
+static void
+errout (void *data, const char *format, ...)
+{
+ va_list va;
+
+ va_start (va, format);
+
+ VErrorF (format, va);
+
+ va_end (va);
+}
+
struct qxl_mem *
qxl_mem_create (void *base,
unsigned long n_bytes)
@@ -63,6 +77,8 @@ qxl_mem_create (void *base,
ErrorF ("memory space from %p to %p\n", base, (char *)base + n_bytes);
+ mspace_set_print_func (errout);
+
mem->space = create_mspace_with_base (base, n_bytes, 0, NULL);
mem->base = base;
@@ -89,20 +105,21 @@ qxl_mem_dump_stats (struct qxl_mem *mem,
const char *header)
{
ErrorF ("%s\n", header);
-
+
mspace_malloc_stats (mem->space);
}
void *
qxl_alloc (struct qxl_mem *mem,
- unsigned long n_bytes)
+ unsigned long n_bytes,
+ const char *name)
{
void *addr = mspace_malloc (mem->space, n_bytes);
#ifdef DEBUG_QXL_MEM
VALGRIND_MALLOCLIKE_BLOCK(addr, n_bytes, 0, 0);
#ifdef DEBUG_QXL_MEM_VERBOSE
- fprintf(stderr, "alloc %p: %ld\n", addr, n_bytes);
+ fprintf(stderr, "alloc %p: %ld (%s)\n", addr, n_bytes, name);
#endif
#endif
return addr;
@@ -110,12 +127,16 @@ qxl_alloc (struct qxl_mem *mem,
void
qxl_free (struct qxl_mem *mem,
- void *d)
+ void *d,
+ const char * name)
{
+#if 0
+ ErrorF ("%p <= free %s\n", d, name);
+#endif
mspace_free (mem->space, d);
#ifdef DEBUG_QXL_MEM
#ifdef DEBUG_QXL_MEM_VERBOSE
- fprintf(stderr, "free %p\n", d);
+ fprintf(stderr, "free %p %s\n", d, name);
#endif
VALGRIND_FREELIKE_BLOCK(d, 0);
#endif
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index c422476..e88675f 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -348,7 +348,7 @@ qxl_surface_recycle (surface_cache_t *cache, uint32_t id)
qxl_surface_t *surface = cache->all_surfaces + id;
n_live--;
- qxl_free (cache->qxl->surf_mem, surface->address);
+ qxl_free (cache->qxl->surf_mem, surface->address, "surface memory");
surface->next = cache->free_surfaces;
cache->free_surfaces = surface;
@@ -445,7 +445,7 @@ make_surface_cmd (surface_cache_t *cache, uint32_t id, QXLSurfaceCmdType type)
struct QXLSurfaceCmd *cmd;
qxl_screen_t *qxl = cache->qxl;
- cmd = qxl_allocnf (qxl, sizeof *cmd);
+ cmd = qxl_allocnf (qxl, sizeof *cmd, "surface command");
cmd->release_info.id = pointer_to_u64 (cmd) | 2;
cmd->type = type;
@@ -490,7 +490,7 @@ make_drawable (qxl_screen_t *qxl, int surface, uint8_t type,
struct QXLDrawable *drawable;
int i;
- drawable = qxl_allocnf (qxl, sizeof *drawable);
+ drawable = qxl_allocnf (qxl, sizeof *drawable, "drawable command");
assert(drawable);
drawable->release_info.id = pointer_to_u64 (drawable);
@@ -631,7 +631,7 @@ surface_send_create (surface_cache_t *cache,
*/
qxl_garbage_collect (qxl);
retry2:
- address = qxl_alloc (qxl->surf_mem, stride * height + stride);
+ address = qxl_alloc (qxl->surf_mem, stride * height + stride, "surface memory");
if (!address)
{
@@ -640,7 +640,7 @@ retry2:
if (qxl_garbage_collect (qxl))
goto retry2;
- ErrorF ("- OOM at %d %d %d\n", width, height, bpp);
+ ErrorF ("- OOM at %d %d %d (= %d bytes)\n", width, height, bpp, width * height * (bpp / 8));
print_cache_info (cache);
if (qxl_handle_oom (qxl))
@@ -663,7 +663,7 @@ retry:
if (!qxl_handle_oom (cache->qxl))
{
ErrorF (" Out of surfaces\n");
- qxl_free (qxl->surf_mem, address);
+ qxl_free (qxl->surf_mem, address, "surface memory");
return NULL;
}
else
@@ -1336,7 +1336,7 @@ qxl_surface_copy (qxl_surface_t *dest,
}
else
{
- struct QXLImage *image = qxl_allocnf (qxl, sizeof *image);
+ struct QXLImage *image = qxl_allocnf (qxl, sizeof *image, "surface image struct");
dest->u.copy_src->ref_count++;
@@ -1406,7 +1406,7 @@ image_from_picture (qxl_screen_t *qxl,
qxl_surface_t *surface,
int *force_opaque)
{
- struct QXLImage *image = qxl_allocnf (qxl, sizeof *image);
+ struct QXLImage *image = qxl_allocnf (qxl, sizeof *image, "image struct for picture");
image->descriptor.id = 0;
image->descriptor.type = SPICE_IMAGE_TYPE_SURFACE;
@@ -1427,7 +1427,7 @@ get_transform (qxl_screen_t *qxl, PictTransform *transform)
{
if (transform)
{
- QXLTransform *qxform = qxl_allocnf (qxl, sizeof (QXLTransform));
+ QXLTransform *qxform = qxl_allocnf (qxl, sizeof (QXLTransform), "transform");
qxform->t00 = transform->matrix[0][0];
qxform->t01 = transform->matrix[0][1];