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