// SPDX-License-Identifier: MPL-2.0
#include "std/malloc.h"
#include "memory/page.h"
#include "memory/heap.h"
#include "memory/vmem_layout.h"
#include "kernel/log.h"
SH_STATUS last_status=0;
SH_STATUS sh_malloc_get_last_status() {
  return last_status;
}
void* sh_malloc(sh_uint64 size) {
  if (size==0) return SH_NULLPTR;
  sh_page_VIRTUAL_ADDRESS va=0;
  SH_STATUS status;
  if (size<=1024) {
    status=sh_heap_allocate_object((sh_uint32)size,&va);
  } else {
    sh_uint32 pages=(sh_uint32)((size+4095LL)/4096LL);
    status=sh_heap_allocate_pages(pages,&va);
  }
  last_status=status;
  return (sh_status_error(status))?SH_NULLPTR:(void*)va;
}
void sh_free(void *ptr) {
  if (ptr==SH_NULLPTR) return;
  sh_page_VIRTUAL_ADDRESS va=(sh_page_VIRTUAL_ADDRESS)ptr;
  if (va>=SH_VMEM_LAYOUT_HEAP_SLAB_LEVEL_0_VA && va<SH_VMEM_LAYOUT_HEAP_SLAB_LEVEL_7_VA+SH_VMEM_LAYOUT_HEAP_SLAB_LEVEL_7_SIZE_BYTES) {
    last_status=sh_heap_free_object(va);
    return;
  }
  if (va>=SH_VMEM_LAYOUT_HEAP_BIG_VA && va<SH_VMEM_LAYOUT_HEAP_SLAB_LEVEL_0_VA) {
    last_status=sh_heap_free_pages(va);
    if (sh_status_error(last_status)) {
      sh_log_fcritical(SH_LOG_SOURCE_HEAP,"Couldn't free pages at va=0x%x\n",va);
    }
    return;
  }
  sh_log_fcritical(SH_LOG_SOURCE_HEAP,"va=0x%x doesn't came from heap\n",va);
}
