2016-10-27 00:34:10 +00:00
|
|
|
/****************************************************************************
|
|
|
|
* Copyright (C) 2015 Dimok
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
****************************************************************************/
|
|
|
|
#include <malloc.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "memory.h"
|
2017-01-23 14:59:44 +00:00
|
|
|
#include <wiiu/mem.h>
|
2016-10-27 00:34:10 +00:00
|
|
|
|
2016-10-29 01:56:40 +00:00
|
|
|
static MEMExpandedHeap* mem1_heap;
|
|
|
|
static MEMExpandedHeap* bucket_heap;
|
2016-10-27 18:53:56 +00:00
|
|
|
|
2016-10-27 00:34:10 +00:00
|
|
|
void memoryInitialize(void)
|
|
|
|
{
|
2016-10-29 01:56:40 +00:00
|
|
|
MEMHeapHandle mem1_heap_handle = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
|
2016-10-27 18:53:56 +00:00
|
|
|
unsigned int mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4);
|
|
|
|
void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4);
|
|
|
|
if(mem1_memory)
|
|
|
|
mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0);
|
2016-10-27 14:33:40 +00:00
|
|
|
|
2016-10-29 01:56:40 +00:00
|
|
|
MEMHeapHandle bucket_heap_handle = MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG);
|
2016-10-27 00:34:10 +00:00
|
|
|
unsigned int bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4);
|
|
|
|
void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4);
|
|
|
|
if(bucket_memory)
|
|
|
|
bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void memoryRelease(void)
|
|
|
|
{
|
2016-10-27 18:53:56 +00:00
|
|
|
MEMDestroyExpHeap(mem1_heap);
|
2016-11-16 17:25:23 +00:00
|
|
|
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1), MEM_FRAME_HEAP_FREE_ALL);
|
2016-10-29 01:56:40 +00:00
|
|
|
mem1_heap = NULL;
|
2016-10-27 18:53:56 +00:00
|
|
|
|
2016-10-27 00:34:10 +00:00
|
|
|
MEMDestroyExpHeap(bucket_heap);
|
2016-11-16 17:25:23 +00:00
|
|
|
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG), MEM_FRAME_HEAP_FREE_ALL);
|
2016-10-29 01:56:40 +00:00
|
|
|
bucket_heap = NULL;
|
2016-10-27 00:34:10 +00:00
|
|
|
}
|
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
void* _memalign_r(struct _reent *r, size_t alignment, size_t size)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
2016-11-16 17:25:23 +00:00
|
|
|
return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), size, alignment);
|
2016-10-27 00:34:10 +00:00
|
|
|
}
|
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
void* _malloc_r(struct _reent *r, size_t size)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
2016-11-16 17:25:23 +00:00
|
|
|
return _memalign_r(r, 4, size);
|
2016-10-27 00:34:10 +00:00
|
|
|
}
|
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
void _free_r(struct _reent *r, void *ptr)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
2016-10-27 22:03:21 +00:00
|
|
|
if (ptr) {
|
2016-11-16 17:25:23 +00:00
|
|
|
MEMFreeToExpHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), ptr);
|
2016-10-27 22:03:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
size_t _malloc_usable_size_r(struct _reent *r, void *ptr)
|
|
|
|
{
|
2016-10-27 22:03:21 +00:00
|
|
|
return MEMGetSizeForMBlockExpHeap(ptr);
|
|
|
|
}
|
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
void * _realloc_r(struct _reent *r, void *ptr, size_t size)
|
|
|
|
{
|
|
|
|
if (!ptr)
|
|
|
|
return _malloc_r(r, size);
|
2016-10-27 22:03:21 +00:00
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
if (_malloc_usable_size_r(r, ptr) >= size)
|
2016-10-27 22:03:21 +00:00
|
|
|
return ptr;
|
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
void *realloc_ptr = _malloc_r(r, size);
|
2016-10-27 22:03:21 +00:00
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
if(!realloc_ptr)
|
2016-10-27 22:03:21 +00:00
|
|
|
return NULL;
|
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
memcpy(realloc_ptr, ptr, _malloc_usable_size_r(r, ptr));
|
|
|
|
_free_r(r, ptr);
|
2016-10-27 22:03:21 +00:00
|
|
|
|
|
|
|
return realloc_ptr;
|
|
|
|
}
|
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
void* _calloc_r(struct _reent *r, size_t num, size_t size)
|
|
|
|
{
|
|
|
|
void *ptr = _malloc_r(r, num*size);
|
2016-10-27 22:03:21 +00:00
|
|
|
|
|
|
|
if(ptr) {
|
|
|
|
memset(ptr, 0, num*size);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2016-11-16 17:25:23 +00:00
|
|
|
void * _valloc_r(struct _reent *r, size_t size)
|
|
|
|
{
|
|
|
|
return _memalign_r(r, 64, size);
|
2016-10-27 22:03:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-27 00:34:10 +00:00
|
|
|
//!-------------------------------------------------------------------------------------------
|
|
|
|
//! some wrappers
|
|
|
|
//!-------------------------------------------------------------------------------------------
|
|
|
|
void * MEM2_alloc(unsigned int size, unsigned int align)
|
|
|
|
{
|
2016-11-16 17:25:23 +00:00
|
|
|
return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), size, align);
|
2016-10-27 00:34:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MEM2_free(void *ptr)
|
|
|
|
{
|
2016-11-16 17:25:23 +00:00
|
|
|
if (ptr)
|
|
|
|
MEMFreeToExpHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), ptr);
|
2016-10-27 00:34:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void * MEM1_alloc(unsigned int size, unsigned int align)
|
|
|
|
{
|
|
|
|
if (align < 4)
|
|
|
|
align = 4;
|
|
|
|
return MEMAllocFromExpHeapEx(mem1_heap, size, align);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MEM1_free(void *ptr)
|
|
|
|
{
|
|
|
|
MEMFreeToExpHeap(mem1_heap, ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void * MEMBucket_alloc(unsigned int size, unsigned int align)
|
|
|
|
{
|
|
|
|
if (align < 4)
|
|
|
|
align = 4;
|
|
|
|
return MEMAllocFromExpHeapEx(bucket_heap, size, align);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MEMBucket_free(void *ptr)
|
|
|
|
{
|
|
|
|
MEMFreeToExpHeap(bucket_heap, ptr);
|
|
|
|
}
|