pipebuffer: Check buffer over- & underflows when mapping/unmapping too.
authorJosé Fonseca <jrfonseca@tungstengraphics.com>
Thu, 28 Aug 2008 12:06:06 +0000 (21:06 +0900)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Thu, 28 Aug 2008 12:06:06 +0000 (21:06 +0900)
src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c

index 4cb8c3bb5578f5d1ee0d6472d46ba5912372f3d9..5d9f6d3f39b6caa12379fac5e0cf17c1611927ae 100644 (file)
@@ -138,12 +138,30 @@ check_random_pattern(const uint8_t *dst, size_t size,
 
 
 static void
-pb_debug_buffer_destroy(struct pb_buffer *_buf)
+pb_debug_buffer_fill(struct pb_debug_buffer *buf)
 {
-   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);  
    uint8_t *map;
    
-   assert(!buf->base.base.refcount);
+   map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
+   assert(map);
+   if(map) {
+      fill_random_pattern(map, buf->underflow_size);
+      fill_random_pattern(map + buf->underflow_size + buf->base.base.size, 
+                          buf->overflow_size);
+      pb_unmap(buf->buffer);
+   }
+}
+
+
+/**
+ * Check for under/over flows.
+ * 
+ * Should be called with the buffer unmaped.
+ */
+static void
+pb_debug_buffer_check(struct pb_debug_buffer *buf)
+{
+   uint8_t *map;
    
    map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_READ);
    assert(map);
@@ -154,9 +172,9 @@ pb_debug_buffer_destroy(struct pb_buffer *_buf)
       underflow = !check_random_pattern(map, buf->underflow_size, 
                                         &min_ofs, &max_ofs);
       if(underflow) {
-        debug_printf("buffer underflow (%u of %u bytes) detected\n",
-                     buf->underflow_size - min_ofs,
-                     buf->underflow_size);
+         debug_printf("buffer underflow (%u of %u bytes) detected\n",
+                      buf->underflow_size - min_ofs,
+                      buf->underflow_size);
       }
       
       overflow = !check_random_pattern(map + buf->underflow_size + buf->base.base.size, 
@@ -169,9 +187,27 @@ pb_debug_buffer_destroy(struct pb_buffer *_buf)
       }
       
       debug_assert(!underflow && !overflow);
-      
+
+      /* re-fill if not aborted */
+      if(underflow)
+         fill_random_pattern(map, buf->underflow_size);
+      if(overflow)
+         fill_random_pattern(map + buf->underflow_size + buf->base.base.size, 
+                             buf->overflow_size);
+
       pb_unmap(buf->buffer);
    }
+}
+
+
+static void
+pb_debug_buffer_destroy(struct pb_buffer *_buf)
+{
+   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);  
+   
+   assert(!buf->base.base.refcount);
+   
+   pb_debug_buffer_check(buf);
 
    pb_reference(&buf->buffer, NULL);
    FREE(buf);
@@ -183,9 +219,14 @@ pb_debug_buffer_map(struct pb_buffer *_buf,
                     unsigned flags)
 {
    struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
-   void *map = pb_map(buf->buffer, flags);
+   void *map;
+   
+   pb_debug_buffer_check(buf);
+
+   map = pb_map(buf->buffer, flags);
    if(!map)
       return NULL;
+   
    return (uint8_t *)map + buf->underflow_size;
 }
 
@@ -195,6 +236,8 @@ pb_debug_buffer_unmap(struct pb_buffer *_buf)
 {
    struct pb_debug_buffer *buf = pb_debug_buffer(_buf);   
    pb_unmap(buf->buffer);
+   
+   pb_debug_buffer_check(buf);
 }
 
 
@@ -227,7 +270,6 @@ pb_debug_manager_create_buffer(struct pb_manager *_mgr,
    struct pb_debug_buffer *buf;
    struct pb_desc real_desc;
    size_t real_size;
-   uint8_t *map;
    
    buf = CALLOC_STRUCT(pb_debug_buffer);
    if(!buf)
@@ -262,13 +304,7 @@ pb_debug_manager_create_buffer(struct pb_manager *_mgr,
    buf->underflow_size = mgr->band_size;
    buf->overflow_size = buf->buffer->base.size - buf->underflow_size - size;
    
-   map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
-   assert(map);
-   if(map) {
-      fill_random_pattern(map, buf->underflow_size);
-      fill_random_pattern(map + buf->underflow_size + size, buf->overflow_size);
-      pb_unmap(buf->buffer);
-   }
+   pb_debug_buffer_fill(buf);
    
    return &buf->base;
 }