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-09-05 18:17:21 -0400 |
commit | e738d00e1fb3cd469f850765e2b42976c2a85764 (patch) | |
tree | 6aef1abe0f614ff89be7a789b2a2118fe2cbcb1f /src | |
parent | 4a43bd436c58dae72f91905657a36158efc68907 (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.
Diffstat (limited to 'src')
-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 | 14 |
6 files changed, 61 insertions, 39 deletions
@@ -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++; |