Block GPUTransientMemoryAllocator::allocate(GPUProgressTracking & progress, GPUTransientChunk & chunk, size_t size, size_t alignment, SeqNum cmdList) { size = roundUpToMultiple(size, alignment); auto &free = chunk.m_free; auto b = free.fitAtBegin(size, alignment); #if 0 XOR_GPU_TRANSIENT_VERBOSE("Trying to allocate %zu for list %lld in existing chunk (%lld, %lld).\n", size, cmdList, free.begin, free.end); #endif // If the allocation fits in the previous active chunk, just use that. if (b) { free.begin = b.end; #if 0 XOR_GPU_TRANSIENT_VERBOSE(" Allocation successful. Chunk is now (%lld, %lld).\n", free.begin, free.end); #endif return b; } // If not, get a new chunk. else { XOR_GPU_TRANSIENT_VERBOSE(" Existing chunk cannot hold allocation, getting new chunk for list %lld.\n", cmdList); XOR_CHECK(size <= static_cast<size_t>(m_chunkSize), "Allocation does not fit in one chunk"); ChunkNumber newChunk = findFreeChunk(progress); XOR_CHECK(newChunk >= 0, "There are no free or waitable chunks."); m_usedChunks.emplace_back(cmdList, newChunk); int64_t begin = newChunk * m_chunkSize; free = Block(begin, begin + m_chunkSize); auto b = free.fitAtBegin(size, alignment); XOR_ASSERT(b.valid(), "Allocation failed with an empty chunk"); free.begin = b.end; return b; } }
void *allocateMemory(unsigned size_in_bytes) { int size; unsigned chunk; int chunk_size; if (!initialized) { initializeHeap(); initialized = true; } if (size_in_bytes == 0) { return nullptr; } size = (size_in_bytes + sizeof(int)-1) / sizeof(int); chunk = findFreeChunk(size); if (always_false) { displayChunks(); } if (chunk == bogus_chunk) { printf("Ah NUTS, out of memory\n"); exit(-1); // forces main to return -1 !immediately! } splitChunkIfNecessary(chunk, size); chunk_size = memory_pool[chunk]; assert(chunk_size >= size); // just a sanity check, pretty insane really setBothSignatures(chunk, -chunk_size); /* OK, all done... all we need to do now is return... oh, * we're supposed to return a pointer, not an index..... */ return &memory_pool[chunk + 1]; }