Merge pull request #3639 from AchrafReyani/fix/libc-mspace-32-byte-alignment
fix(libc): align mspace allocations to 32 bytes
This commit is contained in:
commit
34c94e1d42
|
|
@ -16,6 +16,7 @@ namespace {
|
|||
|
||||
constexpr unsigned MspaceThreadUnsafe = 1;
|
||||
constexpr std::uintptr_t Granule = 16;
|
||||
constexpr std::uintptr_t MinimumAlignment = 32;
|
||||
constexpr std::uintptr_t ArenaHeaderBytes = 64;
|
||||
|
||||
struct Chunk {
|
||||
|
|
@ -60,7 +61,7 @@ void RemoveFree(Arena& arena, std::map<std::uintptr_t, Chunk>::iterator chunk) {
|
|||
|
||||
void* Allocate(Arena* arena, std::size_t size, std::size_t alignment) {
|
||||
if (!arena) return nullptr;
|
||||
alignment = std::max<std::size_t>(alignment, Granule);
|
||||
alignment = std::max<std::size_t>(alignment, MinimumAlignment);
|
||||
const auto needed = AlignUp(std::max<std::size_t>(size, 1), Granule);
|
||||
if (needed < size || needed > std::numeric_limits<std::uintptr_t>::max() - alignment) {
|
||||
Error(12);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,33 @@ struct MallocManagedSize {
|
|||
static void Require(bool value) {
|
||||
if (!value) { std::fputs("Mspace check failed\n", stderr); std::abort(); }
|
||||
}
|
||||
static void CheckAlignment() {
|
||||
alignas(32) static std::array<unsigned char, 65536 + 16> storage{};
|
||||
void* arena = sceLibcMspaceCreate_nid_postfix("aligned", storage.data() + 16, 65536, 0);
|
||||
Require(arena != nullptr);
|
||||
const auto aligned = [](const void* pointer) { return pointer && (reinterpret_cast<std::uintptr_t>(pointer) & 31u) == 0; };
|
||||
void* blocks[64] = {};
|
||||
for (std::size_t index = 0; index < 64; ++index) {
|
||||
blocks[index] = sceLibcMspaceMalloc_nid_postfix(arena, index + 1);
|
||||
Require(aligned(blocks[index]));
|
||||
std::memset(blocks[index], 0xa5, index + 1);
|
||||
}
|
||||
void* zeroed = sceLibcMspaceCalloc_nid_postfix(arena, 3, 13);
|
||||
Require(aligned(zeroed));
|
||||
blocks[0] = sceLibcMspaceRealloc_nid_postfix(arena, blocks[0], 600);
|
||||
Require(aligned(blocks[0]));
|
||||
void* small = sceLibcMspaceMemalign_nid_postfix(arena, 16, 40);
|
||||
Require(aligned(small));
|
||||
void* moved = sceLibcMspaceReallocalign_nid_postfix(arena, nullptr, 40, 8);
|
||||
Require(aligned(moved));
|
||||
void* posix = nullptr;
|
||||
Require(sceLibcMspacePosixMemalign_nid_postfix(arena, &posix, 8, 40) == 0 && aligned(posix));
|
||||
for (void* block : blocks) sceLibcMspaceFree_nid_postfix(arena, block);
|
||||
for (void* block : {zeroed, small, moved, posix}) sceLibcMspaceFree_nid_postfix(arena, block);
|
||||
Require(sceLibcMspaceDestroy_nid_postfix(arena) == 0);
|
||||
}
|
||||
int main() {
|
||||
CheckAlignment();
|
||||
alignas(16) std::array<unsigned char, 65536> storage{};
|
||||
void* arena = sceLibcMspaceCreate_nid_postfix("test", storage.data(), storage.size(), 0);
|
||||
Require(arena != nullptr);
|
||||
|
|
|
|||
Loading…
Reference in New Issue