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-09-05 18:17:21 -0400
commite738d00e1fb3cd469f850765e2b42976c2a85764 (patch)
tree6aef1abe0f614ff89be7a789b2a2118fe2cbcb1f
parent4a43bd436c58dae72f91905657a36158efc68907 (diff)
Improved support for memory debugging.
Make all memory allocation functions take a string that will explain what the memory will be used for. This allows debug print statements to be added to the allocation functions and could later potentially be used for more detailed statistics.
-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.c14
6 files changed, 61 insertions, 39 deletions
diff --git a/src/qxl.h b/src/qxl.h
index 1d9ca75..d976fd5 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -446,12 +446,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 7535e11..634f181 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 dba40e3..68d063e 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;
@@ -280,10 +280,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 387a183..579a284 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -337,7 +337,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;
@@ -434,7 +434,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;
@@ -479,7 +479,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);
@@ -620,7 +620,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)
{
@@ -629,7 +629,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))
@@ -652,7 +652,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
@@ -1322,7 +1322,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++;