| 4220 | |
| 4221 | |
| 4222 | static ULONG memory_init(thread_db* tdbb, BufferControl* bcb, ULONG number) |
| 4223 | { |
| 4224 | /************************************** |
| 4225 | * |
| 4226 | * m e m o r y _ i n i t |
| 4227 | * |
| 4228 | ************************************** |
| 4229 | * |
| 4230 | * Functional description |
| 4231 | * Initialize memory for the cache. |
| 4232 | * Return number of buffers allocated. |
| 4233 | * |
| 4234 | **************************************/ |
| 4235 | SET_TDBB(tdbb); |
| 4236 | Database* const dbb = tdbb->getDatabase(); |
| 4237 | |
| 4238 | ULONG buffers = 0; |
| 4239 | const size_t page_size = dbb->dbb_page_size; |
| 4240 | UCHAR* memory = nullptr; |
| 4241 | UCHAR* lock_memory = nullptr; |
| 4242 | const UCHAR* memory_end = nullptr; |
| 4243 | BufferDesc* tail = nullptr; |
| 4244 | |
| 4245 | const size_t lock_key_extra = PageNumber::getLockLen() > Lock::KEY_STATIC_SIZE ? |
| 4246 | PageNumber::getLockLen() - Lock::KEY_STATIC_SIZE : 0; |
| 4247 | |
| 4248 | const size_t lock_size = (bcb->bcb_flags & BCB_exclusive) ? 0 : |
| 4249 | FB_ALIGN(sizeof(Lock) + lock_key_extra, alignof(Lock)); |
| 4250 | |
| 4251 | while (number) |
| 4252 | { |
| 4253 | if (!memory) |
| 4254 | { |
| 4255 | // Allocate memory block big enough to accomodate BufferDesc's, Lock's and page buffers. |
| 4256 | |
| 4257 | ULONG to_alloc = number; |
| 4258 | |
| 4259 | while (true) |
| 4260 | { |
| 4261 | const size_t memory_size = (sizeof(BufferDesc) + lock_size + page_size) * (to_alloc + 1); |
| 4262 | |
| 4263 | fb_assert(memory_size > 0); |
| 4264 | if (memory_size < MIN_BUFFER_SEGMENT) |
| 4265 | { |
| 4266 | // Diminishing returns |
| 4267 | return buffers; |
| 4268 | } |
| 4269 | |
| 4270 | try |
| 4271 | { |
| 4272 | memory = (UCHAR*) bcb->bcb_bufferpool->allocate(memory_size ALLOC_ARGS); |
| 4273 | memory_end = memory + memory_size; |
| 4274 | break; |
| 4275 | } |
| 4276 | catch (Firebird::BadAlloc&) |
| 4277 | { |
| 4278 | // Either there's not enough virtual memory or there is |
| 4279 | // but it's not virtually contiguous. Let's find out by |
no test coverage detected