2 * Copyright 2006-2012, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, axeld@pinc-software.de
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!
18 #include "ServerMemoryAllocator.h"
22 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
23 # include <syscalls.h>
27 static const size_t kReservedSize
= 128 * 1024 * 1024;
28 static const size_t kReserveMaxSize
= 32 * 1024 * 1024;
41 ServerMemoryAllocator::ServerMemoryAllocator()
48 ServerMemoryAllocator::~ServerMemoryAllocator()
50 for (int32 i
= fAreas
.CountItems(); i
-- > 0;) {
51 area_mapping
* mapping
= (area_mapping
*)fAreas
.ItemAt(i
);
53 delete_area(mapping
->local_area
);
60 ServerMemoryAllocator::InitCheck()
67 ServerMemoryAllocator::AddArea(area_id serverArea
, area_id
& _area
,
68 uint8
*& _base
, size_t size
, bool readOnly
)
70 area_mapping
* mapping
= new (std::nothrow
) area_mapping
;
71 if (mapping
== NULL
|| !fAreas
.AddItem(mapping
)) {
76 status_t status
= B_ERROR
;
77 uint32 addressSpec
= B_ANY_ADDRESS
;
79 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
80 if (!readOnly
&& size
< kReserveMaxSize
) {
81 // Reserve 128 MB of space for the area, but only if the area
82 // is smaller than 32 MB (else the address space waste would
83 // likely to be too large)
84 base
= (void*)0x60000000;
85 status
= _kern_reserve_address_range((addr_t
*)&base
, B_BASE_ADDRESS
,
87 addressSpec
= status
== B_OK
? B_EXACT_ADDRESS
: B_BASE_ADDRESS
;
91 mapping
->local_area
= clone_area(readOnly
92 ? "server read-only memory" : "server_memory", &base
, addressSpec
,
93 B_READ_AREA
| (readOnly
? 0 : B_WRITE_AREA
), serverArea
);
94 if (mapping
->local_area
< B_OK
) {
95 status
= mapping
->local_area
;
97 fAreas
.RemoveItem(mapping
);
103 mapping
->server_area
= serverArea
;
104 mapping
->local_base
= (uint8
*)base
;
106 _area
= mapping
->local_area
;
107 _base
= mapping
->local_base
;
114 ServerMemoryAllocator::RemoveArea(area_id serverArea
)
116 for (int32 i
= fAreas
.CountItems(); i
-- > 0;) {
117 area_mapping
* mapping
= (area_mapping
*)fAreas
.ItemAt(i
);
119 if (mapping
->server_area
== serverArea
) {
120 // we found the area we should remove
121 delete_area(mapping
->local_area
);
123 fAreas
.RemoveItem(i
);
131 ServerMemoryAllocator::AreaAndBaseFor(area_id serverArea
, area_id
& _area
,
134 // TODO: why not use a map?
135 for (int32 i
= fAreas
.CountItems(); i
-- > 0;) {
136 area_mapping
* mapping
= (area_mapping
*)fAreas
.ItemAt(i
);
138 if (mapping
->server_area
== serverArea
) {
139 _area
= mapping
->local_area
;
140 _base
= mapping
->local_base
;
149 } // namespace BPrivate