1 /* 2 * Copyright 2006, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 /*! 10 Note, this class don't provide any locking whatsoever - you are 11 supposed to have a BPrivate::AppServerLink object around which 12 does the necessary locking. 13 However, this is not enforced in the methods here, you have to 14 take care for yourself! 15 */ 16 17 #include "ServerMemoryAllocator.h" 18 19 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST 20 # include <syscalls.h> 21 #endif 22 23 #include <new> 24 25 26 namespace BPrivate { 27 28 struct area_mapping { 29 area_id server_area; 30 area_id local_area; 31 uint8* local_base; 32 }; 33 34 35 ServerMemoryAllocator::ServerMemoryAllocator() 36 : 37 fAreas(4) 38 { 39 } 40 41 42 ServerMemoryAllocator::~ServerMemoryAllocator() 43 { 44 for (int32 i = fAreas.CountItems(); i-- > 0;) { 45 area_mapping* mapping = (area_mapping*)fAreas.ItemAt(i); 46 47 delete_area(mapping->local_area); 48 delete mapping; 49 } 50 } 51 52 53 status_t 54 ServerMemoryAllocator::InitCheck() 55 { 56 return B_OK; 57 } 58 59 60 status_t 61 ServerMemoryAllocator::AddArea(area_id serverArea, area_id& _area, uint8*& _base, 62 bool readOnly) 63 { 64 area_mapping* mapping = new (std::nothrow) area_mapping; 65 if (mapping == NULL || !fAreas.AddItem(mapping)) { 66 delete mapping; 67 return B_NO_MEMORY; 68 } 69 70 status_t status = B_ERROR; 71 uint32 addressSpec = B_ANY_ADDRESS; 72 void* base; 73 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST 74 if (!readOnly) { 75 // reserve 128 MB of space for the area 76 base = (void*)0x60000000; 77 status = _kern_reserve_heap_address_range((addr_t*)&base, 78 B_BASE_ADDRESS, 128 * 1024 * 1024); 79 addressSpec = status == B_OK ? B_EXACT_ADDRESS : B_BASE_ADDRESS; 80 } 81 #endif 82 83 mapping->local_area = clone_area(readOnly ? "server read-only memory" : "server_memory", 84 &base, addressSpec, B_READ_AREA | (readOnly ? 0 : B_WRITE_AREA), serverArea); 85 if (mapping->local_area < B_OK) { 86 status = mapping->local_area; 87 88 fAreas.RemoveItem(mapping); 89 delete mapping; 90 91 return status; 92 } 93 94 mapping->server_area = serverArea; 95 mapping->local_base = (uint8*)base; 96 97 _area = mapping->local_area; 98 _base = mapping->local_base; 99 100 return B_OK; 101 } 102 103 104 void 105 ServerMemoryAllocator::RemoveArea(area_id serverArea) 106 { 107 for (int32 i = fAreas.CountItems(); i-- > 0;) { 108 area_mapping* mapping = (area_mapping*)fAreas.ItemAt(i); 109 110 if (mapping->server_area == serverArea) { 111 // we found the area we should remove 112 delete_area(mapping->local_area); 113 delete mapping; 114 break; 115 } 116 } 117 } 118 119 120 status_t 121 ServerMemoryAllocator::AreaAndBaseFor(area_id serverArea, area_id& _area, uint8*& _base) 122 { 123 for (int32 i = fAreas.CountItems(); i-- > 0;) { 124 area_mapping* mapping = (area_mapping*)fAreas.ItemAt(i); 125 126 if (mapping->server_area == serverArea) { 127 _area = mapping->local_area; 128 _base = mapping->local_base; 129 return B_OK; 130 } 131 } 132 133 return B_ERROR; 134 } 135 136 } // namespace BPrivate 137