static void * vmw_swc_reserve(struct svga_winsys_context *swc, uint32_t nr_bytes, uint32_t nr_relocs ) { struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); #ifdef DEBUG /* Check if somebody forgot to check the previous failure */ if(vswc->must_flush) { debug_printf("Forgot to flush:\n"); debug_backtrace_dump(vswc->must_flush_stack, VMW_MUST_FLUSH_STACK); assert(!vswc->must_flush); } debug_flush_might_flush(vswc->fctx); #endif assert(nr_bytes <= vswc->command.size); if(nr_bytes > vswc->command.size) return NULL; if(vswc->preemptive_flush || vswc->command.used + nr_bytes > vswc->command.size || vswc->surface.used + nr_relocs > vswc->surface.size || vswc->shader.used + nr_relocs > vswc->shader.size || vswc->region.used + nr_relocs > vswc->region.size) { #ifdef DEBUG vswc->must_flush = TRUE; debug_backtrace_capture(vswc->must_flush_stack, 1, VMW_MUST_FLUSH_STACK); #endif return NULL; } assert(vswc->command.used + nr_bytes <= vswc->command.size); assert(vswc->surface.used + nr_relocs <= vswc->surface.size); assert(vswc->shader.used + nr_relocs <= vswc->shader.size); assert(vswc->region.used + nr_relocs <= vswc->region.size); vswc->command.reserved = nr_bytes; vswc->surface.reserved = nr_relocs; vswc->surface.staged = 0; vswc->shader.reserved = nr_relocs; vswc->shader.staged = 0; vswc->region.reserved = nr_relocs; vswc->region.staged = 0; return vswc->command.buffer + vswc->command.used; }
static void * pb_debug_buffer_map(struct pb_buffer *_buf, unsigned flags, void *flush_ctx) { struct pb_debug_buffer *buf = pb_debug_buffer(_buf); void *map; pb_debug_buffer_check(buf); map = pb_map(buf->buffer, flags, flush_ctx); if (!map) return NULL; mtx_lock(&buf->mutex); ++buf->map_count; debug_backtrace_capture(buf->map_backtrace, 1, PB_DEBUG_MAP_BACKTRACE); mtx_unlock(&buf->mutex); return (uint8_t *)map + buf->underflow_size; }
void * debug_malloc(const char *file, unsigned line, const char *function, size_t size) { struct debug_memory_header *hdr; struct debug_memory_footer *ftr; hdr = os_malloc(sizeof(*hdr) + size + sizeof(*ftr)); if(!hdr) { debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", file, line, function, (long unsigned)size); return NULL; } hdr->no = last_no++; hdr->file = file; hdr->line = line; hdr->function = function; hdr->size = size; hdr->magic = DEBUG_MEMORY_MAGIC; hdr->tag = 0; #if DEBUG_FREED_MEMORY hdr->freed = FALSE; #endif #if DEBUG_MEMORY_STACK debug_backtrace_capture(hdr->backtrace, 0, DEBUG_MEMORY_STACK); #endif ftr = footer_from_header(hdr); ftr->magic = DEBUG_MEMORY_MAGIC; pipe_mutex_lock(list_mutex); LIST_ADDTAIL(&hdr->head, &list); pipe_mutex_unlock(list_mutex); return data_from_header(hdr); }
/** * Log a reference count change to the log file (if enabled). * This is called via the pipe_reference() and debug_reference() functions, * basically whenever a reference count is initialized or changed. * * \param p the refcount being changed (the value is not changed here) * \param get_desc a function which will be called to print an object's * name/pointer into a string buffer during logging * \param change the reference count change which must be +/-1 or 0 when * creating the object and initializing the refcount. */ void debug_reference_slowpath(const struct pipe_reference *p, debug_reference_descriptor get_desc, int change) { assert(change >= -1); assert(change <= 1); if (debug_refcnt_state < 0) return; if (!debug_refcnt_state) { const char *filename = debug_get_option("GALLIUM_REFCNT_LOG", NULL); if (filename && filename[0]) stream = fopen(filename, "wt"); if (stream) debug_refcnt_state = 1; else debug_refcnt_state = -1; } if (debug_refcnt_state > 0) { struct debug_stack_frame frames[STACK_LEN]; const char *symbols[STACK_LEN]; char buf[1024]; unsigned i; unsigned refcnt = p->count; unsigned serial; boolean existing = debug_serial((void *) p, &serial); debug_backtrace_capture(frames, 1, STACK_LEN); for (i = 0; i < STACK_LEN; ++i) { if (frames[i].function) symbols[i] = debug_symbol_name_cached(frames[i].function); else symbols[i] = 0; } get_desc(buf, p); if (!existing) { fprintf(stream, "<%s> %p %u Create\n", buf, (void *) p, serial); dump_stack(symbols); /* this is here to provide a gradual change even if we don't see * the initialization */ for (i = 1; i <= refcnt - change; ++i) { fprintf(stream, "<%s> %p %u AddRef %u\n", buf, (void *) p, serial, i); dump_stack(symbols); } } if (change) { fprintf(stream, "<%s> %p %u %s %u\n", buf, (void *) p, serial, change > 0 ? "AddRef" : "Release", refcnt); dump_stack(symbols); } if (!refcnt) { debug_serial_delete((void *) p); fprintf(stream, "<%s> %p %u Destroy\n", buf, (void *) p, serial); dump_stack(symbols); } fflush(stream); } }
static struct pb_buffer * pb_debug_manager_create_buffer(struct pb_manager *_mgr, pb_size size, const struct pb_desc *desc) { struct pb_debug_manager *mgr = pb_debug_manager(_mgr); struct pb_debug_buffer *buf; struct pb_desc real_desc; pb_size real_size; assert(size); assert(desc->alignment); buf = CALLOC_STRUCT(pb_debug_buffer); if(!buf) return NULL; real_size = mgr->underflow_size + size + mgr->overflow_size; real_desc = *desc; real_desc.usage |= PIPE_BUFFER_USAGE_CPU_WRITE; real_desc.usage |= PIPE_BUFFER_USAGE_CPU_READ; buf->buffer = mgr->provider->create_buffer(mgr->provider, real_size, &real_desc); if(!buf->buffer) { FREE(buf); #if 0 pipe_mutex_lock(mgr->mutex); debug_printf("%s: failed to create buffer\n", __FUNCTION__); if(!LIST_IS_EMPTY(&mgr->list)) pb_debug_manager_dump(mgr); pipe_mutex_unlock(mgr->mutex); #endif return NULL; } assert(pipe_is_referenced(&buf->buffer->base.reference)); assert(pb_check_alignment(real_desc.alignment, buf->buffer->base.alignment)); assert(pb_check_usage(real_desc.usage, buf->buffer->base.usage)); assert(buf->buffer->base.size >= real_size); pipe_reference_init(&buf->base.base.reference, 1); buf->base.base.alignment = desc->alignment; buf->base.base.usage = desc->usage; buf->base.base.size = size; buf->base.vtbl = &pb_debug_buffer_vtbl; buf->mgr = mgr; buf->underflow_size = mgr->underflow_size; buf->overflow_size = buf->buffer->base.size - buf->underflow_size - size; debug_backtrace_capture(buf->create_backtrace, 1, PB_DEBUG_CREATE_BACKTRACE); pb_debug_buffer_fill(buf); pipe_mutex_init(buf->mutex); pipe_mutex_lock(mgr->mutex); LIST_ADDTAIL(&buf->head, &mgr->list); pipe_mutex_unlock(mgr->mutex); return &buf->base; }