* Do not reserve memory when the area is too large. This fixes #7740 where the

reserved amount was simply too small, but also works around address space
  waste with many larger bitmaps.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42298 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2011-06-24 17:04:50 +00:00
parent ee918f6365
commit 8c5a0accf5
3 changed files with 15 additions and 11 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku, Inc. All Rights Reserved. * Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -22,7 +22,7 @@ class ServerMemoryAllocator {
status_t InitCheck(); status_t InitCheck();
status_t AddArea(area_id serverArea, area_id& _localArea, uint8*& _base, status_t AddArea(area_id serverArea, area_id& _localArea, uint8*& _base,
bool readOnly = false); size_t size, bool readOnly = false);
void RemoveArea(area_id serverArea); void RemoveArea(area_id serverArea);
status_t AreaAndBaseFor(area_id serverArea, area_id& area, uint8*& base); status_t AreaAndBaseFor(area_id serverArea, area_id& area, uint8*& base);
+10 -4
View File
@@ -24,6 +24,10 @@
#endif #endif
static const size_t kReservedSize = 128 * 1024 * 1024;
static const size_t kReserveMaxSize = 32 * 1024 * 1024;
namespace BPrivate { namespace BPrivate {
@@ -61,7 +65,7 @@ ServerMemoryAllocator::InitCheck()
status_t status_t
ServerMemoryAllocator::AddArea(area_id serverArea, area_id& _area, ServerMemoryAllocator::AddArea(area_id serverArea, area_id& _area,
uint8*& _base, bool readOnly) uint8*& _base, size_t size, bool readOnly)
{ {
area_mapping* mapping = new (std::nothrow) area_mapping; area_mapping* mapping = new (std::nothrow) area_mapping;
if (mapping == NULL || !fAreas.AddItem(mapping)) { if (mapping == NULL || !fAreas.AddItem(mapping)) {
@@ -73,11 +77,13 @@ ServerMemoryAllocator::AddArea(area_id serverArea, area_id& _area,
uint32 addressSpec = B_ANY_ADDRESS; uint32 addressSpec = B_ANY_ADDRESS;
void* base; void* base;
#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
if (!readOnly) { if (!readOnly && size < kReserveMaxSize) {
// reserve 128 MB of space for the area // Reserve 128 MB of space for the area, but only if the area
// is smaller than 32 MB (else the address space waste would
// likely to be too large)
base = (void*)0x60000000; base = (void*)0x60000000;
status = _kern_reserve_address_range((addr_t*)&base, B_BASE_ADDRESS, status = _kern_reserve_address_range((addr_t*)&base, B_BASE_ADDRESS,
128 * 1024 * 1024); kReservedSize);
addressSpec = status == B_OK ? B_EXACT_ADDRESS : B_BASE_ADDRESS; addressSpec = status == B_OK ? B_EXACT_ADDRESS : B_BASE_ADDRESS;
} }
#endif #endif
+3 -5
View File
@@ -1008,12 +1008,10 @@ BBitmap::_InitObject(BRect bounds, color_space colorSpace, uint32 flags,
} }
// allocate the bitmap buffer // allocate the bitmap buffer
if (error == B_OK) { if (error == B_OK) {
// NOTE: Maybe the code would look more robust if the // TODO: Let the app_server return the size when it allocated the bitmap
// "size" was not calculated here when we ask the server
// to allocate the bitmap. -Stephan
int32 size = bytesPerRow * (bounds.IntegerHeight() + 1); int32 size = bytesPerRow * (bounds.IntegerHeight() + 1);
if (flags & B_BITMAP_NO_SERVER_LINK) { if ((flags & B_BITMAP_NO_SERVER_LINK) != 0) {
fBasePointer = (uint8*)malloc(size); fBasePointer = (uint8*)malloc(size);
if (fBasePointer) { if (fBasePointer) {
fSize = size; fSize = size;
@@ -1055,7 +1053,7 @@ BBitmap::_InitObject(BRect bounds, color_space colorSpace, uint32 flags,
if (allocationFlags & kNewAllocatorArea) { if (allocationFlags & kNewAllocatorArea) {
error = allocator->AddArea(fServerArea, fArea, error = allocator->AddArea(fServerArea, fArea,
fBasePointer); fBasePointer, size);
} else { } else {
error = allocator->AreaAndBaseFor(fServerArea, fArea, error = allocator->AreaAndBaseFor(fServerArea, fArea,
fBasePointer); fBasePointer);