BPicture: Fix archive constructor.
[haiku.git] / src / kits / app / ServerMemoryAllocator.cpp
blob6d34fc238dfe8dc59c8e39142803464cfdb8a178
1 /*
2 * Copyright 2006-2012, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 */
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"
20 #include <new>
22 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
23 # include <syscalls.h>
24 #endif
27 static const size_t kReservedSize = 128 * 1024 * 1024;
28 static const size_t kReserveMaxSize = 32 * 1024 * 1024;
31 namespace BPrivate {
34 struct area_mapping {
35 area_id server_area;
36 area_id local_area;
37 uint8* local_base;
41 ServerMemoryAllocator::ServerMemoryAllocator()
43 fAreas(4)
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);
54 delete mapping;
59 status_t
60 ServerMemoryAllocator::InitCheck()
62 return B_OK;
66 status_t
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)) {
72 delete mapping;
73 return B_NO_MEMORY;
76 status_t status = B_ERROR;
77 uint32 addressSpec = B_ANY_ADDRESS;
78 void* base;
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,
86 kReservedSize);
87 addressSpec = status == B_OK ? B_EXACT_ADDRESS : B_BASE_ADDRESS;
89 #endif
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);
98 delete mapping;
100 return status;
103 mapping->server_area = serverArea;
104 mapping->local_base = (uint8*)base;
106 _area = mapping->local_area;
107 _base = mapping->local_base;
109 return B_OK;
113 void
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);
122 delete mapping;
123 fAreas.RemoveItem(i);
124 break;
130 status_t
131 ServerMemoryAllocator::AreaAndBaseFor(area_id serverArea, area_id& _area,
132 uint8*& _base)
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;
141 return B_OK;
145 return B_ERROR;
149 } // namespace BPrivate