OSDN Git Service

fix [1980202] Surfaceflinger crash with transparent rollo on firestone
authorMathias Agopian <mathias@google.com>
Fri, 17 Jul 2009 01:04:54 +0000 (18:04 -0700)
committerMathias Agopian <mathias@google.com>
Fri, 17 Jul 2009 01:06:19 +0000 (18:06 -0700)
we now automatically size the pmem region isntead of using hardcoded values

modules/gralloc/allocator.cpp
modules/gralloc/allocator.h
modules/gralloc/gralloc.cpp

index f901741..4dad6a1 100644 (file)
 // align all the memory blocks on a cache-line boundary
 const int SimpleBestFitAllocator::kMemoryAlign = 32;
 
-SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
+SimpleBestFitAllocator::SimpleBestFitAllocator()
+    : mHeapSize(0)
 {
-    size_t pagesize = getpagesize();
-    mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
+}
 
-    chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
-    mList.insertHead(node);
+SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
+    : mHeapSize(0)
+{
+    setSize(size);
 }
 
 SimpleBestFitAllocator::~SimpleBestFitAllocator()
@@ -38,14 +40,27 @@ SimpleBestFitAllocator::~SimpleBestFitAllocator()
     }
 }
 
+ssize_t SimpleBestFitAllocator::setSize(size_t size)
+{
+    Locker::Autolock _l(mLock);
+    if (mHeapSize != 0) return -EINVAL;
+    size_t pagesize = getpagesize();
+    mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
+    chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
+    mList.insertHead(node);
+    return size;
+}
+    
+    
 size_t SimpleBestFitAllocator::size() const
 {
     return mHeapSize;
 }
 
-size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
+ssize_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
 {
     Locker::Autolock _l(mLock);
+    if (mHeapSize == 0) return -EINVAL;
     ssize_t offset = alloc(size, flags);
     return offset;
 }
@@ -53,6 +68,7 @@ size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
 ssize_t SimpleBestFitAllocator::deallocate(size_t offset)
 {
     Locker::Autolock _l(mLock);
+    if (mHeapSize == 0) return -EINVAL;
     chunk_t const * const freed = dealloc(offset);
     if (freed) {
         return 0;
index dfb06f6..6823982 100644 (file)
@@ -95,12 +95,15 @@ class SimpleBestFitAllocator
 {
 public:
 
-                        SimpleBestFitAllocator(size_t size);
-    virtual             ~SimpleBestFitAllocator();
+    SimpleBestFitAllocator();
+    SimpleBestFitAllocator(size_t size);
+    ~SimpleBestFitAllocator();
 
-    virtual size_t      allocate(size_t size, uint32_t flags = 0);
-    virtual ssize_t     deallocate(size_t offset);
-    virtual size_t      size() const;
+    ssize_t     setSize(size_t size);
+
+    ssize_t     allocate(size_t size, uint32_t flags = 0);
+    ssize_t     deallocate(size_t offset);
+    size_t      size() const;
 
 private:
     struct chunk_t {
@@ -123,5 +126,4 @@ private:
     size_t              mHeapSize;
 };
 
-
 #endif /* GRALLOC_ALLOCATOR_H_ */
index 8c496dc..9928a75 100644 (file)
 
 /*****************************************************************************/
 
+static SimpleBestFitAllocator sAllocator;
+
+/*****************************************************************************/
+
 struct gralloc_context_t {
     alloc_device_t  device;
     /* our private data here */
@@ -172,14 +176,23 @@ static int gralloc_alloc_framebuffer(alloc_device_t* dev,
     return err;
 }
 
-static SimpleBestFitAllocator sAllocator(8*1024*1024);
-
 static int init_pmem_area_locked(private_module_t* m)
 {
     int err = 0;
     int master_fd = open("/dev/pmem", O_RDWR, 0);
     if (master_fd >= 0) {
-        void* base = mmap(0, sAllocator.size(),
+        
+        size_t size;
+        pmem_region region;
+        if (ioctl(master_fd, PMEM_GET_TOTAL_SIZE, &region) < 0) {
+            LOGE("PMEM_GET_TOTAL_SIZE failed, limp mode");
+            size = 8<<20;   // 8 MiB
+        } else {
+            size = region.len;
+        }
+        sAllocator.setSize(size);
+
+        void* base = mmap(0, size, 
                 PROT_READ|PROT_WRITE, MAP_SHARED, master_fd, 0);
         if (base == MAP_FAILED) {
             err = -errno;