diff options
author | Søren Sandmann <ssp@redhat.com> | 2012-08-21 12:56:52 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-08-23 17:45:31 -0400 |
commit | f81be0914b8208f99bdfce5685b54db15fa05af1 (patch) | |
tree | e1e6eb1c0d22024e342970f124635f897682dc92 | |
parent | bdf042a1552680014a6ccd5f3aaf8f190a831e3c (diff) |
better memory debugging
-rw-r--r-- | src/qxl.h | 9 | ||||
-rw-r--r-- | src/qxl_cursor.c | 4 | ||||
-rw-r--r-- | src/qxl_driver.c | 34 | ||||
-rw-r--r-- | src/qxl_image.c | 8 | ||||
-rw-r--r-- | src/qxl_mem.c | 31 | ||||
-rw-r--r-- | src/qxl_surface.c | 18 |
6 files changed, 63 insertions, 41 deletions
@@ -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]; |