Ejemplo n.º 1
0
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;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
/**
 * 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);
   }
}
Ejemplo n.º 5
0
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;
}